【问题标题】:JAXB classes from Webservice marshalling error来自 Web 服务编组错误的 JAXB 类
【发布时间】:2011-09-01 16:53:27
【问题描述】:

我有一些 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;}
}

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

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

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

现在让我们在 web 服务调用中创建对象:

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.<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)

如何处理?谢谢你,雷神。

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

<Sport>
  <sportsID>int</sportsID>
  <sportsName>string</sportsName>
</Sport>

【问题讨论】:

    标签: java jaxb jax-ws


    【解决方案1】:

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

    【讨论】:

    • 感谢您的提示,但这也适用于具有此(maven)依赖项的新项目:javax.xml.bind:jaxb-api:2.2.2 和 com.sun.xml.bind: jaxb-impl:2.2.2。我发现如果我实例化 @WebServiceClient 并在此之后手动创建类,甚至会发生这种情况。
    • 你检查过你的 \jdk\jre\lib\endorsed 了吗?检查那里是否有 jaxb.jar
    • 在 OSX 上好像是 /Library/Java/Home/lib/endorsed,但是这个目录是空的。
    • 为什么不尝试在字段级别添加注释,例如:@XmlAttribute(name = "sportsID", required = true) sportsID 等等
    • 类是由 wsimport 创建的。我正在使用网络服务器,因此无法修改结构(请参阅更新 2)。
    【解决方案2】:

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

    本质上,JAXB 和 JAX-WS 都必须是内部的,或者两者都必须是外部的。 This thread 建议如果您有外部 JAXB 并且想要切换到使用内部版本。

    【讨论】:

      【解决方案3】:

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

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

      因此,我们在 JAXB 上下文中添加了 A 类,而 jws 确实在他的 JAXB 上下文中添加了 A 类。

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

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

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

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

      当我们将来自较低类加载器的对象与层次较高的类加载器混合在一起时,编组无法进行匹配。

      这就是我记得这个问题的方式。

      【讨论】:

      • 我知道这是一个老问题,但您能否详细说明您的解决方案?我不清楚您所说的“将 JAXB 函数用于‘共享’对象”是什么意思。
      • 我也可以对这个答案进行一些澄清。
      【解决方案4】:

      我有时也会遇到这个错误(它不是恒定的,ô令人沮丧!!),我在answer 的帮助下解决了它:我在我的代码中添加了httpClientPolicy.setAllowChunking(false);,然后\ o/,没问题了:)

      但是,真的,我不知道为什么:/

      【讨论】:

      • 您似乎遇到了同样的ClassCastException 错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多