Otrzymuję ten komunikat po uruchomieniu aplikacji internetowej. Działa dobrze, ale pojawia się ten komunikat podczas zamykania.
SEVERE: Aplikacja internetowa zarejestrowała sterownik JBDC [oracle.jdbc.driver.OracleDriver], ale nie wyrejestrowała go, gdy aplikacja internetowa została zatrzymana. Aby zapobiec wyciekowi pamięci, sterownik JDBC został wymuszony niezarejestrowany.
Każda pomoc doceniona.
Odpowiedzi:
Od wersji 6.0.24 Tomcat jest wyposażony w funkcję wykrywania wycieków pamięci , która z kolei może prowadzić do tego rodzaju komunikatów ostrzegawczych, gdy w aplikacji internetowej znajduje się sterownik zgodny z JDBC 4.0,
/WEB-INF/lib
który automatycznie rejestruje się podczas uruchamiania aplikacji internetowej za pomocąServiceLoader
interfejsu API , ale który nie wyrejestrował się sam podczas zamykania aplikacji internetowej. Ten komunikat jest czysto nieformalny, Tomcat już odpowiednio podjął działanie zapobiegające wyciekowi pamięci.Co możesz zrobić?
Zignoruj te ostrzeżenia. Tomcat dobrze wykonuje swoją pracę. Rzeczywisty błąd znajduje się w czyimś kodzie (sterownik JDBC, o którym mowa), a nie w twoim. Ciesz się, że Tomcat wykonał swoje zadanie poprawnie i poczekaj, aż dostawca sterowników JDBC go naprawi, abyś mógł zaktualizować sterownik. Z drugiej strony nie należy upuszczać sterownika JDBC w aplikacji internetowej
/WEB-INF/lib
, ale tylko w serwerze/lib
. Jeśli nadal przechowujesz go w aplikacji internetowej/WEB-INF/lib
, powinieneś ręcznie zarejestrować go i wyrejestrować za pomocąServletContextListener
.Zmień wersję na Tomcat 6.0.23 lub starszą, aby nie przejmować się tymi ostrzeżeniami. Ale po cichu wycieknie pamięć. Nie jestem pewien, czy to dobrze wiedzieć. Tego rodzaju wycieki pamięci są jedną z głównych przyczyn
OutOfMemoryError
problemów podczas wdrażania Tomcat.Przenieś sterownik JDBC do
/lib
folderu Tomcat i uzyskaj źródło danych w puli połączeń do zarządzania sterownikiem. Zauważ, że wbudowany DBCP Tomcat nie wyrejestrowuje sterowników poprawnie przy zamknięciu. Zobacz także błąd DBCP-322, który jest zamknięty jako WONTFIX. Wolisz zastąpić DBCP inną pulą połączeń, która działa lepiej niż DBCP. Na przykład HikariCP , BoneCP lub może Tomcat JDBC Pool .źródło
lib
).W metodzie kontekstu detektora kontekstu serwletu ręcznie wyrejestruj sterowniki:
źródło
Chociaż Tomcat siłą wyrejestrowuje dla ciebie sterownik JDBC, dobrą praktyką jest czyszczenie wszystkich zasobów utworzonych przez twoją aplikację internetową po zniszczeniu kontekstu, na wypadek, gdybyś przeniósł się do innego kontenera serwletu, który nie wykonuje kontroli zapobiegania wyciekowi pamięci, którą wykonuje Tomcat.
Metodologia wyrejestrowania ogólnego sterownika jest jednak niebezpieczna. Niektóre sterowniki zwracane przez tę
DriverManager.getDrivers()
metodę mogły zostać załadowane przez nadrzędny moduł ClassLoader (tj. Moduł ładujący kontener serwletu), a nie moduł ClassLoader kontekstu aplikacji sieci Web (np. Mogą znajdować się w folderze lib kontenera, a nie w aplikacji WWW, a zatem udostępnione w całym kontenerze ). Wyrejestrowanie ich wpłynie na wszystkie inne aplikacje internetowe, które mogą ich używać (lub nawet sam kontener).Dlatego przed wyrejestrowaniem należy sprawdzić, czy ClassLoader dla każdego sterownika jest ClassLoader aplikacji internetowej. Zatem w metodzie contextDestroyed () obiektu ContextListener:
źródło
if (cl.equals(driver.getClass().getClassLoader())) {
?DriverManager
. Bardziej szczegółowy komentarz zostawiłemWidzę, że często pojawia się ten problem. Tak, Tomcat 7 automatycznie go wyrejestrowuje, ale czy NAPRAWDĘ przejmuje kontrolę nad twoim kodem i dobrą praktyką kodowania? Z pewnością chcesz wiedzieć, że dysponujesz odpowiednim kodem, aby zamknąć wszystkie obiekty, zamknąć wątki puli połączeń z bazą danych i pozbyć się wszystkich ostrzeżeń. Z pewnością tak.
Tak to robię.
Krok 1: Zarejestruj słuchacza
web.xml
Krok 2: Zaimplementuj nasłuchiwanie
com.mysite.MySpecialListener.java
Skomentuj i / lub dodaj ...
źródło
DataSource
NIE maclose
metodycontextDestroyed
? Dlaczego robisz krok 1. Przed robi krok 2., gdzieinitContext
,envContext
idatasource
nie są wymienione w ogóle? Pytam, ponieważ nie rozumiem kroku 3.lookup
wydaje się , że po prostu dostaje kilka przedmiotów, których nie potrzebujesz. Krok 3. jest całkowicie bezużyteczny. Z pewnością nie zapewnia żadnego bezpieczeństwa i wygląda na coś, co zrobiliby początkujący, którzy nie rozumieją, jak działa GC. Po prostu pójdę ze stackoverflow.com/a/5315467/897024 i usunę wszystkie sterowniki.Jest to kwestia wyłącznie rejestracji / wyrejestrowania sterownika w sterowniku mysql lub w programie ładującym webapp-tomcats. Skopiuj sterownik mysql do folderu lib tomcats (więc jest ładowany bezpośrednio przez jvm, a nie przez tomcat), a wiadomość zniknie. To sprawia, że sterownik mysql jdbc jest zwalniany tylko podczas zamykania JVM, a wtedy nikt nie dba o wycieki pamięci.
źródło
Jeśli otrzymujesz ten komunikat od wojny zbudowanej przez Maven, zmień zakres sterownika JDBC na dostarczony i umieść jego kopię w katalogu lib. Lubię to:
źródło
Rozwiązanie dla wdrożeń na aplikację
To jest słuchacz, który napisałem w celu rozwiązania problemu: automatycznie wykrywa, czy sterownik się zarejestrował i działa odpowiednio. To
Ważne: należy go używać TYLKO, gdy słoik sterownika jest wdrożony w WEB-INF / lib , a nie w Tomcat / lib, jak wielu sugeruje, aby każda aplikacja mogła zadbać o własny sterownik i działać na nietkniętym Tomcat . Tak powinno być IMHO.
Wystarczy skonfigurować odbiornik w pliku web.xml przed innymi i cieszyć się.
dodaj u góry strony web.xml :
zapisz jako utils / db / OjdbcDriverRegistrationListener.java :
źródło
@WebListener
i pomijaćweb.xml
konfigurację.Dodam do tego coś, co znalazłem na forach wiosennych. Jeśli przeniesiesz słoik sterownika JDBC do folderu tomcat lib, zamiast instalować go za pomocą aplikacji internetowej, ostrzeżenie wydaje się znikać. Mogę potwierdzić, że to zadziałało dla mnie
http://forum.springsource.org/showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883
źródło
Odkryłem, że wdrożenie prostej metody destroy () w celu wyrejestrowania sterowników JDBC działa dobrze.
źródło
Aby zapobiec wyciekom pamięci, po prostu wyrejestruj sterownik podczas zamykania kontekstu.
pom.xml
MyWebAppContextListener.java
web.xml
Źródło, które zainspirowało mnie do tej poprawki.
źródło
Miałem podobny problem, ale dodatkowo pojawiał się błąd Java Heap Space za każdym razem, gdy modyfikowałem / zapisywałem strony JSP z uruchomionym serwerem Tomcat, dlatego kontekst nie został w pełni naładowany.
Moje wersje to Apache Tomcat 6.0.29 i JDK 6u12.
Uaktualnienie JDK do wersji 6u21 zgodnie z sugestią w sekcji Odnośniki w adresie URL http://wiki.apache.org/tomcat/MemoryLeakProtection rozwiązało problem przestrzeni stosu Java (kontekst ładuje się teraz OK), chociaż błąd sterownika JDBC nadal występuje.
źródło
Znalazłem ten sam problem z Tomcat w wersji 6.026.
Użyłem Mysql JDBC.jar w bibliotece WebAPP, a także w TOMCAT Lib.
Aby naprawić powyższe, usuwając Jar z folderu lib TOMCAT.
Rozumiem więc, że TOMCAT prawidłowo obsługuje wyciek pamięci JDBC. Ale jeśli słoik Jdbc MYSQL zostanie zduplikowany w aplikacjach WebApp i Tomcat Lib, Tomcat będzie w stanie obsłużyć słoik obecny w folderze Tomcat Lib.
źródło
Napotkałem ten problem, kiedy wdrażałem moją aplikację Grails na AWS. Jest to kwestia domyślnego sterownika JDBC sterownik org.h2 . Jak widać na Datasource.groovy w folderze konfiguracji. Jak widać poniżej:
Skomentuj te wiersze, gdziekolwiek jest mowa o org.h2.Driver w pliku , jeśli nie korzystasz z tej bazy danych. W przeciwnym razie musisz pobrać plik jar bazy danych.
Dzięki .
źródło
Ten błąd przytrafił mi się w aplikacji Grails ze sterownikiem JTDS 1.3.0 (SQL Server). Problem polegał na niepoprawnym logowaniu w SQL Server. Po rozwiązaniu tego problemu (w SQL Server) moja aplikacja została poprawnie wdrożona w Tomcat. Wskazówka: Widziałem błąd w pliku stacktrace.log
źródło