PicoContainer
  1. PicoContainer
  2. PICO-122

picoextra's servlet library unusable in shared multple classloader environment

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major 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 :
      1

      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

        Hide
        Jacob Kjome added a comment -

        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.

        Show
        Jacob Kjome added a comment - 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.
        Jacob Kjome made changes -
        Field Original Value New Value
        Attachment patch.diff [ 11358 ]
        Hide
        Paul Hammant added a comment -

        Applied.

        Show
        Paul Hammant added a comment - Applied.
        Paul Hammant made changes -
        Status Open [ 1 ] Closed [ 6 ]
        Resolution Fixed [ 1 ]

          People

          • Assignee:
            Unassigned
            Reporter:
            Jacob Kjome
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: