Hi Tomcat Community:

BACKGROUND:
I have a Servlet-based WEBAPP that is running in Tomcat7, JDK 1.6.0_27 on 
Windows Server 2008 R2 64-bit - all 64-bit.  We make use of class.newInstance 
quite a bit as we have a fairly modular, interface-based system, and create 
class instances on the fly.  As part of our extensibility,  I'm also using a 
pretty well documented "hack" [The code is listed below]  for dynamically 
adding JAR(s) so they are accessible immediately without stopping our WEBAPP or 
the actual Tomcat server process.   This process has worked great for both 
JAR(s) in the WEB-INF/lib and for ones we dynamically added - until you try and 
stop the WEBAPP via the Tomcat manager app.

PROBLEM:
This solution for dynamically loading JARs worked great as long as we 
start/stop the actual Tomcat server process, but I found out the JAR(s) that I 
have been dynamically loading this way are not released when you stop the 
WEBAPP.  I am using SysInternals Process Explorer to monitor the open file 
handles of the Tomcat7 process.  I can see that when I stop the WEBAPP, the 
dynamically loaded JAR is still referenced.

QUESTION:
I made an assumption that calling 
Thread.currentThread().getContextClassLoader() would provide me the classloader 
of my WEBAPP - which should be the same classloader that all the JARs in the 
WEB-INF/lib are in.  We control the WEBAPP, so I assumed this was a safe 
assumption.

The usage of the dynamically loaded JAR(s) is no different than the default 
JAR(s) in WEB-INF/lib.  None of the WEB-INF/lib JARs are left open when we stop 
the WEBAPP - only the JAR(s) that are loaded via the "addUrl" approach below.

I have been through a number of online articles when I first created this logic 
- including a PDF by Ted Neward [while at Developmentor] that described these 
approaches, but am not sure how to troubleshoot this further now.

If anyone has an answer or any suggestions, I would greatly appreciate it.

Thanks in advance,
Bob


Code to dynamically load JAR(s):

    public static void loadJarOnTheFly(File jarFile) throws IOException
    {
      Class<?>[] parameters = new Class[]{URL.class};

      // IMPORTANT: MUST use the webapp classloader - so derived extension 
classes can resolve their base classes
      ClassLoader contextClassLoader = 
Thread.currentThread().getContextClassLoader();

      // cast to a URL class loader so we can additional JAR(s) to the search 
path
        URLClassLoader webappClassLoader = (URLClassLoader)contextClassLoader;

        Class<?> sysclass = URLClassLoader.class;

        try
        {
            URL jarUrl = jarFile.toURI().toURL();

            Method method = sysclass.getDeclaredMethod("addURL", parameters);
            method.setAccessible(true);
            method.invoke(webappClassLoader, new Object[]{ jarUrl });
        }
        catch (Throwable t)
        {
            throw new IOException("Error, could not add URL to system 
classloader");
        }
    }



Bob DeRemer
Senior Director, Architecture and Development

http://www.thingworx.com<http://www.thingworx.com/>
Skype: bob.deremer
O: 717.505.7923
M: 717.881.3986

Reply via email to