4

Is there any mechanism, lifecycle event or callbacks, in Spring or Tomcat to notify once Tomcat server startup is completed? (I have 8 web applications and queues configured. I would prefer to get notification back to each application once all the applications are started.) I know Spring has the application listener, which can be used once the web application is initialized. But I cannot use it in my case because I would prefer to get a notification once all the web apps are initialized.

EDITED*

I've implemented a Tomcat listener to log the message, but I have absolutely no idea where to hook this listener.

I tried to create this bean using Spring and also adding the listener to web.xml both did not work.

Here is my code:

public class KPTomcatListener implements LifecycleListener {

    private static final Logger LOG = LoggerFactory.getLogger(KPTomcatListener.class);
    /**
     * All the events of tomcat
     * See: https://tomcat.apache.org/tomcat-10.0-doc/api/constant-values.html
     * AFTER_DESTROY_EVENT     "after_destroy"
     * AFTER_INIT_EVENT     "after_init"
     * AFTER_START_EVENT     "after_start"
     * AFTER_STOP_EVENT     "after_stop"
     * BEFORE_DESTROY_EVENT     "before_destroy"
     * BEFORE_INIT_EVENT     "before_init"
     * BEFORE_START_EVENT     "before_start"
     * BEFORE_STOP_EVENT     "before_stop"
     * CONFIGURE_START_EVENT     "configure_start"
     * CONFIGURE_STOP_EVENT     "configure_stop"
     * PERIODIC_EVENT     "periodic"
     * START_EVENT     "start"
     * STOP_EVENT     "stop"
     */
    private static int counter;
    
    @Override
    public void lifecycleEvent(LifecycleEvent arg0) {
        String event = arg0.getType();
        LOG.debug("Tomcat Events: " + (++counter) + " :: " + event);
        if(event.equals(org.apache.catalina.Lifecycle.AFTER_START_EVENT)) { // or "after_start"
            LOG.debug("Hey I've started");
        }
    }

}
ATutorMe
  • 820
  • 8
  • 14
Karthik Prasad
  • 9,662
  • 10
  • 64
  • 112
  • 1
    possible duplicate of [Java EE Enterprise Application: perform some action on deploy/startup](http://stackoverflow.com/questions/6120831/java-ee-enterprise-application-perform-some-action-on-deploy-startup) You can use WebContextListener that will give you exact this thing – jmj Mar 13 '14 at 21:06
  • @JigarJoshi A `ServletContextListener` is run before any `Filter` or `Servlet` instances are initialized. I think OP wants the whole web application. – Sotirios Delimanolis Mar 13 '14 at 21:14
  • @Sot I don't think OP want to initialize all servlet and filter, consider that there are some url patterns which gets hit only in certain cases (for example user is admin and logged in) how would that specific servlet (if configured) will get loaded without attempting to knock that URL – jmj Mar 13 '14 at 21:32
  • @JigarJoshi How are you interpreting `I would prefer to get notification back to each applications once all the applications are started`? – Sotirios Delimanolis Mar 13 '14 at 21:34
  • @Sot I understand that OP's container has 8 different web application that gets started and OP wants an action that flags on each application's startup – jmj Mar 13 '14 at 21:35
  • @JigarJoshi I don't think `once all the applications are started` means _on each application's startup_. In any case, the application hasn't started when `ServletContextListener#contextInitialized(..)` is called. – Sotirios Delimanolis Mar 13 '14 at 21:36
  • @Sot on successful context initialization that particular app has been started, if OP can do it for all the apps he can confirm that all of his web context have been initialized successfully – jmj Mar 13 '14 at 21:37
  • @JigarJoshi You have misunderstood my questiononce all the application started up means once all web the application is started not each application is started. I feel I don't get better advantage of using servlet context over application context. Both are specific to application not to the server. – Karthik Prasad Mar 14 '14 at 05:19
  • @JigarJoshi If you had marked as duplicate could you please unmark. as the question I asked is not the same. – Karthik Prasad Mar 17 '14 at 07:30
  • According to the [tomcat javadoc](https://tomcat.apache.org/tomcat-9.0-doc/api/constant-values.html#org.apache.catalina.Lifecycle.AFTER_START_EVENT) the String value is actually 'after_start', which is the value of org.apache.catalina.Lifecycle.AFTER_START_EVENT. – ATutorMe Nov 16 '22 at 04:32

3 Answers3

9

All of the major Tomcat components implement org.apache.catalina.Lifecycle which includes the ability to add a org.apache.catalina.LifecycleListener. It sounds like you want the AFTER_START_EVENT of the Host.

You configure the listener in server.xml like this:

<Host ... >
  <Listener className="your.package.KPTomcatListener"/>
  <!-- Other nested elements go here -->
</Host>

The class must be packaged in a JAR and the JAR placed in Tomcat's lib directory.

Mark Thomas
  • 16,339
  • 1
  • 39
  • 60
  • Thanks for input let me try – Karthik Prasad Mar 14 '14 at 05:20
  • Can you please let me know how to hook it? Please let me know by Tomcat components? – Karthik Prasad Mar 14 '14 at 14:50
  • But, how I can delegate event to my application. I do not find a way to use it in my application. I can use it only if there is a mechanism where web application can register for tomcat events. Is there any way for such case? – Karthik Prasad Mar 17 '14 at 07:29
  • The simplest way to expose this is via static flag on your listener that your web application can then check. – Mark Thomas Mar 17 '14 at 08:14
  • Thanks a lot for your suggestion. I implemented using file . My tomcat listener class would create started.txt file and since shutdown can occur for application( an application can be stopped) I sued springs application context events). and also shutdown will remove the file( While starting in application I check if file is existing, if exists check if file was not created before 2minutes to avoid tomcat kill process) – Karthik Prasad Mar 17 '14 at 09:30
5

In case someone wants to do it programmatically (if using embedded Tomcat for example):

Tomcat tomcat = new Tomcat();
...
tomcat.getServer().addLifecycleListener(new KPTomcatListener());
tomcat.start()
Helder Pereira
  • 5,522
  • 2
  • 35
  • 52
0

Following on from Helder's post of embedded Tomcat, you can also handle this in a lambda:

tomcat.getServer().addLifecycleListener((LifecycleEvent e) -> {
  if (e.getType().equals(AFTER_START_EVENT)) {
    // do something
  }
});
ATutorMe
  • 820
  • 8
  • 14