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)