Details
-
Type: Improvement
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: 1.0-beta-5
-
Fix Version/s: None
-
Component/s: PicoContainer (Java)
-
Labels:None
-
Environment:Any servlet container using multiple classloaders. An example of this would be Tomcat.
-
Number of attachments :
Description
The exception below is caused by having picocontainer libraries in the parent
classloader (Tomcat's shared/lib) and the ContainerComposer implementation in
the child classloader (WEB-INF/classes). Well, that's actually the symptom,
not the cause. The cause is on line 79 of
org.picoextras.servlet.ServletContainerListener...
result = (ContainerComposer) Class.forName(className).newInstance();
Using Class.forName(String) is a no, no, in a Java2 environment with multiple
classloaders. Not providing the thread context classloader with which to load
the provided class renders the picoextra's servlet library unusable in shared
environments. This is especially apparent under containers such as Tomcat
which uses an extensive classloader hierarchy. The solution is to replace the
above line with this...
result = (ContainerComposer) Class.forName(className, true, Thread.currentThread().getContextClassLoader()).newInstance();
Now it doesn't matter where the picocontainer libraries exist. As long as they
are in some classloader in the same VM as the client classes, things will work
just fine.
patch coming up!
Jake
2004-02-07 18:03:21 StandardContext[/picoservlet]Exception sending context initialized event to listener instance of class org.picoextras.servlet.ServletContainerListener
java.lang.RuntimeException: Cannot instanciate container assembler class. Root cause: java.lang.ClassNotFoundException: org.picoextras.servlet.sample.SampleContainerComposer
at org.picoextras.servlet.ServletContainerListener.loadAssembler(ServletContainerListener.java:82)
at org.picoextras.servlet.ServletContainerListener.contextInitialized(ServletContainerListener.java:39)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3775)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4269)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:866)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:850)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:638)
at org.apache.catalina.core.StandardHostDeployer.addChild(StandardHostDeployer.java:840)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:252)
at org.apache.commons.digester.SetNextRule.end(SetNextRule.java:256)
at org.apache.commons.digester.Rule.end(Rule.java:276)
at org.apache.commons.digester.Digester.endElement(Digester.java:1058)
at org.apache.catalina.util.CatalinaDigester.endElement(CatalinaDigester.java:123)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.commons.digester.Digester.parse(Digester.java:1567)
at org.apache.catalina.core.StandardHostDeployer.install(StandardHostDeployer.java:520)
at org.apache.catalina.core.StandardHost.install(StandardHost.java:906)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:527)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:472)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1008)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:394)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:166)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1133)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:832)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1125)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:518)
at org.apache.catalina.core.StandardService.start(StandardService.java:519)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:2345)
at org.apache.catalina.startup.Catalina.start(Catalina.java:598)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:297)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:398)
Activity
Field | Original Value | New Value |
---|---|---|
Attachment | patch.diff [ 11358 ] |
Status | Open [ 1 ] | Closed [ 6 ] |
Resolution | Fixed [ 1 ] |
Patch fixing use of Class.forName(String) to be Class.forName(String, boolean, ClassLoader) with the ClassLoader parameter being the container-provided thread context class loader allowing the picoextra's servlet library to be shared in a parent class loader while still being able to find a configured ContainerComposer implementation in a child class loader.