J'ai un service Web SOAP que j'essaie d'appeler à l'intérieur d'une application. J'utilise le plugin cxf-codegen-plugin (3.1.10) pour générer des sources à partir du WSDL.
En utilisant le client généré, si j'appelle le service Web dans l'application, cela fonctionne très bien. Cependant, j'utilise également une autre instance JAXB pour le même package au sein de l'application à l'origine du problème.
Par exemple, ce qui suit fonctionne très bien:
OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);
Cependant, l'initialisation d'une nouvelle instance JAXB juste avant entraîne l'échec de l'appel getOutboundServicePort()
:
JAXBContext.newInstance(SendMessageRequest.class);
OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);
Avec le stacktrace suivant:
Caused by: Java.lang.ClassCastException: outbound.model.standard.StandardOutboundMessage$JaxbAccessorF_messageUUId cannot be cast to com.Sun.xml.internal.bind.v2.runtime.reflect.Accessor
at com.Sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.instanciate(OptimizedAccessorFactory.Java:190)
at com.Sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.Java:179)
at com.Sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.Java:271)
at com.Sun.xml.internal.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.Java:77)
at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:62)
at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:45)
at Java.lang.reflect.Constructor.newInstance(Constructor.Java:422)
at com.Sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.Java:113)
at com.Sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.Java:166)
at com.Sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.Java:488)
at com.Sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.Java:153)
at com.Sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.Java:488)
at com.Sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.Java:305)
at com.Sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.Java:124)
at com.Sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.Java:1123)
at com.Sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.Java:147)
at com.Sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.Java:152)
at com.Sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.Java:96)
at com.Sun.xml.internal.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.Java:98)
at com.Sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory.newContext(JAXBRIContextFactory.Java:79)
... 25 more
Choses que j'ai essayées jusqu'ici:
Classes JAXB provenant d'une erreur de triage de Webservice
Problèmes lors de la création d'un objet JAXBContext vers marshal en XML
System.setProperty( "com.Sun.xml.bind.v2.bytecode.ClassTailor.noOptimize", "true");
qui fonctionne. Cependant, définir cette propriété n'est pas une option pour moi malheureusement dans mon environnement. De plus, il semble que ce soit un peu un bidouillage qui ne règle pas le vrai problème (à moins que je ne le comprenne mal).Je suis sur le point de me pendre avec la petite corde qui me reste. Qu'est-ce que j'oublie ici?
Je n'aime pas répondre à ma propre question, mais je voulais m'assurer que la solution que j'ai trouvée était clairement documentée.
Le problème fondamental était que le fichier jaxb-impl apporté par camel-jaxb était en conflit avec la version fournie par JDK 8.
Cette réponse décrit ce qui se passe plus clairement:
J'ai rencontré la même erreur lorsque j'ai essayé de mettre à niveau JAXB vers un plus récent version que celle fournie avec le JDK. Java a rencontré deux ou plus instances de JAXB au moment de l'exécution et ne pouvaient pas décider quelle version utiliser utilisation.
Dans mon cas, j'ai simplement exclu le jaxb-impl fourni avec camel-jaxb et l'application a commencé à fonctionner correctement.
Je rencontre le même problème dans la portée du test. Pour moi, l'ajout de jaxws-rt runtime m'a aidé. Notez que je l'ai ajouté uniquement pour ma portée de test. Vous ne ferez pas cela pour le runtime du prod, car le conteneur JEE est supposé avoir déjà cette implémentation ou une autre.
<dependency>
<groupId>com.Sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>