Je reçois ce message lorsque j'exécute mon application Web. Cela fonctionne bien mais je reçois ce message lors de l'arrêt.
GRAVE: Une application Web a enregistré le pilote JBDC [oracle.jdbc.driver.OracleDriver] mais n'a pas réussi à le désinscrire lorsque l'application Web a été arrêtée. Pour éviter une fuite de mémoire, le pilote JDBC a été annulé de force.
Toute aide appréciée.
Réponses:
Depuis la version 6.0.24, Tomcat est livré avec une fonction de détection de fuite de mémoire , qui à son tour peut conduire à ce type de messages d'avertissement lorsqu'il y a un pilote compatible JDBC 4.0 dans la webapp
/WEB-INF/lib
qui s'enregistre automatiquement au démarrage de la webapp à l'aide de l'ServiceLoader
API , mais qui ne s'est pas désenregistré automatiquement lors de l'arrêt de la webapp. Ce message est purement informel, Tomcat a déjà pris les mesures de prévention des fuites de mémoire en conséquence.Que pouvez-vous faire?
Ignorez ces avertissements. Tomcat fait bien son travail. Le bogue réel est dans le code de quelqu'un d'autre (le pilote JDBC en question), pas dans le vôtre. Soyez heureux que Tomcat ait fait son travail correctement et attendez que le fournisseur de pilotes JDBC le corrige pour que vous puissiez mettre à niveau le pilote. D'un autre côté, vous n'êtes pas censé supprimer un pilote JDBC dans les applications Web
/WEB-INF/lib
, mais uniquement dans les serveurs/lib
. Si vous le conservez toujours dans l'application Web/WEB-INF/lib
, vous devez l'enregistrer et le désenregistrer manuellement à l'aide de aServletContextListener
.Rétrogradez vers Tomcat 6.0.23 ou une version antérieure afin de ne pas être dérangé par ces avertissements. Mais il gardera silencieusement la fuite de mémoire. Je ne sais pas si c'est bon à savoir après tout. Ce type de fuites de mémoire est l'une des principales causes des
OutOfMemoryError
problèmes lors des déploiements à chaud Tomcat.Déplacez le pilote JDBC vers le
/lib
dossier Tomcat et disposez d'une source de données regroupée de connexions pour gérer le pilote. Notez que le DBCP intégré de Tomcat ne désenregistre pas correctement les pilotes à la fermeture. Voir aussi le bogue DBCP-322 qui est fermé en tant que WONTFIX. Vous préférez remplacer DBCP par un autre pool de connexions qui fait mieux son travail que DBCP. Par exemple, HikariCP , BoneCP ou peut-être le pool JDBC Tomcat .la source
lib
).Dans la méthode contextDestroyed () de votre écouteur de contexte de servlet, annulez manuellement l'enregistrement des pilotes:
la source
Bien que Tomcat désenregistre de force le pilote JDBC pour vous, il est néanmoins de bonne pratique de nettoyer toutes les ressources créées par votre application Web lors de la destruction du contexte au cas où vous passez à un autre conteneur de servlet qui ne fait pas les vérifications de prévention des fuites de mémoire que fait Tomcat.
Cependant, la méthodologie de désinscription globale des pilotes est dangereuse. Certains pilotes renvoyés par la
DriverManager.getDrivers()
méthode peuvent avoir été chargés par le ClassLoader parent (c'est-à-dire le chargeur de classe du conteneur de servlet) et non par le ClassLoader du contexte de l'application Web (par exemple, ils peuvent se trouver dans le dossier lib du conteneur, pas celui de l'application Web, et donc être partagés sur l'ensemble du conteneur. ). Le retrait de ceux-ci affectera toutes les autres applications Web qui pourraient 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 la webapp avant de le désenregistrer. Ainsi, dans la méthode contextDestroyed () de votre ContextListener:
la source
if (cl.equals(driver.getClass().getClassLoader())) {
?DriverManager
. J'ai laissé un commentaire plus détaillé sur github.com/spring-projects/spring-boot/issues/…Je vois que ce problème revient souvent. Oui, Tomcat 7 le désenregistre automatiquement, mais est-ce que vous prenez VRAIMENT le contrôle de votre code et une bonne pratique de codage? Vous voulez sûrement savoir que vous avez tout le code correct en place pour fermer tous vos objets, fermer les threads du pool de connexion à la base de données et vous débarrasser de tous les avertissements. Je fais certainement.
Voilà comment je le fais.
Étape 1: enregistrer un auditeur
web.xml
Étape 2: implémenter l'écouteur
com.mysite.MySpecialListener.java
N'hésitez pas à commenter et / ou ajouter ...
la source
DataSource
n'a PAS declose
méthodecontextDestroyed
? Pourquoi faites - vous l' étape 1. avant de faire l' étape 2., oùinitContext
,envContext
etdatasource
ne sont pas référencés du tout? Je demande parce que je ne comprends pas l'étape 3.lookup
semble simplement obtenir des objets dont vous n'avez pas besoin. L'étape 3. est complètement inutile. Cela n'ajoute certainement aucune sécurité et ressemble à quelque chose que les débutants feraient qui ne comprennent pas comment fonctionne GC. Je voudrais simplement aller avec stackoverflow.com/a/5315467/897024 et supprimer tous les pilotes.Il s'agit uniquement d'un problème d'enregistrement / de désinscription du pilote dans le pilote mysql ou le chargeur de classe webapp tomcats. Copiez le pilote mysql dans le dossier lib tomcats (afin qu'il soit chargé directement par jvm, pas par tomcat), et le message disparaîtra. Cela fait que le pilote mysql jdbc ne doit être déchargé qu'à l'arrêt de la JVM, et personne ne se soucie alors des fuites de mémoire.
la source
Si vous recevez ce message d'une guerre construite par Maven, changez la portée du pilote JDBC en fourni et mettez-en une copie dans le répertoire lib. Comme ça:
la source
Solution pour les déploiements par application
Voici un écouteur que j'ai écrit pour résoudre le problème: il détecte automatiquement si le pilote s'est enregistré et agit en conséquence.
Important: il est destiné à être utilisé UNIQUEMENT lorsque le fichier pilote est déployé dans WEB-INF / lib , pas dans Tomcat / lib, comme beaucoup le suggèrent, afin que chaque application puisse prendre soin de son propre pilote et s'exécuter sur un Tomcat intact. . C'est ainsi que cela devrait être à mon humble avis.
Configurez simplement l'écouteur dans votre web.xml avant tout autre et profitez-en.
ajoutez en haut de web.xml :
enregistrer sous utils / db / OjdbcDriverRegistrationListener.java :
la source
@WebListener
et omettre laweb.xml
configuration.J'ajouterai à ce quelque chose que j'ai trouvé sur les forums de printemps. Si vous déplacez votre jar de pilote JDBC vers le dossier lib tomcat, au lieu de le déployer avec votre webapp, l'avertissement semble disparaître. Je peux confirmer que cela a fonctionné pour moi
http://forum.springsource.org/showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883
la source
J'ai trouvé que l'implémentation d'une méthode destroy () simple pour désenregistrer les pilotes JDBC fonctionne bien.
la source
Pour éviter cette fuite de mémoire, désenregistrez simplement le pilote à l'arrêt du contexte.
pom.xml
MyWebAppContextListener.java
web.xml
Source qui m'a inspiré pour cette correction de bogue.
la source
J'avais un problème similaire, mais en plus, j'obtenais une erreur Java Heap Space chaque fois que je modifiais / sauvegardais des pages JSP avec le serveur Tomcat en cours d'exécution, donc le contexte n'était pas complètement rechargé.
Mes versions étaient Apache Tomcat 6.0.29 et JDK 6u12.
La mise à niveau de JDK vers 6u21 comme suggéré dans la section Références de l'URL http://wiki.apache.org/tomcat/MemoryLeakProtection a résolu le problème de l'espace de tas Java (le contexte se recharge maintenant OK) bien que l'erreur du pilote JDBC s'affiche toujours.
la source
J'ai trouvé le même problème avec Tomcat version 6.026.
J'ai utilisé le Mysql JDBC.jar dans la bibliothèque WebAPP ainsi que dans TOMCAT Lib.
Pour corriger ce qui précède en supprimant le Jar du dossier lib TOMCAT.
Donc, ce que je comprends, c'est que TOMCAT gère correctement la fuite de mémoire JDBC. Mais si le jar MYSQL Jdbc est dupliqué dans WebApp et Tomcat Lib, Tomcat ne pourra gérer que le jar présent dans le dossier Tomcat Lib.
la source
J'ai rencontré ce problème lorsque je déployais mon application Grails sur AWS. Il s'agit du pilote par défaut JDBC org.h2 driver. Comme vous pouvez le voir dans le Datasource.groovy à l'intérieur de votre dossier de configuration. Comme vous pouvez le voir ci-dessous:
Commentez ces lignes partout où il est mentionné org.h2.Driver dans le fichier , si vous n'utilisez pas cette base de données. Sinon, vous devez télécharger ce fichier jar de base de données.
Merci .
la source
Cette erreur m'est arrivée dans une application Grails avec le pilote JTDS 1.3.0 (SQL Server). Le problème était une connexion incorrecte dans SQL Server. Après avoir résolu ce problème (dans SQL Server), mon application a été correctement déployée dans Tomcat. Astuce: j'ai vu l'erreur dans stacktrace.log
la source