来自Webservice的JAXB类编组错误

我有一些wsimport生成的JAXB类

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

我将演示这个类的问题(我自己只添加了@XmlRootElement):

 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;} } 

直接实例化和编组工作正常( 例1

 Sport sport = new Sport(); sport.setSportsID(1); sport.setSportsName("test"); JAXBContext jc = JAXBContext.newInstance(Sport.class); jc.createMarshaller().marshal(sport,System.out); 

现在让我们在webservice调用中创建对象:

 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); } 

然后我得到了这个例外:

 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.(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.(ClassBeanInfoImpl.java:183) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:526) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(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) 

怎么处理这个? 谢谢你,托尔。

更新2如果我修改Example1到此,我得到相同的错误

 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结构

  int string  

我不确定这是否是导致这种情况发生的唯一原因,但这是我遇到的一个问题并且这样解决了,请检查您的Java认可目录并删除任何重复的jaxb-impl.jar。 即使使用webservice-api.jar,也可能发生这种情况。 希望这可以帮助。

最近,当我尝试将JAXB升级到比JDK附带的更新版本时,我收到了相同的错误消息。 我有一个JAXB的外部版本,但我的JAX-WS仍然是JDK附带的内部版本。 内部JAX-WS尝试调用内部JAXB,但应用程序想要使用外部JAXB。

从本质上讲,JAXB和JAX-WS都必须是内部的,或者两者都必须是外部的。 如果您有外部JAXB并且想要切换到使用内部版本,则此线程会提供建议。

我知道,这个问题很老,但我遇到了类似的问题,我想在这里提供解决问题的方法。

问题是,我们在jws JAXB上下文所在的同一个类加载器中有我们自己的jaxbcontext实例。

因此,我们在JAXB上下文中添加了类A,jws在其JAXB上下文中添加了类A.

在使用jws代码时,类加载器确实提供了错误的类,并抛出了一个classcastexception。

通过对这个“共享”对象使用JAXB。(un)marshal函数,我们可以解决这个问题。

更新:好的,既然有人问过,我会在4年后更新这个问题:-)

上述问题指向分层类加载器问题。 JAXB从注释中动态生成类(un)编组对象,并将它们添加到缓存中。 这些类最初看起来是相同的,但对于相同的注释它们是不同的类对象。 这是有效的,因为它们不在同一个类加载器中,并且服务器类加载器不会将类加载器树下载到另一个类加载器来查找它们。

当我们将下层类加载器中的对象与层次结构中较高的类加载器混合时,编组无法进行匹配。

多数民众赞成我如何记住这个问题。

我也不时地交叉这个错误(它不是常数,令人沮丧!!),我在这个答案的帮助下解决了它:我添加了httpClientPolicy.setAllowChunking(false); 在我的代码中,\ o /,没有更多的问题:)

但是,确实,我不知道为什么:/