views:

112

answers:

2

I have read that it is possible with Tomcat 5.5+ to deploy a war to a Tomcat server without a restart. That sounds fantastic but I guess I am too skeptical about this functionality and it's reliability. My previous experience (with Websphere) was that it was a best practice to restart the server to avoid memory problems, etc. So I wanted to get feedback as to what pitfalls might exist with Tomcat.

(To be clear about my experience, I developed java web apps for 5 years for a large company that partitioned the app developers from the app server engineers - we used Websphere - so I don't have a lot of experience with running/configuring any app servers myself)

+2  A: 

In general, there are multiple type of leaks and they apply to redeploy-scenarios. For production systems, it's really the best to perform restarts if possible, as there are so many different components and libraries used in todays applications that it's very hard to find them all and even harder to fix them. Esp. if you haven't got access to all source code.

  • Memory leaks
  • Thread and ThreadLocal leaks
  • ClassLoader leaks
  • System resource leaks
  • Connection leaks

ClassLoader leaks are the ones which bite at redeployment.

They can be caused by everything. Really, i mean everything:

  • Timers: Timers have Threads and Threads created at runtime inherit the current context class loader, which means the WebappClassloader of Tomcat.
  • ThreadLocals: ThreadLocals are bound to the thread. App servers use Thread pools. When a ThreadLocal is bound to a Thread and the Thread is given back to the pool, the ThreadLocal will stay there if nobody removes() it properly. Happens quite often and very hard to find (ThreadLocals do not have a name, except the rarely used Spring NamedThreadLocal). If the ThreadLocal holds a class loaded by the WebappClassloader, you got a ClassLoader leak.
  • Caches: e.g. EhCache CacheManager
  • Reflection: JavaBeans Introspector (e.g. holding Class or Method caches)
  • JDBC Drivers: they shouldn't be in the .war file anyway. Leak due to static registry
  • Static libraries which cache ClassLoaders, such as Commons-Logging LogFactory

Specific to Tomcat, my experience is as follows:

  • For simple apps with "clean" libraries, it works fine in Tomcat
  • Tomcat tries very hard to clean up classes loaded by the WebappClassloader. For example, all static fields of classes are set to null when a webapp is undeployed. This sometimes leads to NullPointerExceptions when code is run while the undeployment is happening, e.g. background jobs using a Logger
  • Tomcat has a Listener which cleans up even more stuff. Its called org.apache.catalina.core.JreMemoryLeakPreventionListener and was submitted recently to Tomcat 6.x

I wrote a blog post about my experience with leaks when doing redeployment stresstesting - trying to "fix" all possible leaks of an enterprise-grade Java Web Application.

mhaller
Just an additional note, they mysql driver fired off a thread that never stopped - causing a leak on redeployment in tomcat They've fixed that in either 5.1.11 or 5.1.12 - if you're using mysql , make sure you got the latest driver
nos
Sweet, thanks guys.
sdek
A: 

Hot deployment is very nice as it usually is much faster than bringing the server up and down.

mhaller has written a lot about avoiding leaks. Another issue is for active users to have their session survive the application "reboot". There are several things that must be taken care of, but which all in all means that their session must be serializable and THEN deserialize properly afterwards. This can be a bit tricky if you have stateful database connections etc, but if your code is robust against database hickups anyway that shouldn't be too bad.

Also note that some IDE's allow updating code inside the WAR (in the same way as applications) when saving a modified source file, instead of having to redeploy. MyEclipse does this rather nicely.

Thorbjørn Ravn Andersen