Morty
Morty

Reputation: 1736

Websphere: Shared libraries in common classloader earlier on classpath than application modules, even with parent last policy

Background: I have the following problem: I have several WAR files I need to have deployed on same Websphere server. The WAR files use libraries that depend on having a specific version of XMLSec regisered as the XML Signature Provider (with the Java Security class). Currently I bundle this library with each WAR file (since the WAR files also need to work standalone and on Tomcat's without any special shared library configuration etc.). Each WAR files registers the provider with Security.addProvider() in a ServerContextListener. But this causes problems in the multi-WAR setup, because if one WAR file does the registration with Security.addProvider) and another WAR files tries to fetch it using the XMLSignatureFactory class (which is actually a javax.* class contained inside the XMLSec JAR itself, but which ultimately calls back to the global provider list configured with Security.addProvider), then it causes a ClassCastException inside XMLSignatureFactory, because this class does a cast of what it gets from Security into to its own version of the provider classes, which doesn't work. The exact stack trace is as follows:

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)

By the way this is not a case of conflict with different versions of XMLSec being in play or conflicts with Websphere's own version. There is only one version albeit it is loaded from different WAR's.

Of course the solution is to have the xmlsec library loaded with a common classloader so that there is only one version of the classes loaded that all WAR files see, which would avoid ClassCastExceptions etc.. But here is the rub: I also need to have each application loaded with the "parent last" policy - or rather, I need the JAR files inside each application to take precedence over Websphere's built-in version of the libraries (for instance Axis2 that I also include in the WAR filesetc.). Furter, I would prefer that I can keep the xmlsec library in each WAR files' WEB-INF/lib folder, so that the WAR files can still work stand-alone (i.e. in other environments which might not have the shared library configured etc.).

So basically I want to have a common class loader loading the XMLSec library, say, somewhere from disk. Let's denote that [SHARED XMLSEC]. Then I want each application classpath to ultimately appear like this:

App1: [SHARED XMLSEC][App1 WEB-inf/lib][Websphere libraries][JDK libraries]

App2: [SHARED XMLSEC][App2 WEB-inf/lib][Websphere libraries][JDK libraries]

etc.

In such a configuration it doesn't matter if App1+App2 themselves contain the XMLSec library since the shared one will take precedence so they will use the common one. At the same time, App1+App2 are still free to override other built-in Websphere libraries (Axis2).

Is it possible to realize this configuration and what options do I need to set? Do you see alternative ways to achieve the same objective?

Upvotes: 2

Views: 2025

Answers (1)

Haxiel
Haxiel

Reputation: 693

Since you have a conflict between classes here, I would suggest going for isolated class loaders for each application. On the server side, setting the class loader policy to 'Multiple' should provide isolation between applications.

Once you have this set, configure class loading at the application level to the 'Parent last' configuration for both the applications.

The following Knowledge Center link has the relevant instructions [Steps 2,3 & 4 under the 'Procedure' section] : http://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/trun_classload.html

[Note: The version of WAS in use is not specified in the question. The Knowledge Center link refers to version 8.5.5.]

Upvotes: 0

Related Questions