Я поддерживаю драйвер JDBC, который также имеет режим встроенного сервера базы данных, предоставляемый через собственную библиотеку (доступ к которой осуществляется через JNA). Завершение работы, выполняемое как часть выгрузки самой собственной библиотеки, вызывает проблемы в Windows из-за порядка выгрузки ее зависимостей. Чтобы избежать нарушений доступа или других проблем, мне нужно явно выключить встроенный движок, прежде чем эта библиотека будет выгружена.
Учитывая характер его использования, трудно определить подходящий момент для вызова выключения, и единственный правильный способ для обычного приложения Java, который я вижу прямо сейчас, - это зарегистрировать обработчик выключения, используя Runtime.getRuntime().addShutdownHook
с подклассом Thread
, который реализует выключение логика.
Это отлично работает для обычного Java-приложения, но для веб-приложений, которые включают мою библиотеку как часть приложения (в WEB-INF/lib
WAR), это вызовет утечку памяти при отмене развертывания, поскольку ловушка выключения будет поддерживать сильную ссылку на мои завершение работы и загрузчик классов веб-приложения.
Что было бы подходящим и подходящим способом решения этой проблемы? Варианты, которые я сейчас рассматриваю:
Использование
java.sql.DriverAction.deregister()
для очистки.Не подходит, поскольку драйвер не будет снят с регистрации при обычном выходе из приложения.
Использование
java.sql.DriverAction.deregister()
для удаления ловушки выключения и выполнения самой логики выключения.Использование
DriverAction
немного проблематично, поскольку драйвер по-прежнему поддерживает Java 7, и этот класс был представлен в JDBC 4.2 (Java 8). Технически это не всегда является правильным использованием действия (драйвер JDBC также можно отменить регистрацию, пока существующие соединения остаются действительными и используются), и возможно, что драйвер используется (черезjavax.sql.DataSource
), пока реализация JDBCjava.sql.Driver
не зарегистрирована. .Включая реализацию
javax.servlet.ServletContextListener
, помеченную@WebListener
, с драйвером, который удалит ловушку выключения и сам выполнит логику выключения.Этот вариант имеет сложности, если драйвер развертывается на сервере в целом, а не в конкретном веб-приложении (хотя эти сложности можно решить).
Есть ли в Java механизм выключения, который я упустил из виду, который подходит для моих нужд?
@WebListener
в Tomcat для отмены регистрации несколькихjava.sql.Driver
(с использованиемDriverManager.deregisterDriver
) в нескольких контейнерах (я всегда отменяю регистрацию именно того драйвера, который был зарегистрирован данным контейнером, сохраняяClass<? extends java.sql.Driver>
), и мне интересно, нет ли Я что-то упустил. - person Tomasz Linkowski   schedule 14.08.2018<catalina-home>/lib
и определите источник данных в server.xml. Подобные функции существуют и на других серверах приложений. Ручная регистрация / отмена регистрации драйвера не сработает для этих ситуаций (и это не будет работать для не веб-приложений), и я не думаю, что это решит мою проблему, если драйвер доступен глобально, даже если он зарегистрирован для WAR (java.sql.Driver
реализации являются (или должны быть) довольно легкими). - person Mark Rotteveel   schedule 15.08.2018