Bien que Tomcat désenregistre de force le pilote JDBC pour vous, il est néanmoins bon de nettoyer toutes les ressources créées par votre application Web lors de la destruction du contexte au cas où vous passeriez à un autre conteneur de servlet qui ne ferait pas les vérifications de prévention des fuites de mémoire que fait Tomcat.
Cependant, la méthodologie de désenregistrement global du pilote est dangereuse. Certains pilotes retournés par la méthode DriverManager.getDrivers()
ont peut-être été chargés par le Parent ClassLoader (c'est-à-dire, le classloader du conteneur de servlet) et non par le ClassLoader du contexte de l'application Web (par exemple, ils peuvent être dans le dossier lib du conteneur, pas de l'application Web, et donc partagés dans tout le conteneur). Désenregistrer ceux-ci affectera toute autre application Web qui pourrait les utiliser (ou même le conteneur lui-même).
Par conséquent, il convient de vérifier que le ClassLoader de chaque pilote est le ClassLoader de l'application Web avant de le désenregistrer. Donc, dans la méthode contextDestroyed() de votre ContextListener :
public final void contextDestroyed(ServletContextEvent sce) {
// ... Tout d'abord, fermez toutes les tâches de fond qui pourraient utiliser la BD ...
// ... Puis fermez tous les pools de connexions à la BD ...
// Maintenant, désenregistrez les pilotes JDBC dans le ClassLoader de ce contexte :
// Obtenez le ClassLoader de l'application Web
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Parcourir tous les pilotes
Enumeration drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
// Ce pilote a été enregistré par le ClassLoader de l'application Web, donc désenregistrez-le :
try {
log.info("Désenregistrement du pilote JDBC {}", driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
log.error("Erreur lors du désenregistrement du pilote JDBC {}", driver, ex);
}
} else {
// Le pilote n'a pas été enregistré par le ClassLoader de l'application Web et peut être utilisé ailleurs
log.trace("Ne désenregistrez pas le pilote JDBC {} car il n'appartient pas au ClassLoader de cette application Web", driver);
}
}
}
4 votes
Pourrait être un doublon de stackoverflow.com/questions/2604630/…