Estou recebendo essa mensagem quando executo meu aplicativo da web. Funciona bem, mas recebo esta mensagem durante o desligamento.
GRAVE: Um aplicativo da web registrou o driver JBDC [oracle.jdbc.driver.OracleDriver], mas falhou em cancelar o registro quando o aplicativo da web foi parado. Para evitar um vazamento de memória, o driver JDBC não foi registrado à força.
Qualquer ajuda apreciada.
Respostas:
Desde a versão 6.0.24, o Tomcat é fornecido com um recurso de detecção de vazamento de memória , que por sua vez pode levar a esse tipo de mensagem de aviso quando há um driver compatível com JDBC 4.0 nos aplicativos da web
/WEB-INF/lib
que se registra automaticamente durante a inicialização do aplicativo usando aServiceLoader
API , mas que não se registrou automaticamente durante o desligamento do webapp. Esta mensagem é puramente informal, o Tomcat já executou a ação de prevenção de vazamento de memória em conformidade.O que você pode fazer?
Ignore esses avisos. O Tomcat está fazendo seu trabalho corretamente. O bug real está no código de outra pessoa (o driver JDBC em questão), não no seu. Fique feliz que o Tomcat tenha feito seu trabalho corretamente e aguarde até que o fornecedor do driver JDBC o conserte para que você possa atualizar o driver. Por outro lado, você não deve soltar um driver JDBC nos aplicativos da web
/WEB-INF/lib
, mas apenas nos servidores/lib
. Se você ainda o mantiver em aplicativos da web/WEB-INF/lib
, deverá registrá-lo manualmente e cancelar o registro usando aServletContextListener
.Faça o downgrade para o Tomcat 6.0.23 ou anterior para que você não seja incomodado com esses avisos. Mas silenciosamente manterá vazando memória. Não sei se é bom saber, afinal. Esse tipo de vazamento de memória é uma das principais causas dos
OutOfMemoryError
problemas durante as implantações a quente do Tomcat.Mova o driver JDBC para a
/lib
pasta do Tomcat e tenha uma fonte de dados em conjunto de conexões para gerenciar o driver. Observe que o DBCP interno do Tomcat não cancela o registro dos drivers corretamente ao fechar. Veja também o bug DBCP-322, que está fechado como WONTFIX. Você gostaria de substituir o DBCP por outro conjunto de conexões que esteja fazendo seu trabalho melhor que o DBCP. Por exemplo , HikariCP , BoneCP ou talvez Tomcat JDBC Pool .fonte
lib
).No método contextDestroyed () do ouvinte de contexto do servlet, cancele o registro manual dos drivers:
fonte
Embora o Tomcat cancele o registro forçado do driver JDBC para você, é uma boa prática limpar todos os recursos criados pelo seu webapp na destruição de contexto, caso você mude para outro contêiner de servlet que não faça as verificações de prevenção de vazamento de memória que o Tomcat faz.
No entanto, a metodologia de cancelamento de registro geral do motorista é perigosa. Alguns drivers retornados pelo
DriverManager.getDrivers()
método podem ter sido carregados pelo ClassLoader pai (ou seja, o carregador de classe do contêiner do servlet) e não pelo ClassLoader do contexto do aplicativo da web (por exemplo, eles podem estar na pasta lib do contêiner, não nos aplicativos da web e, portanto, compartilhados em todo o contêiner ) O cancelamento do registro desses afetará quaisquer outros aplicativos da web que possam estar usando-os (ou até o próprio contêiner).Portanto, deve-se verificar se o ClassLoader de cada driver é o ClassLoader do webapp antes de cancelá-lo. Portanto, no método contextDestroyed () do seu ContextListener:
fonte
if (cl.equals(driver.getClass().getClassLoader())) {
?DriverManager
. Deixei um comentário mais detalhado em github.com/spring-projects/spring-boot/issues/…Vejo esse problema surgir muito. Sim, o Tomcat 7 cancela o registro automaticamente, mas é REALMENTE assumindo o controle do seu código e uma boa prática de codificação? Certamente, você deseja saber que possui todo o código correto para fechar todos os seus objetos, desligar os threads do conjunto de conexões com o banco de dados e se livrar de todos os avisos. Eu certamente faço.
É assim que eu faço.
Etapa 1: registrar um ouvinte
web.xml
Etapa 2: implementar o ouvinte
com.mysite.MySpecialListener.java
Por favor, sinta-se livre para comentar e / ou adicionar ...
fonte
DataSource
não tem umclose
métodocontextDestroyed
? Por que você faz passo 1. antes de fazer o passo 2., ondeinitContext
,envContext
edatasource
não são referenciados em tudo? Estou perguntando porque eu não entendo passo 3.lookup
parece que apenas alguns objetos não são necessários. O passo 3. é completamente inútil. Certamente não adiciona nenhuma segurança e parece algo que os iniciantes fariam sem entender como o GC funciona. Gostaria apenas de ir com stackoverflow.com/a/5315467/897024 e remover todos os drivers.Este é um problema puramente de registro / cancelamento de registro no driver do mysql ou no webapp-classloader do mysql. Copie o driver mysql na pasta lib do tomcats (para que seja carregado diretamente pelo jvm, não pelo tomcat) e a mensagem desaparecerá. Isso faz com que o driver mysql jdbc seja descarregado apenas no desligamento da JVM, e ninguém se importa com vazamentos de memória.
fonte
Se você estiver recebendo esta mensagem de uma guerra criada pelo Maven, altere o escopo do driver JDBC para fornecido e coloque uma cópia dela no diretório lib. Como isso:
fonte
Solução para implantações por aplicativo
Este é um ouvinte que escrevi para resolver o problema: ele detecta automaticamente se o driver se registrou e age de acordo.
Importante: ele deve ser usado SOMENTE quando o jar do driver é implantado no WEB-INF / lib , não no Tomcat / lib, como muitos sugerem, para que cada aplicativo possa cuidar de seu próprio driver e executar em um Tomcat intocado . É assim que deve ser o IMHO.
Basta configurar o ouvinte no seu web.xml antes de qualquer outro e aproveitar.
adicione próximo ao topo do web.xml :
salve como utils / db / OjdbcDriverRegistrationListener.java :
fonte
@WebListener
e omitir aweb.xml
configuração.Vou acrescentar a isso algo que encontrei nos fóruns do Spring. Se você mover o jar do driver JDBC para a pasta lib do tomcat, em vez de implementá-lo com o aplicativo da web, o aviso parecerá desaparecer. Posso confirmar que isso funcionou para mim
http://forum.springsource.org/showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883
fonte
Eu descobri que implementar um método simples destroy () para cancelar o registro de qualquer driver JDBC funciona bem.
fonte
Para evitar esse vazamento de memória, simplesmente cancele o registro do driver no encerramento do contexto.
pom.xml
MyWebAppContextListener.java
web.xml
Fonte que me inspirou para esta correção de bug.
fonte
Eu estava tendo um problema semelhante, mas, além disso, estava recebendo um erro do Java Heap Space sempre que modificava / salvava páginas JSP com o servidor Tomcat em execução, portanto, o contexto não era totalmente recarregado.
Minhas versões eram Apache Tomcat 6.0.29 e JDK 6u12.
A atualização do JDK para 6u21, conforme sugerido na seção Referências da URL http://wiki.apache.org/tomcat/MemoryLeakProtection, resolveu o problema do Java Heap Space (o contexto agora recarrega OK), embora o erro do driver JDBC ainda apareça.
fonte
Encontrei o mesmo problema com o Tomcat versão 6.026.
Eu usei o Mysql JDBC.jar na WebAPP Library e no TOMCAT Lib.
Para corrigir o problema acima, removendo o Jar da pasta lib do TOMCAT.
Então, o que eu entendo é que o TOMCAT está lidando com o vazamento de memória JDBC corretamente. Mas se o jar MYSQL Jdbc for duplicado no WebApp e no Tomcat Lib, o Tomcat poderá manipular o jar presente na pasta Lib do Tomcat.
fonte
Eu enfrentei esse problema quando estava implantando meu aplicativo Grails na AWS. Esta é uma questão de driver org.h2 do driver padrão JDBC . Como você pode ver isso no Datasource.groovy dentro da sua pasta de configuração. Como você pode ver abaixo:
Comente essas linhas sempre que houver mencionado org.h2.Driver no arquivo datasource.groovy, se você não estiver usando esse banco de dados. Caso contrário, você deverá baixar o arquivo jar do banco de dados.
Obrigado .
fonte
Este erro ocorreu comigo em um aplicativo Grails com o driver JTDS 1.3.0 (SQL Server). O problema foi um logon incorreto no SQL Server. Depois de resolver esse problema (no SQL Server), meu aplicativo foi implantado corretamente no Tomcat. Dica: eu vi o erro no stacktrace.log
fonte