Recibo este mensaje cuando ejecuto mi aplicación web. Funciona bien pero recibo este mensaje durante el apagado.
GRAVE: Una aplicación web registró el controlador JBDC [oracle.jdbc.driver.OracleDriver] pero no pudo cancelar el registro cuando se detuvo la aplicación web. Para evitar una pérdida de memoria, el controlador JDBC no se ha registrado por la fuerza.
Cualquier ayuda apreciada.
Respuestas:
Desde la versión 6.0.24, Tomcat se entrega con una función de detección de pérdida de memoria , que a su vez puede generar este tipo de mensajes de advertencia cuando hay un controlador compatible con JDBC 4.0 en la aplicación web
/WEB-INF/lib
que se registra automáticamente durante el inicio de la aplicación utilizando laServiceLoader
API , pero que no se dio de baja automáticamente durante el cierre de la aplicación web. Este mensaje es puramente informal, Tomcat ya ha tomado la acción de prevención de pérdida de memoria en consecuencia.¿Qué puedes hacer?
Ignora esas advertencias. Tomcat está haciendo bien su trabajo. El error real está en el código de otra persona (el controlador JDBC en cuestión), no en el tuyo. Esté feliz de que Tomcat haya hecho su trabajo correctamente y espere hasta que el proveedor del controlador JDBC lo repare para que pueda actualizar el controlador. Por otro lado, se supone que no debe soltar un controlador JDBC en aplicaciones web
/WEB-INF/lib
, sino solo en servidores/lib
. Si aún lo mantiene en la aplicación web/WEB-INF/lib
, debe registrarlo y cancelar su registro manualmente mediante aServletContextListener
.Cambie a Tomcat 6.0.23 o anterior para que no le molesten esas advertencias. Pero en silencio seguirá perdiendo memoria. No estoy seguro si es bueno saberlo después de todo. Ese tipo de pérdidas de memoria son una de las principales causas de
OutOfMemoryError
problemas durante las implementaciones en caliente de Tomcat.Mueva el controlador JDBC a la
/lib
carpeta de Tomcat y tenga una fuente de datos agrupada de conexión para administrar el controlador. Tenga en cuenta que el DBCP incorporado de Tomcat no anula el registro de los controladores correctamente al cerrar. Vea también el error DBCP-322 que está cerrado como WONTFIX. Prefiere reemplazar DBCP por otro grupo de conexiones que esté haciendo su trabajo mejor que DBCP. Por ejemplo , HikariCP , BoneCP o quizás Tomcat JDBC Pool .fuente
lib
).En su método servlet context listener contextDestroyed (), anule el registro manualmente de los controladores:
fuente
Aunque Tomcat cancela el registro del controlador JDBC por usted, es una buena práctica limpiar todos los recursos creados por su aplicación web en la destrucción del contexto en caso de que se mude a otro contenedor de servlet que no realiza las comprobaciones de prevención de pérdida de memoria que hace Tomcat.
Sin embargo, la metodología de desregistro del controlador general es peligrosa. Algunos controladores devueltos por el
DriverManager.getDrivers()
método pueden haber sido cargados por el ClassLoader principal (es decir, el cargador de clases del contenedor de servlet), no el ClassLoader del contexto de la aplicación web (por ejemplo, pueden estar en la carpeta lib del contenedor, no en la aplicación web, y por lo tanto compartidos en todo el contenedor ) Anular el registro de estos afectará a cualquier otra aplicación web que pueda estar usándolos (o incluso al contenedor en sí).Por lo tanto, uno debe verificar que el ClassLoader para cada controlador es el ClassLoader de la aplicación web antes de cancelar su registro. Entonces, en el método contextDestroyed () de ContextListener:
fuente
if (cl.equals(driver.getClass().getClassLoader())) {
?DriverManager
. Dejé un comentario más detallado en github.com/spring-projects/spring-boot/issues/…Veo que este problema surge mucho. Sí, Tomcat 7 lo anula automáticamente, pero ¿REALMENTE toma el control de su código y es una buena práctica de codificación? Seguramente USTED desea saber que tiene todo el código correcto para cerrar todos sus objetos, cerrar los subprocesos del grupo de conexiones de la base de datos y deshacerse de todas las advertencias. Ciertamente lo hago.
Así es como lo hago.
Paso 1: Registre un oyente
web.xml
Paso 2: Implemente el oyente
com.mysite.MySpecialListener.java
Por favor, siéntase libre de comentar y / o agregar ...
fuente
DataSource
NO tiene unclose
métodocontextDestroyed
? ¿Por qué haces Paso 1. Antes de realizar el paso 2., dondeinitContext
,envContext
ydatasource
no se hace referencia a todos? Lo pregunto porque no entiendo el paso 3.lookup
parece que solo obtiene algunos objetos que no necesita. El paso 3. es completamente inútil. Ciertamente no agrega ninguna seguridad y parece algo que los principiantes harían si no entienden cómo funciona GC. Simplemente iría con stackoverflow.com/a/5315467/897024 y eliminaría todos los controladores.Esto es puramente un problema de registro / desregistro del controlador en el controlador de mysql o tombats webapp-classloader. Copie el controlador mysql en la carpeta lib de tomcats (para que se cargue directamente por jvm, no por tomcat), y el mensaje desaparecerá. Eso hace que el controlador mysql jdbc se descargue solo en el apagado de JVM, y a nadie le importan las pérdidas de memoria en ese momento.
fuente
Si recibe este mensaje de una guerra construida por Maven, cambie el alcance del controlador JDBC que se proporciona y coloque una copia en el directorio lib. Me gusta esto:
fuente
Solución para implementaciones por aplicación
Este es un oyente que escribí para resolver el problema: detecta automáticamente si el controlador se ha registrado y actúa en consecuencia.
Importante: está destinado a usarse SOLO cuando el controlador jar se implementa en WEB-INF / lib , no en Tomcat / lib, como muchos sugieren, para que cada aplicación pueda cuidar su propio controlador y ejecutarse en un Tomcat intacto . Esa es la forma en que debería ser en mi humilde opinión.
Simplemente configure el oyente en su web.xml antes que cualquier otro y disfrute.
agregue cerca de la parte superior de web.xml :
guardar como utils / db / OjdbcDriverRegistrationListener.java :
fuente
@WebListener
y omitir laweb.xml
configuración.Agregaré a esto algo que encontré en los foros de Spring. Si mueve el jar del controlador JDBC a la carpeta lib de tomcat, en lugar de implementarlo con su aplicación web, la advertencia parece desaparecer. Puedo confirmar que esto funcionó para mí
http://forum.springsource.org/showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883
fuente
Descubrí que implementar un método simple destroy () para cancelar el registro de cualquier controlador JDBC funciona bien.
fuente
Para evitar esta pérdida de memoria, simplemente anule el registro del controlador al apagar el contexto.
pom.xml
MyWebAppContextListener.java
web.xml
Fuente que me inspiró para esta corrección de errores.
fuente
Estaba teniendo un problema similar, pero además recibía un error de Java Heap Space cada vez que modificaba / guardaba páginas JSP con el servidor Tomcat ejecutándose, por lo tanto, el contexto no se recargó por completo.
Mis versiones fueron Apache Tomcat 6.0.29 y JDK 6u12.
La actualización de JDK a 6u21 como se sugiere en la sección Referencias de la URL http://wiki.apache.org/tomcat/MemoryLeakProtection resolvió el problema de Java Heap Space (el contexto ahora se recarga correctamente ) aunque el error del controlador JDBC todavía aparece.
fuente
Encontré el mismo problema con Tomcat versión 6.026.
Utilicé Mysql JDBC.jar en la biblioteca de WebAPP, así como en TOMCAT Lib.
Para arreglar lo anterior quitando el Jar de la carpeta lib de TOMCAT.
Entonces, lo que entiendo es que TOMCAT está manejando la pérdida de memoria JDBC correctamente. Pero si el jar MYSQL Jdbc está duplicado en WebApp y Tomcat Lib, Tomcat solo podrá manejar el jar presente en la carpeta Tomcat Lib.
fuente
Me enfrenté a este problema cuando estaba implementando mi aplicación Grails en AWS. Esto es cuestión del controlador predeterminado JDBC org.h2 driver. Como puede ver esto en Datasource.groovy dentro de su carpeta de configuración. Como puede ver abajo :
Comente esas líneas siempre que se mencione org.h2.Driver en el archivo datasource.groovy, si no está utilizando esa base de datos. De lo contrario, debe descargar el archivo jar de la base de datos.
Gracias .
fuente
Este error me ocurrió en una aplicación Grails con el controlador JTDS 1.3.0 (SQL Server). El problema fue un inicio de sesión incorrecto en SQL Server. Después de resolver este problema (en SQL Server), mi aplicación se implementó correctamente en Tomcat. Consejo: vi el error en stacktrace.log
fuente