JAXB classes from Webservice marshalling error

2019-04-26 17:35发布

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>

标签: java jaxb jax-ws
4条回答
走好不送
2楼-- · 2019-04-26 17:45

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.

查看更多
疯言疯语
3楼-- · 2019-04-26 17:54

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.

查看更多
别忘想泡老子
4楼-- · 2019-04-26 18:01

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.

查看更多
放我归山
5楼-- · 2019-04-26 18:06

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 :/

查看更多
登录 后发表回答