acerphenix
acerphenix

Reputation: 343

Is it necessary to restart tomcat when redeploy a war?

I know Tomcat can reload the .war file when redeploy it, I don't need to kill the Tomcat process and restart it. I can remove the .war, wait for Tomcat to undeploy it, and copy the new .war to the web path. But, after many times of trivial update war without restart the Tomcat, is it possible that Tomcat will not release the memory effectively or cause some performance issues? Assume there is only one war application in one Tomcat instance.

Upvotes: 5

Views: 3903

Answers (2)

Usman Mutawakil
Usman Mutawakil

Reputation: 5259

Yes. It is far cleaner to stop Tomcat, deploy your new war, then restart Tomcat. One drawback is much of your application classes by default won't be loaded till a new request comes in to hit your application but its not a huge issue. Just means theres a few seconds of startup on the very first request to your new WAR. This is how we deploy wars in production.

Also allows us to setup health-checking in the logs if the new war prevents Tomcat from starting up correctly then we rollback the war knowing theres an issue, but thats a separate topic.

What About Down Time?

This might be out of scope of your question but when you want to prevent users from seeing any downtime you would run multiple instance of tomcat and deploy and restart one at a time.

Upvotes: 1

The basic problem is that Java does currently not provide any kind of isolation between the parts of code running in a Java Virtual Machine (JVM), in the same way that an operating system does with processes. You can kill a process without affecting another process under Windows/Linux/etc. All you can do is ensuring that things can be garbage collected.

For Tomcat the way that WAR's are being handled - according to the various specifications - require that each war has its own classloader that is responsible for running that code. When the WAR is undeployed the final result should be that that class loader should be garbage collected.

Unfortunately the garbage collector can only handle objects that are completely unreferenced, and there is a large set of subtle bugs that can be present in WAR code that can prohibit this, and then every redeploy cause another classloader to be created and none destroyed so you have a memory leak. A lot of effort has gone into detecting and working around these type of bugs inside Tomcat itself, but it is close to impossible to do 100% right without JVM support.

The only cure besides fixing the WAR is to restart the JVM.

You can watch the memory usage with VisualVM even in production to see what happens over time with the Tomcat JVM.

Upvotes: 6

Related Questions