java - Websphere:公共(public)类加载器中的共享库比应用程序模块早于类路径,即使使用父级最后策略

标签 java websphere classloader xmlsec

背景: 我有以下问题:我有几个 WAR 文件需要部署在同一个 Websphere 服务器上。 WAR 文件使用的库依赖于将特定版本的 XMLSec 注册为 XML 签名提供程序(使用 Java 安全类)。目前,我将此库与每个 WAR 文件捆绑在一起(因为 WAR 文件也需要独立工作并且在 Tomcat 上运行,无需任何特殊的共享库配置等)。每个 WAR 文件都会在 ServerContextListener 中使用 Security.addProvider() 注册提供程序。但这会在多 WAR 设置中导致问题,因为如果一个 WAR 文件使用 Security.addProvider 进行注册,而另一个 WAR 文件尝试使用 XMLSignatureFactory 类(实际上是 XMLSec JAR 本身中包含的 javax.* 类,但最终回调到使用 Security.addProvider 配置的全局提供程序列表)来获取它,那么它会在 XMLSignatureFactory 内导致 ClassCastException,因为该类将从 Security 获取的内容强制转换为它自己的提供程序类版本,这不会导致任何问题。不工作。确切的堆栈跟踪如下:

Caused by: java.lang.ClassCastException: org.apache.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory incompatible with javax.xml.crypto.dsig.XMLSignatureFactory at javax.xml.crypto.dsig.XMLSignatureFactory.findInstance(XMLSignatureFactory.java:202) at javax.xml.crypto.dsig.XMLSignatureFactory.getInstance(XMLSignatureFactory.java:292)

顺便说一句,这并不是与正在使用的不同版本的 XMLSec 发生冲突,也不是与 Websphere 自己的版本发生冲突。尽管它是从不同的 WAR 加载的,但只有一个版本。

当然,解决方案是使用公共(public)类加载器加载 xmlsec 库,这样所有 WAR 文件都可以看到加载的类的一个版本,这将避免 ClassCastExceptions 等。但问题是:我还需要使用“父级最后”策略加载每个应用程序 - 或者更确切地说,我需要每个应用程序内的 JAR 文件优先于 Websphere 的内置版本的库(例如我也包含在 WAR 文件中的 Axis2 等)。此外,我希望可以将 xmlsec 库保留在每个 WAR 文件的 WEB-INF/lib 文件夹中,以便 WAR 文件仍然可以独立工作(即在可能没有配置共享库的其他环境中等)。

所以基本上我想要一个通用的类加载器来加载 XMLSec 库,比如说,从磁盘的某个地方。我们将其表示为[SHARED XMLSEC]。然后我希望每个应用程序类路径最终显示如下:

App1:[共享 XMLSEC][App1 WEB-inf/lib][Websphere 库][JDK 库]

App2:[共享 XMLSEC][App2 WEB-inf/lib][Websphere 库][JDK 库]

等等

在这样的配置中,App1+App2 本身是否包含 XMLSec 库并不重要,因为共享库将优先,因此它们将使用公共(public)库。同时,App1+App2 仍然可以自由覆盖其他内置的 Websphere 库(Axis2)。

是否可以实现此配置以及我需要设置哪些选项?您是否有其他方法可以实现相同的目标?

最佳答案

由于这里的类之间存在冲突,我建议为每个应用程序使用独立的类加载器。在服务器端,将类加载器策略设置为“多个”应该可以在应用程序之间提供隔离。

完成此设置后,将应用程序级别的类加载配置为两个应用程序的“父级最后”配置。

以下知识中心链接包含相关说明[“程序”部分下的步骤 2,3 和 4]: http://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/trun_classload.html

[注意:问题中未指定正在使用的 WAS 版本。知识中心链接引用版本8.5.5。]

关于java - Websphere:公共(public)类加载器中的共享库比应用程序模块早于类路径,即使使用父级最后策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37590201/

相关文章:

java - 连接到 RAC 数据库的正确 JDBC URL 是什么

java - 使用 jpa/hibernate Spring 添加新条目时在 Postgresql 中增加值

JSF 2 相当于 IBM 的 hx :scriptCollector pre- and postRender

java - web.xml - Java Servlet 过滤器和 WebSphere - URL 模式问题

java - Eclipse 导出为可执行 jar NullPointerException

java - EAP 6.1 中的类加载问题 - JBoss 7.2/WAR 类看不到 EAR 类

java - Log4j 记录器和并发

java - 递归对数以找到最接近另一个整数 x 的形式 = (2)^n 的最大整数 (n)

java - 如何纠正 "The injection target must not be declared static."警告

java - 是否可以加载类而不加载引用的类/导入?