JAXB classes from Webservice marshalling error
Asked Answered
O

4

8

I have some wsimport generated JAXB classes

wsimport -d src/main/java -keep -extension
  -p my.package
  http://www.OpenLigaDB.de/Webservices/Sportsdata.asmx?WSDL

I will demonstrate the problem with this class (only the @XmlRootElement was added by myself):

package my.package;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Sport", propOrder = {"sportsID","sportsName"})
@XmlRootElement(name = "sport")   //Added by myself
public class Sport
{
    protected int sportsID;
    protected String sportsName;

    public int getSportsID() {return sportsID;}
    public void setSportsID(int value) {this.sportsID = value;}

    public String getSportsName() {return sportsName;}
    public void setSportsName(String value) {this.sportsName = value;}
}

Direcly instantiating and marshalling works fine (Example1)

Sport sport = new Sport();
sport.setSportsID(1);
sport.setSportsName("test");

JAXBContext jc = JAXBContext.newInstance(Sport.class);
jc.createMarshaller().marshal(sport,System.out);

Now lets create the object inside a webservice call:

SportsdataSoap s = new Sportsdata().getSportsdataSoap();
ArrayOfSport sports = s.getAvailSports();

for(Sport sport : sports.getSport())
{
    JAXBContext jc = JAXBContext.newInstance(Sport.class);
    jc.createMarshaller().marshal(sport,System.out);
}

Then I got this exception:

Exception in thread "main" java.lang.ClassCastException: my.package.Sport$JaxbAccessorF_sportsID cannot be cast to com.sun.xml.bind.v2.runtime.reflect.Accessor
    at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.instanciate(OptimizedAccessorFactory.java:199)
    at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:191)
    at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:282)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.<init>(SingleElementNodeProperty.java:94)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:128)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:183)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:526)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:341)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1158)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:140)
    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:202)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
    at my.package.TestOpenLiga.testDisciplines(TestOpenLiga.java:48)
    at my.package.TestOpenLiga.main(TestOpenLiga.java:130)

How to deal with this? Thank you, Thor.

Update 2 If I modify Example1 to this, I get the same error

SportsdataSoap s = new Sportsdata().getSportsdataSoap();

Sport sport = new Sport();
sport.setSportsID(1);
sport.setSportsName("test");

JAXBContext jc = JAXBContext.newInstance(Sport.class);
jc.createMarshaller().marshal(sport,System.out);

Update 2 XML structure of sport

<Sport>
  <sportsID>int</sportsID>
  <sportsName>string</sportsName>
</Sport>
Ox answered 25/5, 2011 at 11:36 Comment(0)
P
2

I am not sure if this is the only reason why this could happen, but this is one problem I faced and solved like this, check your Java endorsed dir and removed any duplicate jaxb-impl.jar. This could happen even with webservice-api.jar. Hope this helps.

Passepartout answered 25/5, 2011 at 11:43 Comment(5)
Thank's for this hint, but this also applies to a fresh project with this (maven) dependencies: javax.xml.bind:jaxb-api:2.2.2 and com.sun.xml.bind:jaxb-impl:2.2.2. I figured out that this even occures if I instantiate the @WebServiceClient and after this create the class manually.Ox
have you checked your \jdk\jre\lib\endorsed?? Check if you have a jaxb.jar therePassepartout
It seems to be /Library/Java/Home/lib/endorsed on OSX, but this directory is empty.Ox
why don't you try adding the annotations at the field level for ex: @XmlAttribute(name = "sportsID", required = true) on sportsID and so onPassepartout
The classes are created by wsimport. I'm consuming a webserver, thus cannot modify the structure (see Update 2).Ox
C
2

I know, this question is old, but I just had a similar issue and I wanted to provide my solution to the problem here.

The issue was, that we had our own instance of a jaxbcontext in the same classloader as the jws JAXB context was residing in.

Thus, we added class A in our JAXB context and jws did add class A in his JAXB context.

On using the jws code, the classloader did provide the wrong class, and a classcast exception was thrown.

By using the JAXB.(un)marshal functions for this "shared" object, we could solve the issue.

UPDATE: Ok, since two asked, I will update this question after 4 years :-)

The issue described above points to a hierarchical classloader issue. JAXB generates class (un)marshalling objects on the fly from annotations and adds them to his cache. These classes seem to be identical at first but they are different class objects for the same annotations. This works because they are not in the same classloader and the servers classloader will not dive down the classloader tree to the other classloader to find them.

When we mixed up the objects from the lower classloader with the classloader higher up the hierarchy, the marshalling was unable to make a match.

Thats how I remember the issue.

Cusped answered 1/4, 2014 at 14:15 Comment(2)
I know this is an old question, but could you elaborate on your solution a bit more? It's unclear to me what you mean by "using the JAXB functions for the 'shared' object".Felske
I also could use some clarification on this answer.Weatherboarding
S
2

I got the same error message recently when I tried to upgrade JAXB to a newer version than what came with the JDK. I had an external version of JAXB, but my JAX-WS was still the internal version that came with the JDK. The internal JAX-WS tried calling the internal JAXB, but the application wanted to use the external JAXB.

Essentially, both JAXB and JAX-WS have to be internal or both have to be external. This thread has advice if you have an external JAXB and you want to switch to using the internal version.

Simile answered 25/11, 2014 at 4:39 Comment(0)
S
-2

i cross this error, time to time too (it wasn't constant, ô frustrating !!) , and I resolved it with the help of this answer : I add the httpClientPolicy.setAllowChunking(false);in my code, and \o/, no more problem :)

But, true, I don't know why :/

System answered 7/4, 2014 at 14:8 Comment(1)
It doesn't look like you were experiencing the same ClassCastException error.Fernyak

© 2022 - 2024 — McMap. All rights reserved.