2 Replies Latest reply on Mar 27, 2008 3:21 PM by brian.stansberry

    Classloader leak in BasicThreadPool

    brian.stansberry

      Discussion of solution to http://jira.jboss.org/jira/browse/JBCOMMON-41 . For background on the problem see http://www.jboss.com/index.html?module=bb&op=viewtopic&t=129122 .

      I intend to solve this by having the BasicThreadPool set an appropriate TCCL on the pool thread:

      1) in the ThreadPoolFactory, just after creating the thread.
      2) when a thread is returned from a task, by subclassing ThreadPoolExecutor and overriding afterExecute().

      What TCCL gets set will be configurable by an injectable policy:

      package org.jboss.util.loading;
      
      public interface ClassLoaderSource {
      
       /**
       * Returns the classloader provided by this object; may return null.
       */
       ClassLoader getClassLoader();
      
      }
      


      If no ClassLoaderSource is injected, the TCCL will be set to null.

      In common-core I'll add a basic SimpleClassLoaderSource which simply returns getClass().getClassLoader(). In the AS, that would return the classloader that loads $JBOSS_HOME/lib.

      Somewhere else, (AS server module?) I'll add another impl that exposes a start() and stop() method. In start it will cache a weak ref to the current TCCL, and will thereafter return that. This could be injected into the jboss.system:service=ThreadPool pool; it will return the classloader in effect when conf/jboss-service.xml is deployed. That seems like a reasonable default for that service, or at least is likely closest to the "typical" behavior of the current thread pool.

        • 1. Re: Classloader leak in BasicThreadPool
          brian.stansberry

          Never mind the bit about start()/stop(). An impl can achieve the same behavior by caching the TCCL in effect when its constructor is invoked. And no lifecycle methods means no reason for the impl to not be in common-core.

          • 2. Re: Classloader leak in BasicThreadPool
            brian.stansberry

            I implemented and tested this before JBW, but this statement had me concerned so I'd put this on the shelf:

            If no ClassLoaderSource is injected, the TCCL will be set to null.


            That's a concern because I see a lot of possible usage of BasicThreadPool outside the AS itself. The above is a change in behavior and there's no way I can find and test every possible user of this class. Or at least I don't want to. ;-)

            So, I intend to instead make it that if no ClassLoaderSource is injected, the pool doesn't mess with the TCCL -- i.e. the existing behavior continues. We can then find the usages of BasicThreadPool in the JBoss AS codebase itself and make sure they have an appropriate ClassLoaderSource injected.