Mirko
Mirko

Reputation: 1552

Tomcat ServletContextListener.contextDestroyed not called

We having multiple MemoryLeaks (found in the catalina.out), while reloading the context.

To clean up these threads, I created an implementation of ServletContextListener.

The contextInitialized() method is successfully called when a context is created, because I can see the log entries.

But the contextDestroyed() method is not called so my cleanup code is not invoked. Any ideas why this is happening?

Should I implement another Interface to be noticed when a context needs to be reloaded?

public class MyContextListener implements ServletContextListener {

    private static final Logger log = Logger.getLogger(MyContextListener.class);

    @Override
    public void contextDestroyed(final ServletContextEvent arg0) {
        MyContextListener.log.info("destroying Servlet Context");
        //Do stuff
        MyContextListener.log.info("Servlet Context destroyed");
    }

    @Override
    public void contextInitialized(final ServletContextEvent arg0) {
        try {
            MyContextListener.log.info("Creating Servlet Context");
            //Do stuff
        } finally {
            MyContextListener.log.info("Servlet Context created");
        }
    }
}

Upvotes: 10

Views: 10123

Answers (2)

Mikhail Ionkin
Mikhail Ionkin

Reputation: 627

I had have the some problem, and I "fixed" it by System.out.println.

  @WebListener
  public class App implements ServletContextListener {
      private static final Logger logger = LoggerFactory.getLogger(App.class);
   
      @Override
      public void contextInitialized(ServletContextEvent sce) {
          System.out.println("START");
          logger.info("START");
      }
   
      @Override
      public void contextDestroyed(ServletContextEvent sce) {
          System.out.println("STOP");
          logger.info("STOP");
      }
  }

log.txt:

[%thread] %-5level %logger{0}:%L - %msg%n
[localhost-startStop-1] INFO  App:16 - START

stdout:

Commons Daemon procrun stdout initialized
START
STOP

It's mean that contextDestroyed has been called, but the logger was stopped before. I used org.slf4j.Logger

To manage the logging live cicle (and so to fix the problem), see: Logging from servlet context destroyed event

Upvotes: 2

mjaggard
mjaggard

Reputation: 2477

As far as I can see, there are a couple of issues:

  1. The servlets and filters are destroyed completely before contextDestroyed is called, so it might be too late for some tasks. I have no idea why Tomcat would report a potential memory leak before calling this method though. :-/
  2. The class loader seems to have been disabled before this method is called (potentially also true for the destroy method on filters and servlets?) meaning that if your contextDestroyed method needs any classes that haven't already been loaded, it will fail. :-(

Upvotes: 0

Related Questions