WebSphere中LinkageError导致的ServiceConfigurationError
ServiceConfigurationError caused by LinkageError in WebSphere
我有一个部署在 WebSphere 9.0.5.2 上的应用程序,我想在其中使用 CXF 进行 Web 服务调用,但我收到了这个 ServiceConfigurationError
WrapperedException { java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider org.apache.cxf.jaxws.spi.ProviderImpl could not be instantiated
进一步查看堆栈跟踪,我发现这是由 LinkageError 引起的
Caused by: java.lang.LinkageError: loading constraint violation when overriding method
"javax/xml/ws/spi/ServiceDelegate.createDispatch(Ljavax/xml/namespace/QName;Ljavax/xml/bind/JAXBContext;Ljavax/xml/ws/Service$Mode;)Ljavax/xml/ws/Dispatch;" during creation of class
"org/apache/cxf/jaxws/ServiceImpl": loader
"com/ibm/ws/classloader/CompoundClassLoader@832133d2" of class
"org/apache/cxf/jaxws/ServiceImpl" and loader
"com/ibm/oti/vm/BootstrapClassLoader@2eec706a" of class
"javax/xml/ws/spi/ServiceDelegate" have different types for the method signature
我知道这可能是由多个库对 QName
或 JAXBContext
具有不同定义引起的,但我认为我已经排除了这些可能性。
我也知道 WebSphere 有它自己的 JAX-WS 和它自己的 ServiceDelegate.createDispatch 方法签名,我已经尝试按照此处的说明在 WebSphere 中将 DisableIBMJAXWSEngine
设置为 true
Using a third-party JAX-WS web services engine
我仍然无法摆脱这个错误,对于接下来要尝试什么几乎一头雾水。任何建议表示赞赏!!!
这里的问题是 JAXB API、JAX-WS API 和 JAX-WS 实现的应用程序和服务器副本之间的交叉链接。该应用程序(配置了父级最后 class 加载委派,因此它在委派给父级之前在本地搜索)包含 JAX-WS 实现和 JAXB API/impl,但它不包含 JAX-WS API。由于 JAX-WS 引用 JAXB,我们得到以下链接模式:
1) 某些应用程序 class 引用了 JAX-WS API。因为它没有打包在应用程序中,所以它是从服务器库中加载的。
2) 当链接 API class 时,它使用其本地 class 加载程序来查找 JAXB API。反过来,它也将它链接到服务器的版本。
3) JAX-WS 使用线程上下文 class 加载器来加载其实现。它在父级最后一个应用程序中找到它。
4) 当链接实现 class 时,它使用其本地 class 加载器查找 JAXB API,后者在应用程序本地找到它。
5) 现在的实现链接到相同的两个版本 class:
JAXWSImpl -> JAXWSAPI -> JAXB(服务器)
JAXWSImpl -> JAXB(应用程序)
JVM 无法容忍,并抛出 LinkageError。
解决方案可以通过以下两种方式之一来解决:
1) 将 JAX-WS API 添加到应用程序 - 这会阻止上面 #1 中的初始委托
2) 从应用程序中删除 JAXB API(和实现,如果提供的话)——这会导致 #4 中的链接向下委托给 JAXB 服务器,所以它总是从同一个地方加载.
无论哪种方式,诀窍是确保所有必需的 classes 通过相同的 class 加载程序可供应用程序使用。
我有一个部署在 WebSphere 9.0.5.2 上的应用程序,我想在其中使用 CXF 进行 Web 服务调用,但我收到了这个 ServiceConfigurationError
WrapperedException { java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider org.apache.cxf.jaxws.spi.ProviderImpl could not be instantiated
进一步查看堆栈跟踪,我发现这是由 LinkageError 引起的
Caused by: java.lang.LinkageError: loading constraint violation when overriding method
"javax/xml/ws/spi/ServiceDelegate.createDispatch(Ljavax/xml/namespace/QName;Ljavax/xml/bind/JAXBContext;Ljavax/xml/ws/Service$Mode;)Ljavax/xml/ws/Dispatch;" during creation of class
"org/apache/cxf/jaxws/ServiceImpl": loader
"com/ibm/ws/classloader/CompoundClassLoader@832133d2" of class
"org/apache/cxf/jaxws/ServiceImpl" and loader
"com/ibm/oti/vm/BootstrapClassLoader@2eec706a" of class
"javax/xml/ws/spi/ServiceDelegate" have different types for the method signature
我知道这可能是由多个库对 QName
或 JAXBContext
具有不同定义引起的,但我认为我已经排除了这些可能性。
我也知道 WebSphere 有它自己的 JAX-WS 和它自己的 ServiceDelegate.createDispatch 方法签名,我已经尝试按照此处的说明在 WebSphere 中将 DisableIBMJAXWSEngine
设置为 true
Using a third-party JAX-WS web services engine
我仍然无法摆脱这个错误,对于接下来要尝试什么几乎一头雾水。任何建议表示赞赏!!!
这里的问题是 JAXB API、JAX-WS API 和 JAX-WS 实现的应用程序和服务器副本之间的交叉链接。该应用程序(配置了父级最后 class 加载委派,因此它在委派给父级之前在本地搜索)包含 JAX-WS 实现和 JAXB API/impl,但它不包含 JAX-WS API。由于 JAX-WS 引用 JAXB,我们得到以下链接模式:
1) 某些应用程序 class 引用了 JAX-WS API。因为它没有打包在应用程序中,所以它是从服务器库中加载的。
2) 当链接 API class 时,它使用其本地 class 加载程序来查找 JAXB API。反过来,它也将它链接到服务器的版本。
3) JAX-WS 使用线程上下文 class 加载器来加载其实现。它在父级最后一个应用程序中找到它。
4) 当链接实现 class 时,它使用其本地 class 加载器查找 JAXB API,后者在应用程序本地找到它。
5) 现在的实现链接到相同的两个版本 class:
JAXWSImpl -> JAXWSAPI -> JAXB(服务器) JAXWSImpl -> JAXB(应用程序)
JVM 无法容忍,并抛出 LinkageError。
解决方案可以通过以下两种方式之一来解决:
1) 将 JAX-WS API 添加到应用程序 - 这会阻止上面 #1 中的初始委托
2) 从应用程序中删除 JAXB API(和实现,如果提供的话)——这会导致 #4 中的链接向下委托给 JAXB 服务器,所以它总是从同一个地方加载.
无论哪种方式,诀窍是确保所有必需的 classes 通过相同的 class 加载程序可供应用程序使用。