未调用Tomcat ServletContextListener.contextDestroyed

时间:2012-05-02 07:14:49

标签: tomcat servletcontextlistener

我们有多个MemoryLeaks(在catalina.out中找到),同时重新加载上下文。

为了清理这些线程,我创建了一个ServletContextListener的实现。

创建上下文时成功调用contextInitialized()方法,因为我可以看到日志条目。

但是没有调用contextDestroyed()方法,因此不会调用我的清理代码。任何想法为什么会发生这种情况?

我是否应该在需要重新加载上下文时实现另一个接口?

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");
        }
    }
}

2 个答案:

答案 0 :(得分:0)

据我所见,有几个问题:

  1. 在调用contextDestroyed之前,servlet和过滤器会被完全销毁,因此对某些任务来说可能为时已晚。我不知道为什么Tomcat会在调用此方法之前报告潜在的内存泄漏。 : - /
  2. 在调用此方法之前,类加载器似乎已被禁用(对于过滤器和servlet上的destroy方法可能也是如此?)这意味着如果contextDestroyed方法需要任何尚未加载的类,它将失败。 : - (

答案 1 :(得分:0)

我有一些问题,我使用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

这意味着调用了contextDestroyed,但日志已经无法运行...... 我使用org.slf4j.Logger

要解决此问题,请参阅:Logging from servlet context destroyed event

抱歉我的英文不好