Saya mendapatkan pesan ini ketika saya menjalankan aplikasi web saya. Ini berjalan dengan baik tetapi saya mendapatkan pesan ini selama shutdown
SEVERE: Aplikasi web mendaftarkan driver JBDC [oracle.jdbc.driver.OracleDriver] tetapi gagal membatalkan registrasi ketika aplikasi web dihentikan. Untuk mencegah kebocoran memori, Driver JDBC telah secara paksa tidak terdaftar.
Setiap bantuan dihargai.
Jawaban:
Sejak versi 6.0.24, Tomcat hadir dengan fitur pendeteksi kebocoran memori , yang pada gilirannya dapat menyebabkan pesan peringatan semacam ini ketika ada driver yang kompatibel dengan JDBC 4.0 di webapp
/WEB-INF/lib
yang secara otomatis mendaftar sendiri saat startup webapp menggunakanServiceLoader
API , tetapi tidak otomatis mendaftar sendiri selama penutupan webapp. Pesan ini murni informal, Tomcat telah mengambil tindakan pencegahan kebocoran memori yang sesuai.Apa yang bisa kau lakukan?
Abaikan peringatan itu. Tomcat melakukan tugasnya dengan benar. Bug yang sebenarnya ada dalam kode orang lain (driver JDBC yang dimaksud), bukan milik Anda. Senang bahwa Tomcat melakukan tugasnya dengan benar dan tunggu sampai vendor driver JDBC memperbaikinya sehingga Anda dapat memutakhirkan driver. Di sisi lain, Anda tidak seharusnya menjatuhkan driver JDBC di webapp
/WEB-INF/lib
, tetapi hanya di server/lib
. Jika Anda masih menyimpannya di webapp/WEB-INF/lib
, maka Anda harus mendaftar dan membatalkan pendaftaran secara manual menggunakan aServletContextListener
.Turunkan versi ke Tomcat 6.0.23 atau lebih lama sehingga Anda tidak akan terganggu dengan peringatan itu. Tapi itu akan secara diam-diam membocorkan ingatan. Tidak yakin apakah itu baik untuk diketahui. Kebocoran memori semacam itu adalah salah satu penyebab utama di balik
OutOfMemoryError
masalah selama masa kerja hotdot Tomcat.Pindahkan driver JDBC ke
/lib
folder Tomcat dan memiliki koneksi kumpulan data sumber daya untuk mengelola driver. Perhatikan bahwa DBCP bawaan Tomcat tidak membatalkan registrasi driver dengan benar saat tutup. Lihat juga bug DBCP-322 yang ditutup sebagai WONTFIX. Anda lebih suka mengganti DBCP dengan kumpulan koneksi lain yang melakukan tugasnya lebih baik daripada DBCP. Misalnya HikariCP , BoneCP , atau mungkin Tomcat JDBC Pool .sumber
lib
).Dalam metode konteks konteks pendengar servlet Anda (), deregister driver secara manual:
sumber
Meskipun Tomcat secara paksa membatalkan pendaftaran driver JDBC untuk Anda, tetap merupakan praktik yang baik untuk membersihkan semua sumber daya yang dibuat oleh aplikasi web Anda pada penghancuran konteks jika Anda pindah ke wadah servlet lain yang tidak melakukan pemeriksaan pencegahan kebocoran memori yang dilakukan Tomcat.
Namun, metodologi deregistrasi blanket driver berbahaya. Beberapa driver yang dikembalikan oleh
DriverManager.getDrivers()
metode ini mungkin telah dimuat oleh induk ClassLoader (mis., Classloader servlet container) bukan ClassLoader konteks webapp (misalnya, mereka mungkin ada di folder lib kontainer, bukan webapp, dan karenanya dibagikan di seluruh wadah ). Membatalkan pendaftaran ini akan memengaruhi webapp lainnya yang mungkin menggunakannya (atau bahkan wadah itu sendiri).Oleh karena itu, orang harus memeriksa apakah ClassLoader untuk setiap driver adalah ClassLoader webapp sebelum membatalkan pendaftaran. Jadi, dalam metode ContextListener contextDestroyed () Anda:
sumber
if (cl.equals(driver.getClass().getClassLoader())) {
?DriverManager
. Saya meninggalkan komentar yang lebih terperinci di github.com/spring-projects/spring-boot/issues/…Saya melihat masalah ini banyak muncul. Ya, Tomcat 7 tidak secara otomatis membatalkan pendaftaran, tetapi apakah BENAR-BENAR mengendalikan kode Anda dan praktik pengkodean yang baik? Tentunya ANDA ingin tahu bahwa Anda memiliki semua kode yang benar untuk menutup semua objek Anda, mematikan utas koneksi database, dan menyingkirkan semua peringatan. Tentu saja saya lakukan.
Beginilah cara saya melakukannya.
Langkah 1: Daftarkan Pendengar
web.xml
Langkah 2: Terapkan Pendengar
com.mysite.MySpecialListener.java
Silakan berkomentar dan / atau tambahkan ...
sumber
DataSource
TIDAK memilikiclose
metodecontextDestroyed
? Mengapa Anda melakukan langkah 1. sebelum melakukan langkah 2., di manainitContext
,envContext
dandatasource
tidak dirujuk sama sekali? Saya bertanya karena saya tidak mengerti langkah 3.lookup
tampaknya hanya mendapatkan beberapa objek yang tidak Anda butuhkan. Langkah 3. sama sekali tidak berguna. Ini tentu saja tidak menambah keamanan dan sepertinya sesuatu yang pemula akan lakukan yang tidak mengerti cara kerja GC. Saya hanya akan pergi dengan stackoverflow.com/a/5315467/897024 dan menghapus semua driver.Ini murni masalah registrasi / larangan registrasi di mysql`s driver atau tomcats webapp-classloader. Salin driver mysql ke folder lib tomcats (jadi itu dimuat oleh jvm secara langsung, bukan oleh tomcat), dan pesan akan hilang. Itu membuat driver jdbc mysql diturunkan hanya pada saat shutdown JVM, dan tidak ada yang peduli dengan kebocoran memori saat itu.
sumber
Jika Anda mendapatkan pesan ini dari perang bawaan Maven, ubah cakupan driver JDBC yang disediakan, dan letakkan salinannya di direktori lib. Seperti ini:
sumber
Solusi untuk penerapan per-aplikasi
Ini adalah pendengar yang saya tulis untuk memecahkan masalah: ia mendeteksi secara otomatis jika driver telah mendaftarkan dirinya dan bertindak sesuai dengannya.
Penting: ini dimaksudkan untuk HANYA digunakan ketika toples driver digunakan di WEB-INF / lib , bukan di Tomcat / lib, seperti yang disarankan banyak orang, sehingga setiap aplikasi dapat merawat drivernya sendiri dan menjalankan Tomcat yang tidak tersentuh. . Begitulah seharusnya IMHO.
Konfigurasikan pendengar di web.xml Anda sebelum yang lain dan selamat menikmati.
tambahkan di dekat bagian atas web.xml :
simpan sebagai utils / db / OjdbcDriverRegistrationListener.java :
sumber
@WebListener
dan menghilangkanweb.xml
konfigurasi.Saya akan menambahkan ini sesuatu yang saya temukan di forum Spring. Jika Anda memindahkan toples driver JDBC Anda ke folder tomcat lib, alih-alih menggunakan dengan aplikasi web Anda, peringatan itu tampaknya hilang. Saya dapat mengkonfirmasi bahwa ini berhasil untuk saya
http://forum.springsource.org/showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883
sumber
Saya menemukan bahwa menerapkan metode destroy () sederhana untuk membatalkan registrasi driver JDBC bekerja dengan baik.
sumber
Untuk mencegah kebocoran memori ini, cukup deregister driver pada saat shutdown konteks.
pom.xml
MyWebAppContextListener.java
web.xml
Sumber yang menginspirasi saya untuk perbaikan bug ini.
sumber
Saya mengalami masalah yang sama, tetapi juga saya mendapatkan kesalahan Java Heap Space setiap kali saya memodifikasi / menyimpan halaman JSP dengan server Tomcat berjalan, oleh karena itu konteksnya tidak sepenuhnya diisi ulang.
Versi saya adalah Apache Tomcat 6.0.29 dan JDK 6u12.
Meningkatkan JDK ke 6u21 seperti yang disarankan di bagian Referensi URL http://wiki.apache.org/tomcat/MemoryLeakProtection memecahkan masalah Java Heap Space (konteks sekarang reload OK) meskipun kesalahan Driver JDBC masih muncul.
sumber
Saya menemukan masalah yang sama dengan Tomcat versi 6.026.
Saya menggunakan JDBC.jar Mysql di Perpustakaan WebAPP serta di TOMCAT Lib.
Untuk memperbaiki di atas dengan menghapus Jar dari folder lib TOMCAT.
Jadi yang saya pahami adalah bahwa TOMCAT menangani kebocoran memori JDBC dengan benar. Tetapi jika toples MYSQL Jdbc digandakan di WebApp dan Tomcat Lib, Tomcat hanya akan dapat menangani toples yang ada di folder Tomcat Lib.
sumber
Saya menghadapi masalah ini ketika saya menggunakan aplikasi Grails di AWS. Ini adalah masalah driver JDBC default driver org.h2 . Seperti yang Anda lihat di Datasource.groovy di dalam folder konfigurasi Anda. Seperti yang Anda lihat di bawah:
Komentari baris-baris itu di mana pun disebutkan org.h2.Driver dalam file , jika Anda tidak menggunakan database itu. Kalau tidak, Anda harus mengunduh file jar basis data itu.
Terima kasih.
sumber
Kesalahan ini terjadi pada saya di Aplikasi Grails dengan JTDS Driver 1.3.0 (SQL Server). Masalahnya adalah login yang salah di SQL Server. Setelah menyelesaikan masalah ini (dalam SQL Server) aplikasi saya dikerahkan dengan benar di Tomcat. Tip: Saya melihat kesalahan di stacktrace.log
sumber