First - I may have posted this to the wrong list, if so please let me know a more 
appropriate place to post this.

I think there is a bug in the way Tomcat (or the JVM) handles class loading of 
classes.  The problem is this, I have a servlet (filter actually) that attempts to do 
some XSLT transformations.  When the filter tries to get a TransformerFactory a 
security exception is thrown, java.lang.SecurityException: sealing violation.  (The 
entire stack trace is at the bottom)
The root of the problem is when the class loader is trying to load a 
org.xml.sax.SAXException.  The resource is correct in that the code source url 
returned is "file:C:/Program Files/Apache 
Group/tomcat/webapps/jdst/WEB-INF/lib/xalan.jar"  the is the xalan.jar file bundled 
with my webapp.  The problem arises when the class loader tries to get the package 
with a call to "getPackage(pkgname);"  The class loader doesn't have this package and 
asks it's parent to see if it can find the package, and sure enough the parent has a 
package object from org.xml.sax.  The problem is this package was loaded earlier and 
it's url is "file:C:/Program Files/Apache Group/tomcat/lib/crimson.jar", so when the 
class loader is checking if the package is sealed it compares the two urls, finds they 
are not the same and throws the exception.  

A big assumption I have is that what I am doing is legal, I assume that the intention 
of the class loading systems is so that the base tomcat code can access it's classes 
with out worry, using whatever version of the classes it likes and that web apps can 
load their own version of classes without effecting the behavior of tomcat or other 
web apps.  Is this correct?

Now you can avoid this problem simply by not asking the package if it is sealed 
against the code source url.  Is this safe?

If you do that though another sort of configuration separation problem happens, in the 
crimson.jar file the property "javax.xml.parsers.DocumentBuilderFactory" is set to 
"org.apache.crimson.jaxp.DocumentBuilderFactoryImpl", so if I ask for a new 
TransformerFactory then I get an instance of 
"org.apache.crimson.jaxp.DocumentBuilderFactoryImpl", if I don't want that type of 
object I can set the property to my own class, e.g. 
"org.apache.xalan.processor.TransformerFactoryImpl" but now all the other web apps are 
forced to deal with my class.  Worse yet, some other webapp could come along and 
switch the property on me.  So it appears that there is no sort of "configuration 
layering" which I think is a problem.

Any help would be appreciated.

Thanks,
Robert Petersen

Stack Trace:
java.lang.SecurityException: sealing violation
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:225)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:217)
        at 
org.apache.catalina.loader.StandardClassLoader.findClass(StandardClassLoader.java:648)
        at 
org.apache.catalina.loader.StandardClassLoader.loadClass(StandardClassLoader.java:987)
        at 
org.apache.catalina.loader.StandardClassLoader.loadClass(StandardClassLoader.java:906)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
        at com.orangefood.xsltfilter.Filter.doFilter(Filter.java:40)
        at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:180)
        at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:251)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:977)
        at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:196)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:977)
        at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2041)
        at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
        at org.apache.catalina.valves.ValveBase.invokeNext(ValveBase.java:242)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:414)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:975)
        at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:159)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:977)
        at 
org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor.java:818)
        at org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.java:897)
        at java.lang.Thread.run(Thread.java:484)

Reply via email to