18

I have a SOAP webservice that I am trying to call inside of an application. I am using the cxf-codegen-plugin (3.1.10) to generate sources from the WSDL.

Using the generated client, if I call the webservice within the application, it works great. However, I am also using another JAXB instance against the same package within the application which is causing an issue.

For example, the following works great:

OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);

However, initializing a new JAXB instance right before causes the getOutboundServicePort() call to fail:

JAXBContext.newInstance(SendMessageRequest.class);

OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);

With the following stacktrace:

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

Things I have tried so far:

JAXB classes from Webservice marshalling error

  • I have no endorsed jars in my JDK folder, so this answer does not apply
  • The jaxb-impl jar (2.2.11) is coming from camel-jaxb in my app so it seems very contained and not like this answer suggests.
  • This answer seems to describe the problem well, but the solution they took seems unclear to me.

Problems creating JAXBContext to marshal object as XML

  • This question seems to be identical to mine, but the solution they ended up going with can not work for my situation (see below)

Netbeans with JAXB Random ClassCastException ..cannot be cast to com.sun.xml.bind.v2.runtime.reflect.Accessor

  • I tried the accepted solution System.setProperty( "com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize", "true"); which does work. However, setting this property is not an option for me unfortunately in my environment. Plus, it seems like it's a bit of a hack that does not address the real issue (unless I'm misunderstanding it).

I'm about to hang myself with the little rope I have left. What am I missing here?

Community
  • 1
  • 1
Tyler Murry
  • 2,705
  • 3
  • 29
  • 46
  • I don't have an answer for you, but it *does* sound like perhaps two separate class loaders as implied by that incomprehensible answer you linked to. Also I was able to dig up at least a slight gem of info on that `noOptimize` option: http://cxf.547215.n5.nabble.com/JAXB-is-not-sitting-well-in-an-OSGI-eclipse-env-tp569834p569839.html, I guess jaxb does some really weird stuff although I'm not sure what you are doing that's triggering the issue. Interested to see an answer. Btw consider also asking on the jaxb users mailing list if nothing comes up here. – Jason C Feb 28 '17 at 03:27

4 Answers4

15

I hate to answer my own question, but I wanted to make sure the solution I ended up going with was documented clearly.

The root issue was that the jaxb-impl jar brought in by camel-jaxb was conflicting with the JDK 8 provided version.

This answer describes what is happening more clearly:

I encountered the same error when I tried to upgrade JAXB to a newer version than what came with the JDK. Java encountered two or more instances of JAXB at runtime and could not decide which version to use.

In my case, I simply excluded the jaxb-impl that came with camel-jaxb and the application started working correctly.

Community
  • 1
  • 1
Tyler Murry
  • 2,705
  • 3
  • 29
  • 46
  • 1
    bang on... I also faced this issues while running junits on my local machine. I was also suspecting the same but your answer helped me to save some time. thanks!!! – PushkarT Apr 20 '18 at 17:16
  • I got this issue when running with JDK8 but not with JDK11. – Julien Kronegg Oct 14 '20 at 07:21
7

I ran into this error when trying to run my JUnit tests through Maven even though they passed locally in Eclipse. My solution was to in a @BeforeClass put:

System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");
geisterfurz007
  • 5,292
  • 5
  • 33
  • 54
Student
  • 287
  • 4
  • 9
1

If you are using spring boot above 2.2.6.RELEASE add this property to your pom:

<glassfish-jaxb.version>2.3.2</glassfish-jaxb.version>

Because in the next versions it changes the java.xml.bind implementation:

Take a look a this pom IE:

https://repo1.maven.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.3.5/jaxb-runtime-2.3.5.pom :

--add-opens org.glassfish.jaxb.runtime/com.sun.xml.bind.v2=java.xml.bind --add-opens org.glassfish.jaxb.runtime/com.sun.xml.bind.v2.schemagen=java.xml.bind --add-opens org.glassfish.jaxb.runtime/com.sun.xml.bind.v2.schemagen.xmlidref=java.xml.bind --add-opens java.base/java.lang=org.glassfish.jaxb.runtime --add-opens java.base/java.lang.reflect=org.glassfish.jaxb.runtime --add-opens org.glassfish.jaxb.runtime/com.sun.xml.bind.v2.runtime.reflect.opt=java.xml.bind

0

I run into the same issue in test scope. For me adding jaxws-rt runtime jar helped. Note, that I added it for my test scope only. You are not going to do this for prod runtime, since JEE container supposed to has this or other implementation already.

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.2.3</version>
    <scope>test</scope>
</dependency>
Peter
  • 1,512
  • 1
  • 22
  • 40