I am repeatedly seeing a warning in my server logs stating that the web application registered the JDBC driver but failed to unregister it upon shutdown. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. This happens every time I redeploy my WAR file. I’m using a MySQL connector with a Spring Boot setup. Does anyone know the specific ServletContextListener code or configuration needed to properly deregister drivers and stop the abandoned connection cleanup thread?
3 answers
This occurs because the JDBC driver is loaded by the WebAppClassLoader. When the app stops, the container tries to clear references to prevent a PermGen/Metaspace leak. To solve this permanently, you should implement a ServletContextListener. In the contextDestroyed method, call DriverManager.deregisterDriver() for every driver returned by DriverManager.getDrivers(). Additionally, if you are using MySQL, you must manually stop the AbandonedConnectionCleanupThread using its uncheckedShutdown() method, otherwise, the thread will keep the ClassLoader alive, resulting in the "forcibly unregistered" warning despite your best efforts to clean up the drivers.
Are you currently placing your JDBC driver JAR file inside the WEB-INF/lib folder of your application, or is it located in the global library folder of your Tomcat server instance?
The simplest fix is to move the JDBC driver to the server's lib directory. This ensures the driver is loaded once by the system, avoiding the leak during redeployment.
I agree with Brian. While the listener code is a "clean" programmatic fix, moving the driver to the container level is the industry standard for production environments to maintain stability.
Mark, I’ve tried both, but putting it in the Tomcat /lib folder seems to stop the warning since the server's common class loader handles it instead of the application's loader. However, for my CI/CD pipeline, I prefer keeping dependencies bundled in the WAR. For those who must keep it in the WAR, the listener approach Jennifer mentioned is the only way to ensure the JVM clears the references properly during a hot redeploy without needing a full server restart.