环境:
1)spring boot 版本: 2.1.1.RELEASE
2)线上tomcat版本: tomcat 8.5版本
3)mysql : 5.7.19
问题:
tomcat重新部署报错:registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it。
解决:
网上搜了很多,大致思路是写个ServletContextListener监听器,当tomcat关闭时,将已注册数据驱动列表所有元素全部移除。
避免重新启动失败。
监听器代码如下:
@Slf4j
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
log.info(String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
e.printStackTrace();
log.error(String.format("deregistering jdbc driver: %s", driver));
}
}
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
}
}
另外,项目依赖的mysql驱动包,移到了线上tomcat目录下${tomact}/lib。
重新启动,报错警告信息没有了。
博主自己当时踩了一个坑,spring boot2.1 依赖的tomcat版本是9.0,而线上的tomcat版本是8.5。
二者jar包中javax.servlet.ServletContextListener不同。9.0版本接口实现了两个默认方法,而8.5没有实现。
9.0版本:
8.5版本
而我本地开发中只重写了javax.servlet.ServletContextListener#contextDestroyed方法,结果在线上果断报错了java.lang.AbstractMethodError。
报错信息如下:
后面我将tomcat版本降低成线上版本,才知道原因。大家切记啊!