今天在练习javaweb书城项目的时候,操作完数据库后重新部署服务器(redeplory)突然报错 百度后得出如下原因: jdbc驱动程序在项目销毁的时候不会自动注销,当项目再次部署的时候就又会有一个驱动。
- 自6.0.24版以来,Tomcat附带了内存泄漏检测特性,当Webapp的驱动程序中有一个兼容JDBC4.0的驱动程序时,这会导致这种警告消息。/WEB-INF/lib的auto-register时使用ServiceLoaderAPI,但在webapp关机期间这不会自动注销。实际的bug在其他人的代码中(有问题的JDBC驱动程序),而不是在您的代码中。Tomcat在正常工作,并等待JDBC驱动程序供应商解决问题,以便升级驱动程序。另一方面,您不应该在webapp的/ WEB-INF / lib中放置JDBC驱动程序,而只能在服务器的/ lib中放置JDBC驱动程序。 如果你仍然保存在webapp的/ WEB-INF / lib中,那么你应该使用ServletContextListener手动注册和注销它。
- 降级到Tomcat 6.0.23或更低版本,这样你就不会被那些警告所困扰。但它会悄悄地泄漏内存。这些内存泄漏是Tomcat的OutOfMemoryError问题背后的主要原因之一。
- 将JDBC驱动程序移动到Tomcat/lib文件夹,并有一个连接池数据源来管理驱动程序。请注意,Tomcat的内置DBCP在关闭时不会正确注销驱动程序。另请参阅作为WONTFIX关闭的bug DBCP-322。您可以将DBCP替换为另一个更好的DBCP连接池。例如HikariCP,BoneCP,或Tomcat JDBC池。
上面就是报错出现的原因,直接无视或者降低tomcat的版本感觉不太行,貌似治标不治本,或者说是掩耳盗铃,将JDBC的驱动程序放到tomcat的/lib,写代码很难受,所以最终我选择给程序添加监听器来手动注销驱动程序。
解决方案:
- 创建监听器
public class MyContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("webService start");
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("webService stop");
try {
while(DriverManager.getDrivers().hasMoreElements()) {
DriverManager.deregisterDriver(DriverManager.getDrivers().nextElement());
}
System.out.println("jdbc Driver close");
AbandonedConnectionCleanupThread.checkedShutdown();
System.out.println("clean thread success");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
- 在web.xml中声明监听器
- 成功解决
|