Saturday, May 28, 2011

Fixing Redeployment Issues for Servlet Applications on Windows

Deployment is hard, redeployment even harder from time to time - especially when your web container, say Tomcat, runs on Windows. Even if you did a good job in avoiding memory leaks and classloader issues, you may experience the problem that the running application fails to undeploy, leaving a couple of files in the webapps folder that could not be deleted.

When Bill designed his beautiful operating system (or whatever you want to call it), he decided to introduce pessimistic locking for file system resources. While this generally sounds good regarding concurrency issues, most of us will already have seen some downsides of this behavior, e.g. when trying to open a document by two users or performing an mvn clean or whatever.


The web container will feel this pain, too. Due to the nature of the JRE, resources are not immediately freed when an application is undeployed - they are just candidates to garbage collection now. So when the application's classloader is de-referenced due to application shutdown, resources such as file system handles may stay open for a while, until our friend GC comes along. If things turn out badly, this will cause the described interference with our redeployment process, since files with open handles cannot be deleted.


There are a couple of things you can do:
  • ditch Windows - seriously, you're doing server side stuff!! Grab any Linux, Solaris, *BSD (including MacOS) or whateverNIX and enjoy...
  • get help from my friends at Zeroturnaround and check out LiveRebel, their new magical tool for rolling out seemlessly
  • or: add the following listener to your servlet application


/**
* ServletContextCleanupListener uses a little hack to get rid of undeployment issues under Windows.
* Just in case you may ask: Free under Apache Software License
*
* @author Rene Gielen
*/
public class ServletContextCleanupListener implements ServletContextListener {

@Override
public void contextInitialized( ServletContextEvent sce ) {
// nothing to do
}

@Override
public void contextDestroyed( ServletContextEvent sce ) {
System.gc(); // No excuse - gc NOW
try {
Thread.sleep(1000); // ease, dude...
} catch ( InterruptedException ex ) {
// Intentionally left blank
}
}
}


My client is really happy now, since it solved all his problems. Actually it did not help me to convince him to ditch Windows *sigh*



Labels

howto (4) java (3) appclient (2) ejb (2) glassfish (2) jee6 (2) maven (2) netbeans (2) scm (2) tutorial (2) adp1 (1) android (1) announcements (1) cdi (1) dependencymanagement (1) deployment (1) eclipse (1) extusb (1) fluff (1) g1 (1) git (1) htc (1) jee (1) jsr299 (1) liferay (1) m2eclipse (1) miniusb (1) operations (1) plug (1) portlet (1) servlet (1) struts2 (1) svn (1) tomcat (1) windows (1)