I maintain a JDBC driver that also has an embedded database server mode provided through a native library, which is accessed through JNA. The shutdown process, done as part of unloading the native library itself, runs into problems on Windows due to the order of unloading its dependencies. To avoid access violations or other issues, I need to explicitly shut down the embedded engine before unloading this library.
Due to the nature of its use, it is difficult to determine an appropriate moment to call for a shutdown. The only correct way to do this for a normal Java application is by registering a shutdown hook using
Runtime.getRuntime().addShutdownHook
with a subclass of Thread
that implements the shutdown logic.
This works fine for a normal Java application, but for web applications that include my library as part of the application (in the WEB-INF/lib
of the WAR), this will cause a memory leak on undeploy as the shutdown hook will maintain a strong reference to my shutdown implementation and to the classloader of the web application.
What would be a suitable and appropriate way to address this? Options I'm looking into right now are:
Using
java.sql.DriverAction.deregister()
to do the cleanup.Not suitable as a driver will not be deregistered on a normal application exit.
Using
java.sql.DriverAction.deregister()
to remove the shutdown hook and execute the shutdown logic itself.Use of
DriverAction
is slightly problematic given the driver still supports Java 7, and this class was introduced in JDBC 4.2 (Java 8). This is technically not always the correct use of action (a JDBC driver can also be deregistered while existing connections remain valid and in use), and it is possible that the driver is used (through ajavax.sql.DataSource
) while the JDBCjava.sql.Driver
implementation is not registered.Including a
javax.servlet.ServletContextListener
implementation annotated with@WebListener
with the driver that will remove the shutdown hook and execute the shutdown logic itself.This option has complications if the driver is deployed to the server as a whole instead of to a specific web application (although those complications can be solved).
Is there a shutdown mechanism in Java I have overlooked that could be suitable for my needs?