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