java 来自 Web 服务编组错误的 JAXB 类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6123843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:24:47  来源:igfitidea点击:

JAXB classes from Webservice marshalling error

javajaxbjax-ws

提问by Thor

I have some wsimport generated JAXB classes

我有一些 wsimport 生成的 JAXB 类

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

我将演示这个类的问题(只有@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;}
}

Direcly instantiating and marshalling works fine (Example1)

直接实例化和编组工作正常(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:

现在让我们在 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);
}

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 2If I modify Example1to this, I get the same error

更新 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);

Update 2XML structure of sport

更新 2运动的 XML 结构

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

回答by Teja Kantamneni

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.

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

回答by thst

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.

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

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

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

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

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

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

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

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

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

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.

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

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.

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

回答by Ritzbot

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.

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

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

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

回答by LE GALL Beno?t

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

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

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

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