tags:

views:

1142

answers:

2

Can you hot deploy JAR files on Tomcat 5? The idea is to avoid restarting Tomcat and still be able to load (via reflection) some class from a newly added JAR. Can it be done? How? Is it unadvisable for a production system? Thanks

Edit: my scenario requires the addition of new JAR files for which the names aren't known in advance. Can the server be "watching" a directory of JARs rather than specific JARs?

+2  A: 

Yes, it is possible. A few tricks from the Tomcat stable, assuming that automatic deployment was switched on:

  1. If a WAR file does not have a corresponding directory, it will be automatically expanded and deployed.
  2. Changes to WEB-INF\web.xml will cause a reload of the application.
  3. Updates to exploded WAR files will cause a redeployment
  4. Changes to the XML configuration files are supposed to cause a redeployment

Of course, this is not advisable for production systems. Not that this feature is faulty, but applications can be poorly coded to not clean up resources or unload classes on undeployment. This will result in certain classes remaining in memory. When the newer version of the application is redeployed, you will encounter vague errors due to the older version of the classes being present. Poorly written singletons, are often the biggest cause of this issue.

The protocol that I follow, to avoid any similar issues is to undeploy the application, bring down Tomcat, verify the 'sanity' of the filesystem directories of Tomcat, delete any resources left behind, restart the Tomcat instance and redeploy the application. It does look a little heavy handed, but I've been burnt enough.

Vineet Reynolds
+3  A: 

Tomcat doesn't provide any mechanism to reload a single JAR. However, the whole context can be reloaded.

You just need to tell Tomcat to watch for your JAR in context.xml, like this,

<?xml version="1.0" encoding="UTF-8"?>
<Context override="true" swallowOutput="true" useNaming="false">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>WEB-INF/lib/your.jar</WatchedResource>
  <Manager pathname=""/>
</Context>

We do this on production. Tomcat used to have some memory leaks but we haven't found any issues with Tomcat 5.5 or later.

Don't know if it's still necessary. We have to make following calls to avoid memory leak during hot deployment.

   public void contextDestroyed(ServletContextEvent sce) {
        // To fix the known memory leaks during re-deploy
        ClassLoader contextClassLoader = 
         Thread.currentThread().getContextClassLoader();
        LogFactory.release(contextClassLoader);

        java.beans.Introspector.flushCaches();
        ...
   }
ZZ Coder
+1 for LogFactory.release() call. Although I don't use Apache Commons Logging, it is code like this that increases confidence in an app. More info @http://wiki.apache.org/jakarta-commons/Logging/UndeployMemoryLeak
Vineet Reynolds
Thanks guys... please see edit in OP.
Germán