背景: 我有以下问题:我需要在同一个Websphere服务器上部署多个WAR文件。 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获取的内容转换为其自己的提供程序类版本,不起作用。确切的堆栈跟踪如下:
引起:java.lang.ClassCastException: org.apache.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory 与javax.xml.crypto.dsig.XMLSignatureFactory不兼容 javax.xml.crypto.dsig.XMLSignatureFactory.findInstance(XMLSignatureFactory.java:202) 在 javax.xml.crypto.dsig.XMLSignatureFactory.getInstance(XMLSignatureFactory.java:292)
顺便说一下,这不是与不同版本的XMLSec发生冲突或与Websphere自己的版本冲突的情况。只有一个版本,尽管它是从不同的WAR加载的。
当然解决方案是让xmlsec库加载一个通用的类加载器,这样只有一个版本的类加载了所有WAR文件,这样可以避免ClassCastExceptions等。但是这里有一个问题:我也是需要让每个应用程序都加载“父最后一个”策略 - 或者更确切地说,我需要每个应用程序中的JAR文件优先于Websphere的内置版本的库(例如我也包含在WAR文件集中的Axis2)。 )。另外,我希望我可以将xmlsec库保存在每个WAR文件的WEB-INF / lib文件夹中,这样WAR文件仍然可以独立工作(即在其他可能没有配置共享库的环境中)。 )。
所以基本上我想要一个通用的类加载器加载XMLSec库,比如从磁盘的某个地方加载。我们用[SHARED XMLSEC]来表示。然后我希望每个应用程序类路径最终都显示如下:
App1:[SHARED XMLSEC] [App1 WEB-inf / lib] [Websphere库] [JDK库]
App2:[SHARED XMLSEC] [App2 WEB-inf / lib] [Websphere库] [JDK库]
等
在这样的配置中,App1 + App2本身是否包含XMLSec库并不重要,因为共享的库将优先使用,因此它们将使用公共库。与此同时,App1 + App2仍可以自由覆盖其他内置的Websphere库(Axis2)。
是否可以实现此配置以及我需要设置哪些选项?您是否看到了实现相同目标的其他方法?
答案 0 :(得分:0)
由于这里的类之间存在冲突,我建议为每个应用程序使用隔离的类加载器。在服务器端,将类加载器策略设置为' Multiple'应在应用程序之间提供隔离
完成此设置后,将应用程序级别的类加载配置为“父级最后一次”。两种应用程序的配置。
以下知识中心链接具有相关说明[步骤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。]