Why do we need to restart a tomcat server whenever a class file is changed, is there no other way?
-
I also noticed this problem. One painful way to do this is changing your web.xml twice: once to some random HelloWorld class and then back to you changed class. Glad I got an answer here. – typesanitizer Aug 24 '14 at 05:40
-
Is this question because you want to keep production downtime minimum? Then tomcat's settings won't help you. It's already described in official documentation. – ha9u63a7 Jan 10 '18 at 20:49
8 Answers
You can configure Tomcat and make your webapp "reloadable". To do so, add reloadable=true
to the <Context>
element of your webapp. About the reloadable
attribute, the documentation says:
Set to
true
if you want Catalina to monitor classes in/WEB-INF/classes/
and/WEB-INF/lib
for changes, and automatically reload the web application if a change is detected. This feature is very useful during application development, but it requires significant runtime overhead and is not recommended for use on deployed production applications. That's why the default setting for this attribute is false. You can use the Manager web application, however, to trigger reloads of deployed applications on demand.

- 562,542
- 136
- 1,062
- 1,124
-
4* sigh * Give my votes to Pascal please, his is the more useful and comprehensive answer. Looking at his, it seems that development mode only checks for changes in JSPs, which isn't what the OP asked about. – Carl Smotricz Dec 09 '09 at 13:43
-
There certainly is! Start Tomcat in development mode, then each webapp will restart itself upon being redeployed.
From the Tomcat docs:
The servlet which implements Jasper is configured using init parameters in your global $CATALINA_BASE/conf/web.xml.
...
development - Is Jasper used in development mode (will check for JSP modification on every access)? true or false, default true.
There are settings you can change to adjust what exactly Tomcat will look for to check for updates. I usually deploy individual class files to their appropriate directory under WEB-INF/classes
and then
touch WEB-INF/web.xml
to kick-start a restart of the application; I think web.xml
is one of the files Tomcat checks by default.

- 66,391
- 18
- 125
- 167
-
2I may be wrong but this seem to be taken from the *Jasper 2 JSP Engine How To* (http://tomcat.apache.org/tomcat-6.0-doc/jasper-howto.html) and applies to JSPs, not classes. – Pascal Thivent Dec 09 '09 at 13:46
On a more general note, the reason you have to do this is because in Java, when a classloader loads a class, it cannot unload it. What Tomcat has to do is use a new classloader and reload all the classes it needs.

- 12,198
- 10
- 63
- 93
If you develop, your IDE should be able to do this transparently on a suitable server. E.g. the Dynamic Web Project in Eclipse knows how to talk to Tomcat.
If you deploy, then create WAR-files and deploy those. Tomcat knows how to redeploy a WAR-file.

- 73,784
- 33
- 194
- 347
If you're using WAR files to deploy, you can set autoDeploy=true
in the Tomcat config, which causes Tomcat to watch the web application root ("webapps" by default) for new or changed WAR files. If such a file is found, it is automatically deployed.
As Pascal Thivent said, though, you can use the Tomcat Manager application (/manager/html) to start, stop, deploy, and undeploy specific applications. If the files you're changing are in a specific application, this is a good way to get Tomcat to recognize the changes.

- 1,185
- 1
- 11
- 17
Besides setting autoDeploy=true in server.conf , you also should be careful not to put any classes in the shared classloader. Classes which are loaded by the shared class loader cannot be re-loaded.

- 905
- 1
- 8
- 17
Your question doesn't actually say whether you are concerned about a production downtime (i.e. reduce it by reloading the classes) or you want non-stop development. So I will try to clarify using the following points:
1) using <Context reloadable=true...
in your catalina.home/conf
directory you can make sure that your webapp reloads when a any class changes. You can add the resource change watchlist in <WatchedResources>
element.
2) But this will reload the context, re-initialise the classloader, empty it's cache, and everything will be as if the webapplication has just started.
This approach will still leave your server unusable, because you have reloaded the Servlet's context. The true "Reload" is
1) You swap the byte code of the class, with some restrictions 2) JVM will return that class when "loadClass()" is called for that classloader.
This is java instrumentation. You can write your own agent which can hook into your JVM either at the beginning or in flight. However, you cannot define new method, and change static variables. These are JVM native restrictions (for Oracle HotSpot JVM, that I know of). You can use a different JVM e.g. DCEVM which doesn't have such restriction. So it's up to you how you want to handle your problem. If you know what you are doing (!), you can get away with replacing classes one-by-one. And you can even define a "Brand New Class", reference that class object/method in an existing/loaded class and instrument it to to pick up changes.
I hope this helps. All the answers here are what you need to make your decision.

- 6,233
- 16
- 73
- 108