Deux classes ont le même type XML nom “objectFactory”

Nous avons été à l'aide de JAXB 2.1 pour une longue période dans notre système. Nous avons une plate-forme qui est construit avec Ant et génère un tas de séries qui sont déployés dans OSGi moment de l'exécution. Nous utilisons Java SE 6.

Nous utilisons JAXB pendant le processus de génération pour générer des types de données à partir de différents schémas. Ces classes sont emballés dans des faisceaux utilisés lors de l'exécution de sérialiser/désérialiser de contenu. En outre, nous utilisons des JAXB dans notre plate-forme d'exécution pour générer les types de données à partir d'autres schémas fournis par l'utilisateur (une sorte de MDA pour la plate-forme).

Dans OSGi d'exécution, nous avons un module qui a l'JAXB et des pots et des exportations les paquets nécessaires. Nous avons créer un JAXBContext exemple avec le chemin de contexte de l'ensemble de l'objet usines générés, afin que nous puissions marshall/unmarshall tous nos types de données.

Qui a travaillé jusqu'à présent, mais maintenant nous sommes en train de mettre à jour vers la dernière version stable de JAXB (2.2.4) et nous sommes d'avoir des problèmes en essayant de créer le contexte d'exécution. Nous obtenons l'exception suivante:

Two classes have the same XML type name "objectFactory". Use @XmlType.name and @XmlType.namespace to assign different names to them.
this problem is related to the following location:
at some.package.ObjectFactory
this problem is related to the following location:
at some.other.package.ObjectFactory
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:191)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:187)
... 76 more

L'erreur Deux classes ont le même type XML nom "objectFactory" est imprimé pour chaque objet usines générés pendant le processus de génération.

Nous avons vu plusieurs postes avec la même erreur, mais l'application pour les types générés, et non pas à l'objet de l'usine. Nous pensons que JAXB peut-être pas l'identification de l'ObjectFactory classe comme une fabrique d'objet, mais comme un type de données.

Une possibilité est que nous étions à l'aide de la version interne de JAXB dans la version 6 de Java, nous avons donc décidé d'utiliser le Système de Propriété -Djava.approuvé.dirs et de mettre les trois pots (jaxb-api-2.2.4.jar, jaxb-impl-2.2.4.jar et jaxb-xjc-2.2.4.jar) dans ce chemin, mais toujours pas de travail.

Nous pensons que le problème pourrait être que nous sommes à l'aide d'une version différente de JAXB dans OSGi d'exécution et dans le processus de construction, de sorte que le code généré n'est pas compatible. Mais peut-être que nous sommes dans l'erreur et il y a un autre problème.

Avez-vous des idées?

Merci d'avance.

(Edit: plus de détails sur ce sujet)

Nous à créer le JAXBContext de cette façon:

    ClassLoader classLoader = new JAXBServiceClassLoader(getParentClassLoader(),
Collections.unmodifiableMap(objectFactories));
context = JAXBContext.newInstance(contextPath.toString(), classLoader);

où contextPath est une Chaîne qui contient l'ensemble de notre objet d'usines, séparés par ':', et le JAXBServiceClassLoader est:

  private static final class JAXBServiceClassLoader extends ClassLoader
{
@NotNull
private final Map<String, Object> objectFactories;
private JAXBServiceClassLoader(@NotNull ClassLoader parent, @NotNull Map<String, Object> objectFactories)
{
super(parent);
this.objectFactories = objectFactories;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException
{
Class<?> ret;
try
{
ret = super.loadClass(name);
}
catch (ClassNotFoundException e)
{
Object objectFactory = objectFactories.get(name);
if (objectFactory != null)
{
ret = objectFactory.getClass();
}
else
{
throw new ClassNotFoundException(name + " class not found");
}
}
return ret;
}
}

(Edit: après Aaron post)

J'ai été le débogage de tous les éléments internes de JAXBContextImpl et le truc, c'est que le JAXBContextImpl est d'essayer d'obtenir le type d'informations à partir de notre ObjectFactory classes, ce qui est faux. En fait, dans com.soleil.xml.interne.bind.v2.de modèle.impl.ModelBuilder:314, le getClassAnnotation() qui renvoie la valeur null mais quand je vois l'exemple, je peux voir l'annotation XmlRegistry.

Le truc, c'est que, à ce point de XmlRegistry.classe.getClassLoader() renvoie null, mais si je lance ((Classe)c).getAnnotations()[0].annotationType().getClassLoader (), elle renvoie le chargeur de classe de l'OSGi bundle "lib.jaxb" qui contient mon JAXB pots, ce qui est correct.

Donc, je suppose que nous sommes de chargement dans le même temps, deux versions différentes de XmlRegistry, l'un à partir du JDK et de l'autre à partir de JAXB 2.2.4 pots. La question est: pourquoi?

Et, plus encore, au lieu de charger tous ces com.soleil.xml.interne.* les classes (comme JAXBContextImpl), ne devrait pas être le chargement et l'exécution de com.soleil.xml.bind.v2.moment de l'exécution.JAXBContextImpl de JAXB de pots? Pendant le processus de débogage je peux voir qu'il fait des trucs avec de la réflexion, mais je ne comprends pas pourquoi le faire.

  • À l'aide de Java SE 6, je vous conseille d'utiliser la dernière version du patch version de votre JAXB impl qui prend en charge JAXB 2.1 à moins qu'il y est un particulier, JAXB 2.2 fonctionnalité que vous essayez d'utiliser.
  • Désolé de ne pas le mentionner. La raison de la mise à niveau de JAXB 2.2.4, c'est que nous améliorons nos JAX-WS version 2.2.5 et il dépend de la version de JAXB (jax-ws.java.net/2.2.5/docs/ReleaseNotes.html). Sinon, on pourrait utiliser JAXB 2.1.
  • Il ressemble à votre JAXB impl-à tort-le traitement de l' ObjectFactory comme un domaine de la classe. Ceci est probablement dû à la @XmlRegistry annotation ne pas être reconnu en raison d'un ClassLoader différence entre les classes de votre domaine et JAX-WS mise en œuvre. Êtes-vous de la création de la JAXBContext directement ou JAX-WS de mise en œuvre de cette mesure?
  • Non, dans ce cas, je ne suis pas à l'utiliser via JAX-WS. Je crée directement le JAXBContext passant le chemin de contexte avec tous l'objet d'usines en tant que paramètre. Le code n'a pas du tout changé, j'ai juste remplacé les pots de 2.1.9 par la version 2.2.4.
  • Puisque vous êtes dans un environnement OSGi, je crois que vous êtes dans un cas où les classes de votre domaine et JAXB impl font référence à des versions différentes de la JAXB binaires. Ce n'était pas le cas avant car il n'y avait qu'une seule version de la JAXB binaires disponibles. Pouvez-vous modifier votre code, de sorte que lorsque vous créez la JAXBContext vous transmettre le chargeur de classe qui a les classes de votre domaine chargé?
  • J'ai édité le post, donc vous pouvez voir le code que nous utilisons pour instancier un JAXBContext.

InformationsquelleAutor Denian | 2011-09-09