Add a class inside your JAR with the following code:
public class TomcatStartupListener implements org.apache.catalina.LifecycleListener {
public void lifecycleEvent(org.apache.catalina.LifecycleEvent event) {
if (event.getType().equals("after_start")) {
// call your main method here
}
}
}
Note: In order to compile this, you need to add <tomcat-dir>/lib/catalina.jar
to your classpath. Otherwise when compiling it won't be able to find the necessary interfaces (org.apache.catalina.LifecycleListener
and org.apache.catalina.LifecycleEvent
). Once you're done with the compiling, put the JAR as usual under <tomcat-dir>/lib
.
Now open <tomcat-dir>/conf/server.xml
and add the following under the <Server>
section:
<Listener className="com.yourpackage.TomcatStartupListener" />
Now whenever your Tomcat server starts, this TomcatStartupListener
class inside your JAR will be called, and you can invoke your main method. There are a whole lot of other event types too! You can use any of these event types:
- before_init
- after_init
- before_start
- configure_start
- start
- after_start
- before_stop
- stop
- configure_stop
- after_stop
- before_destroy
- after_destroy
This approach is necessary because of the way the classloaders work in Tomcat (or even most JVMs). Here are the important points from that link:
There are three aspects of a class loader behavior
Lazy Loading
Class Caching
Separate Namespaces
The JVM will get very heavy if all classes inside all JARs get loaded indiscriminately. So the classes inside shared JARs are loaded only on-demand. The only way for you to invoke the main method is to add the above lifecycle listener.