Tomcat 7强制取消注册JDBC驱动程序,为什么?

AAH*_*AAH 17 java tomcat jdbc

我在tomcat 7中遇到问题,这里有一些关于它的信息,

1 - 我有这样的信息:

INFO: Reloading Context with name [/WebApp] has started
Oct 04, 2013 12:20:50 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/WebApp] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

Oct 04, 2013 12:20:50 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/WebApp] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.
Oct 04, 2013 12:20:51 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/WebApp] is completed
Run Code Online (Sandbox Code Playgroud)

2 - 当我重新加载应用程序时,问题解决了大约20个小时然后又回来了.

3 - 我在tomcat上部署了大约10个应用程序,但只有2个得到了这个错误.

4 - 这两个应用程序的乞讨不存在问题,但是大约2周后就出现了问题.

那么我该如何解决这个问题呢?它与我的代码有关吗?

Sot*_*lis 18

当您在Tomcat中停止Web应用程序时,它会尝试关闭它启动的线程并关闭一堆资源,例如JDBC驱动程序.虽然在这种情况下它能够关闭它们,但是自己做它会更安全.

你可以这样做ServletContextListener.我按照以下方式实施了我的

@WebListener // register it as you wish
public class ContainerContextClosedHandler implements ServletContextListener {
    private static final Logger logger = LoggerFactory.getLogger(ContainerContextClosedHandler.class);

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        // nothing to do
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        Enumeration<Driver> drivers = DriverManager.getDrivers();     

        Driver driver = null;

        // clear drivers
        while(drivers.hasMoreElements()) {
            try {
                driver = drivers.nextElement();
                DriverManager.deregisterDriver(driver);

            } catch (SQLException ex) {
                // deregistration failed, might want to do something, log at the very least
            }
        }

        // MySQL driver leaves around a thread. This static method cleans it up.
        try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            // again failure, not much you can do
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

MySQL确实启动了Tomcat无法关闭的线程.对于当前版本(5.1.23+),他们提供了AbandonedConnectionCleanupThread关闭产生的类Thread,如上所示.


Chr*_*ltz 5

如果您在每个webapp WEB-INF/lib目录中都有Connector/J JDBC驱动程序,那么您可能会遇到与所有Web应用程序类似的问题 - 而不仅仅是这个问题.

如果您正在使用Tomcat的JDBC连接池,那么您应该将Connector/J驱动程序放入Tomcat的lib/目录中,并将其从所有Web应用程序中删除.如果要从自己的应用程序中维护自己的连接池,则必须安排JDBC驱动程序使用全局取消注册DriverManager.更好的是,使用Connector/J的非注册驱动程序而不是注册驱动程序,然后您不必担心Tomcat 实际上会保护您的这些类型的泄漏.