问题描述
我有一些wsimport生成的JAXB类
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
我将演示这个类的问题(我自己只添加了@XmlRootElement):
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;}
}
直接实例化和编组工作正常( Example1 )
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);
现在让我们在webservice调用中创建对象:
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)
如何处理有了这个?谢谢你,Thor。
How to deal with this? Thank you, Thor.
更新2 如果我修改 Example1 ,我会得到同样的错误
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);
更新2 体育的XML结构
<Sport>
<sportsID>int</sportsID>
<sportsName>string</sportsName>
</Sport>
推荐答案
我知道,这个问题很老,但我只是有一个类似的问题,我想在这里提供我的问题的解决方案。
I know, this question is old, but I just had a similar issue and I wanted to provide my solution to the problem here.
问题是,我们在同一个类加载器中有我们自己的jaxbcontext实例jws JAXB上下文驻留在。
The issue was, that we had our own instance of a jaxbcontext in the same classloader as the jws JAXB context was residing in.
因此,我们在JAXB上下文中添加了类A,jws确实在其JAXB上下文中添加了类A.
Thus, we added class A in our JAXB context and jws did add class A in his JAXB context.
在使用jws代码时,类加载器确实提供了错误的类,并抛出了一个classcast异常。
On using the jws code, the classloader did provide the wrong class, and a classcast exception was thrown.
通过使用此共享对象的JAXB。(联合国)编组函数,我们可以解决问题。
By using the JAXB.(un)marshal functions for this "shared" object, we could solve the issue.
更新:好的,既然有人问过,我会在4年后更新这个问题: - )
UPDATE: Ok, since two asked, I will update this question after 4 years :-)
上述问题指向分层类加载器问题。 JAXB从注释中动态生成类(un)编组对象,并将它们添加到缓存中。这些类最初看起来是相同的,但对于相同的注释它们是不同的类对象。这是因为它们不在同一个类加载器中,服务器类加载器不会将类加载器树下载到另一个类加载器来查找它们。
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.
这篇关于来自Webservice的JAXB类编组错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!