【问题标题】:ClassCastException: Cannot be cast to com.sun.xml.internal.bind.v2.runtime.reflect.AccessorClassCastException:无法转换为 com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
【发布时间】:2017-02-28 03:05:51
【问题描述】:

我有一个 SOAP 网络服务,我试图在应用程序内部调用它。我正在使用 cxf-codegen-plugin (3.1.10) 从 WSDL 生成源代码。

使用生成的客户端,如果我在应用程序中调用 web 服务,效果很好。但是,我还在应用程序中针对同一个包使用另一个 JAXB 实例,这会导致问题。

例如,下面的效果很好:

OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);

但是,在之前初始化一个新的 JAXB 实例会导致 getOutboundServicePort() 调用失败:

JAXBContext.newInstance(SendMessageRequest.class);

OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);

使用以下堆栈跟踪:

Caused by: java.lang.ClassCastException: outbound.model.standard.StandardOutboundMessage$JaxbAccessorF_messageUUId cannot be cast to com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
    at com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.instanciate(OptimizedAccessorFactory.java:190)
    at com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
    at com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:271)
    at com.sun.xml.internal.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:77)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:153)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:305)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
    at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:152)
    at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:96)
    at com.sun.xml.internal.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:98)
    at com.sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory.newContext(JAXBRIContextFactory.java:79)
    ... 25 more

到目前为止我尝试过的事情:

JAXB classes from Webservice marshalling error

  • 我的 JDK 文件夹中没有经过认可的 jar,因此 this answer 不适用
  • jaxb-impl jar (2.2.11) 来自我的应用程序中的 camel-jaxb,因此它看起来非常包含,不像 this answer 建议的那样。
  • This answer 似乎很好地描述了这个问题,但他们采取的解决方案对我来说似乎不清楚。

Problems creating JAXBContext to marshal object as XML

  • 这个问题似乎与我的相同,但他们最终采用的解决方案不适用于我的情况(见下文)

Netbeans with JAXB Random ClassCastException ..cannot be cast to com.sun.xml.bind.v2.runtime.reflect.Accessor

  • 我尝试了接受的解决方案System.setProperty( "com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize", "true");,确实工作。但是,不幸的是,在我的环境中,设置此属性不是我的选择。另外,这似乎是一种无法解决真正问题的技巧(除非我误解了它)。

我要用剩下的小绳子上吊了。我在这里错过了什么?

【问题讨论】:

  • 我没有给你答案,但它确实听起来可能像你链接到的那个难以理解的答案所暗示的两个独立的类加载器。此外,我还能够挖掘出至少一点关于 noOptimize 选项的信息:​​cxf.547215.n5.nabble.com/…,我猜 jaxb 做了一些非常奇怪的事情,尽管我不确定你在做什么会触发这个问题。有兴趣看答案。顺便说一句,如果这里没有任何内容,还可以考虑在 jaxb 用户邮件列表中询问。

标签: java jaxb cxf


【解决方案1】:

我不想回答我自己的问题,但我想确保清楚地记录我最终采用的解决方案。

根本问题是camel-jaxb引入的jaxb-impl jar与JDK 8提供的版本冲突。

This answer 更清楚地描述了正在发生的事情:

我在尝试将 JAXB 升级到更新版本时遇到了同样的错误 版本比JDK附带的版本。 Java遇到两个或多个 运行时的 JAXB 实例,无法决定要使用哪个版本 使用。

就我而言,我只是排除了camel-jaxb附带的jaxb-impl,应用程序开始正常工作。

【讨论】:

  • 砰的一声...我在本地机器上运行 junit 时也遇到了这个问题。我也有同样的怀疑,但你的回答帮助我节省了一些时间。谢谢!!!
  • 我在 JDK8 上运行时遇到了这个问题,但在 JDK11 上没有。
【解决方案2】:

我在尝试通过 Maven 运行我的 JUnit 测试时遇到了这个错误,即使它们在 Eclipse 中本地通过。我的解决方案是在 @BeforeClass 中放置:

System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");

【讨论】:

    【解决方案3】:

    我在测试范围内遇到了同样的问题。对我来说,添加 jaxws-rt 运行时 jar 有帮助。请注意,我仅为我的测试范围添加了它。您不会为 prod 运行时执行此操作,因为 JEE 容器应该已经具有此或其他实现。

    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>2.2.3</version>
        <scope>test</scope>
    </dependency>
    

    【讨论】:

      【解决方案4】:

      如果您使用 2.2.6.RELEASE 以上的 spring boot,请将此属性添加到您的 pom:

      2.3.2

      因为在下一个版本中它会更改 java.xml.bind 的实现:

      看看这个 pom IE:

      https://repo1.maven.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.3.5/jaxb-runtime-2.3.5.pom:

      --add-opens org.glassfish.jaxb.runtime/com.sun.xml.bind.v2=java.xml.bind --add-opens org.glassfish.jaxb.runtime/com.sun.xml。 bind.v2.schemagen=java.xml.bind --add-opens org.glassfish.jaxb.runtime/com.sun.xml.bind.v2.schemagen.xmlidref=java.xml.bind --add-opens java。 base/java.lang=org.glassfish.jaxb.runtime --add-opens java.base/java.lang.reflect=org.glassfish.jaxb.runtime --add-opens org.glassfish.jaxb.runtime/com。 sun.xml.bind.v2.runtime.reflect.opt=java.xml.bind

      【讨论】:

        猜你喜欢
        • 2020-10-04
        • 2012-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-28
        • 2014-05-30
        • 2017-07-18
        相关资源
        最近更新 更多