javax.transaction.* 类 WebSphere 9 上的 LinkageError

LinkageError on WebSphere 9 for javax.transaction.* classes

我有一个 Web 应用程序,过去在许多 Web 服务器(tomcat、jboss、weblogic 和 websphere)上 运行 都很好。但是,现在在 WebSphere 9 上部署时出现错误。

该应用程序包含 jar javax.transaction-api-1.2。它的一些 classes,例如 javax.transaction.xa.XAResource,也包含在 Java SE 中,但不是全部。有些特定于 Java EE,并且是我应用程序中某些第 3 方库所必需的。该应用程序始终使用 child-first (parent-last) classloader 进行部署。 当应用程序尝试加载 Oracle JDBC 驱动程序时,WebSphere 9 在启动期间抛出此错误:

java.lang.LinkageError: loading constraint violation: loader "com/ibm/ws/classloader/CompoundClassLoader@7157be44" previously initiated loading for a different type with name 
"javax/transaction/xa/XAResource" defined by loader "com/ibm/oti/vm/BootstrapClassLoader@422c7b1b"

请注意,我们实际上并未在应用中使用 XA 事务,我们使用的是常规事务。

在其他服务器和以前版本的 WebSphere 上,这从来都不是问题。服务器不关心我们从 war 内部加载 XAResource,即使它之前已加载到服务器的某个位置。现在 WebSphere 9 不同了,它说应用程序 classloader 已经从服务器加载了这个 class,但我不知道为什么或什么时候发生的。

知道如何解决这个问题吗?

从您的应用程序中删除交易 API。 JTA 1.2 已经包含在服务器中并且在您的应用程序中没有提供任何价值。将 Java EE/SE API 带入父级最后的 class 加载程序总是有风险的,除非您 100% 确定它们在技术上是必要的,因为它们可能会导致问题喜欢这个

我不能说这在以前的服务器版本中是如何工作的(在执行像这样的链接问题方面有一些 Java 级别的变化),但解决方案相当简单。

最后我们做了两件事来解决这个问题。

1) 我们将 jta jar 升级到版本 1.3 (link here)。这个 jar 通过避免重复 类 解决了这个问题——它只包含 J2EE 类 而忽略了 JVM 中已经包含的 J2SE 类。 2) 我们将 WebSphere 服务器从 9.0.0.7 升级到 9.0.0.11。

当时,我怀疑只升级 jar 就足够了,但我们的 QA 有一些问题,他们还升级了服务器。由于时间不够,我们没有进一步调查,只是决定两者都做。