OpenSSO provides functionality of securing Web Services on various platforms.
This feature mainly includes :
1.Security Token Service
OpenSSO server is hosted as Trusted Authority being Security Token Service.
2.Web Services Security Agents
SOAP providers or plugins based on JSR 196 SPI and supported in Glassfish (Sun App Server 9.0 onwards) container. These plugins as the interceptors that secure and validate web services communication.
3.Client API
WS-Trust client API to get security tokens from OpenSSO hosted STS end point.
Client API to secure and validate web service request / response, using WS-Security tokens (SAML, X509, UserName, Kerberos, etc.)
OpenSSO uses Metro web services framework for WS-Trust and WS-Security (unified JSR 196) functionalities.
OpenSSO is built, shipped an deployed as single Web Application (.war file) and this web application is supported on all of the following containers :
1.Sun Java System Application Server 9.1 Update 1 and Update 2
2.Glassfish Application Server V2 UR1 and UR2
3.Sun Java System Web Server 7.0 Update 3
4.Apache Tomcat 5.5.x and 6.x
5.BEA WebLogic Server 9.2 MP2
6.BEA WebLogic Server 10.x
7.Oracle Application Server 10g
8.IBM WebSphere Application Server 6.1
9.Apache Geronimo Application Server 2.1.1
10.JBoss Application Server 4.x
Requirement :
OpenSSO web application when deployed as server (hosted STS end point) should be supported in all above mentioned 10 containers, with underline Metro web services framework for WS-Trust and WS-Security functionalities. Also for such support, we should not require any container specific settings / changes in either OpenSSO web application or in the container itself.
Problem :
OpenSSO uses underline metro jar files (webservices-api.jar, webservices-rt.jar, webservices-tools.jar, webservices-extra-api.jar, webservices-extra.jar, etc.) to build Web Services Security functionality on top. All these jar files are using latest 2.1 version of jaxb, jax-ws, saaj, etc. in OpenSSO web application (these jar files are bundled in the web app, under WEB-INF/lib). But OpenSSO web app has to run on all above 8 web containers which includes older versions (2.0) of jaxb, jax-ws, saaj, etc. jar files and keep them in container's global class path.
Hence there is a conflict.
Solution :
Implement OpenSSO specific Classloader logic to load web app's WEB-INF/lib jars (web services jar files of jaxb 2.1 version) in separate classloader (parallel to the container's classloader) and not conflict with web container's classpath and its classloader.
Theory :

STS entry or first invocation points from OpenSSO's web.xml bootstrap FAMClassLoader before invoking any Metro (web services relates) class files.
The first thing we check in FAMClassLoader is if Container classloader can load everything we need correctly, i.e. 2.1 classes. So we first check if it's loading JAXB API 2.1. This is done by trying to get resource (ClassLoader.getResource) of the class that is new in 2.1 version (new webservices-*.jar files). If this check detected that our environment (Container classloader) is already loading JAXB API 2.1 for us, then there's nothing else needed. We just proceed with the Container classloader to load all the classes.
But if this check detected that our environment is loading 2.0 API, then the real functionality of FAMClassLoader starts. First, we create a MaskingClassLoader that selectively disables (masks or hides) delegation of JAXB 2.1 API and everything that depends on it (like all the RI code) to the parent (Container) classloader.
/**
* The list of package prefixes we want the
* {@link MaskingClassLoader} to prevent the parent
* classLoader from loading.
*/
public static String[] maskedPackages = new String[]{
"com.sun.istack.tools.",
"com.sun.tools.jxc.",
"com.sun.tools.xjc.",
"com.sun.tools.ws.",
"com.sun.codemodel.",
"com.sun.relaxng.",
"com.sun.xml.xsom.",
"com.sun.xml.bind.",
"com.sun.xml.bind.v2.",
"com.sun.xml.messaging.",
"com.sun.xml.ws.",
"com.sun.xml.ws.addressing.",
"com.sun.xml.ws.api.",
"com.sun.xml.ws.api.addressing.",
"com.sun.xml.ws.server.",
"com.sun.xml.ws.transport.",
"com.sun.xml.wss.",
"com.sun.xml.security.",
"com.sun.xml.xwss.",
"javax.xml.bind.",
"javax.xml.ws.",
"javax.jws.",
"javax.jws.soap.",
"javax.xml.soap.",
"com.sun.istack.",
"com.sun.identity.wss.",
"com.sun.identity.wssagents.",
"com.sun.org.apache.xml.internal.",
"com.sun.org.apache.xpath.internal.",
"com.sun.org.apache.xalan.internal.",
"com.sun.org.apache.xerces.internal.",
"com.sun.identity.saml.xmlsig.",
"com.sun.identity.xmlenc.",
"com.sun.xml.stream."
};
Then we create an URLClassLoader beneath it, by specifying the jar files of the JAXB 2.1 APIs. Now we have a classloader that can load JAXB API 2.1 and its RI without interference from the existing environment.
/**
* The list of jar files to be loaded by FAMClassLoader.
*/
public static String[] jars = new String[]{
"webservices-api.jar",
"webservices-rt.jar",
"webservices-tools.jar",
"webservices-extra-api.jar",
"webservices-extra.jar",
"opensso.jar",
"openssowssproviders.jar",
"xalan.jar",
"xercesImpl.jar",
"openfedlib.jar"
};