Tomcat 7强制取消注册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 

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

3 – 我在tomcat上部署了大约10个应用程序,但只有2个应用程序出现此错误。

4 – 这两个应用程序的乞讨不存在问题,但大约2周后出现。

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

当您在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 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 } } } 

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

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

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