0

我有一个部署在 WebSphere 9.0.5.2 上的应用程序,我想在其中使用 CXF 进行 Web 服务调用,我得到了这个 This 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 

我知道这可能是由对QNameor具有不同定义的多个库引起的JAXBContext,但我想我已经排除了这些。

我也知道 WebSphere 有它自己的 JAX-WS 和它自己的 ServiceDelegate.createDispatch 方法签名,我已经尝试DisableIBMJAXWSEngine按照此处的说明在 WebSphere 中设置为 true

使用第三方 JAX-WS Web 服务引擎

我仍然无法摆脱错误,并且对于接下来要尝试什么感到不知所措。任何建议表示赞赏!

4

1 回答 1

1

这里的问题是应用程序和服务器的 JAXB API、JAX-WS API 和 JAX-WS 实现副本之间的交叉链接。该应用程序(配置了 parent-last 类加载委托,因此它在委托给 parent 之前在本地搜索)包含 JAX-WS 实现和 JAXB API/impl,但它不包含 JAX-WS API。由于 JAX-WS 引用 JAXB,我们得到以下链接模式:

1) 一些应用程序类引用了 JAX-WS API。因为它没有打包在应用程序中,所以它是从服务器库中加载的。

2) 当 API 类被链接时,它使用它的本地类加载器来查找 JAXB API。反过来,这也将其链接到服务器的版本。

3) JAX-WS 使用线程上下文类加载器来加载它的实现。它在 parent-last 应用程序中找到它。

4) 当实现类被链接时,它使用它的本地类加载器来查找 JAXB API,JAXB API 在应用程序本地找到它。

5) 现在的实现链接到同一个类的两个版本:

JAXWSImpl -> JAXWSAPI -> JAXB(服务器) JAXWSImpl -> JAXB(应用程序)

JVM 不能容忍这种情况,并抛出 LinkageError。

可以通过以下两种方式之一来解决该解决方案:

1) 将 JAX-WS API 添加到应用程序 - 这可以防止上面 #1 中的初始委托

2) 从应用程序中删除 JAXB API(和实现,如果提供) - 这会导致 #4 中的链接委托给 JAXB 服务器,因此它总是从同一个地方加载。

无论哪种方式,诀窍是确保所有必要的类都可以通过同一个类加载器提供给应用程序。

于 2020-05-22T12:49:19.753 回答