【问题标题】:ServiceConfigurationError caused by LinkageError in WebSphereWebSphere 中 LinkageError 导致的 ServiceConfigurationError
【发布时间】:2020-05-17 20:02:38
【问题描述】:

我有一个部署在 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 

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

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

Using a third-party JAX-WS web services engine

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

【问题讨论】:

  • 您的应用程序中是否有 JAX-WS 和/或 JAXB API 的副本,或者只有 CXF 实现?看起来正在发生的事情是某种交叉链接(我的阅读是 impl 引用 WAS 中的 API,然后 API 引用 WAS 中的 JAXB,而 impl 引用您的应用程序中的 JAXB)。如果我的猜测是正确的,您可以通过从应用程序中删除 JAXB(或共享库,但是您正在加载最后一个父类)或向其中添加 JAX-WS API 来解决此问题。
  • @Jarid 我有 cxf 库和 jaxb 库。我尝试删除 jaxb 库,但似乎需要它们,因为我无法再启动我的应用程序。我的库列表中没有看到 JAX-WS。
  • 如果您删除 JAXB API,您会遇到什么具体错误? JAXB 已经包含在 WAS 中很长时间了,除非您依赖于非常特定的版本。
  • @Jarid 事实证明,您将 JAX-WS api 添加到我的应用程序的建议解决了这个问题。如果您将其发布为答案,我会检查它,以便您获得信用。感谢您的帮助!!!
  • 完成! (另外,感谢您的建议,很高兴听到您已经启动并运行!)我还添加了对交联机制的更全面的技术描述,以防其他人在将来阅读此问题时有所帮助.

标签: java websphere jax-ws linkageerror


【解决方案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 向下委托给服务器,因此它总是从同一个地方加载。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 2015-02-23
    相关资源
    最近更新 更多