Хоча Tomcat примусово скасовує драйвер JDBC для вас, тим не менше є хорошою практикою очищати всі ресурси, створені вашим веб-сервером для знищення контексту, якщо ви переходите до іншого контейнера сервлетів, який не робить перевірки запобігання витоку пам'яті, які робить Tomcat.
Однак методологія зняття з реєстрації водіїв ковдри небезпечна. Деякі драйвери, повернуті DriverManager.getDrivers()
методом, можуть бути завантажені батьківським ClassLoader (тобто, завантажувачем класу контейнера сервлета), а не ClassLoader контексту webapp (наприклад, вони можуть знаходитися в папці lib контейнера, а не в webapp, і тому поділяються по всьому контейнеру ). Скасування їх реєстрації вплине на будь-які інші веб-карти, які можуть використовувати їх (або навіть сам контейнер).
Тому слід перевірити, що ClassLoader для кожного драйвера - це ClassLoader веб-сайту Webapp, перш ніж скасувати його реєстрацію. Отже, у вашому методі ContextListener’s contextDestroyed ():
public final void contextDestroyed(ServletContextEvent sce) {
// ... First close any background tasks which may be using the DB ...
// ... Then close any DB connection pools ...
// Now deregister JDBC drivers in this context's ClassLoader:
// Get the webapp's ClassLoader
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Loop through all drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
// This driver was registered by the webapp's ClassLoader, so deregister it:
try {
log.info("Deregistering JDBC driver {}", driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
log.error("Error deregistering JDBC driver {}", driver, ex);
}
} else {
// driver was not registered by the webapp's ClassLoader and may be in use elsewhere
log.trace("Not deregistering JDBC driver {} as it does not belong to this webapp's ClassLoader", driver);
}
}
}