ClassCastException: 无法转换为 com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
ClassCastException: Cannot be cast to com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
我有一个 SOAP 网络服务,我正试图在应用程序内部调用它。我正在使用 cxf-codegen-plugin (3.1.10) 从 WSDL 生成源代码。
使用生成的客户端,如果我在应用程序中调用网络服务,效果很好。但是,我还在导致问题的应用程序中针对同一个包使用了另一个 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.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");
, 有效。但是,不幸的是,在我的环境中设置此 属性 对我来说不是一个选项。另外,这似乎是一个没有解决真正问题的黑客(除非我误解了)。
我正准备用剩下的那根小绳子上吊。我在这里错过了什么?
我不想回答我自己的问题,但我想确保清楚地记录了我最终采用的解决方案。
根本问题是 camel-jaxb 引入的 jaxb-impl jar 与 JDK 8 提供的版本冲突。
This answer 更清楚地描述了正在发生的事情:
I encountered the same error when I tried to upgrade JAXB to a newer
version than what came with the JDK. Java encountered two or more
instances of JAXB at runtime and could not decide which version to
use.
在我的例子中,我简单地排除了 camel-jaxb 附带的 jaxb-impl,应用程序开始正常工作。
我 运行 在测试范围内遇到了同样的问题。对我来说,添加 jaxws-rt 运行time jar 很有帮助。请注意,我只是为我的测试范围添加了它。您不会在产品 运行 时间内执行此操作,因为 JEE 容器应该已经具有此或其他实现。
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
我 运行 在尝试通过 Maven 运行 我的 JUnit 测试时遇到此错误,即使它们在 Eclipse 中通过了本地测试。我的解决方案是在 @BeforeClass
中放置:
System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");
如果您使用 spring 启动 2.2 以上。6.RELEASE 将此 属性 添加到您的 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
我有一个 SOAP 网络服务,我正试图在应用程序内部调用它。我正在使用 cxf-codegen-plugin (3.1.10) 从 WSDL 生成源代码。
使用生成的客户端,如果我在应用程序中调用网络服务,效果很好。但是,我还在导致问题的应用程序中针对同一个包使用了另一个 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.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");
, 有效。但是,不幸的是,在我的环境中设置此 属性 对我来说不是一个选项。另外,这似乎是一个没有解决真正问题的黑客(除非我误解了)。
我正准备用剩下的那根小绳子上吊。我在这里错过了什么?
我不想回答我自己的问题,但我想确保清楚地记录了我最终采用的解决方案。
根本问题是 camel-jaxb 引入的 jaxb-impl jar 与 JDK 8 提供的版本冲突。
This answer 更清楚地描述了正在发生的事情:
I encountered the same error when I tried to upgrade JAXB to a newer version than what came with the JDK. Java encountered two or more instances of JAXB at runtime and could not decide which version to use.
在我的例子中,我简单地排除了 camel-jaxb 附带的 jaxb-impl,应用程序开始正常工作。
我 运行 在测试范围内遇到了同样的问题。对我来说,添加 jaxws-rt 运行time jar 很有帮助。请注意,我只是为我的测试范围添加了它。您不会在产品 运行 时间内执行此操作,因为 JEE 容器应该已经具有此或其他实现。
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
我 运行 在尝试通过 Maven 运行 我的 JUnit 测试时遇到此错误,即使它们在 Eclipse 中通过了本地测试。我的解决方案是在 @BeforeClass
中放置:
System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");
如果您使用 spring 启动 2.2 以上。6.RELEASE 将此 属性 添加到您的 pom:
因为在下一个版本中它更改了 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