- 問題出現背景:
最近重構了一個老的項目,這個項目中間曾經參與維護的人比較多,代碼非常亂,所以對其進行了一次小的重構和升級,將系統環境從JDK1.6+Tomcat6+WindowsServer升級JDK1.8+Tomcat8+Linux,但是重構完成的時候出現了錯誤,Tomcat一直無法啟動。
- 錯誤信息
To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 這個錯誤:
- 參考的資料
參考了stack overflow上邊的問題:
http://stackoverflow.com/questions/3320400/to-prevent-a-memory-leak-the-jdbc-driver-has-been-forcibly-unregistered
http://stackoverflow.com/questions/2604630/tomcat-fails-to-start-because-of-jdbc-driver-loading
從6.0.24版本開始,Tomcat加入了內存泄漏檢測特性,由於原來的Tomcat版本為6.0.24版本之前的版本,沒有出現類似問題,但是升級為Tomcat8之后就出現了這個問題,Tomcat啟動的時候出現了一長串的重復錯誤信息,警告 To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
BalusC的建議:
-
Ignore those warnings. Tomcat is doing its job right. The actual bug is in someone else's code (the JDBC driver in question), not in yours. Be happy that Tomcat did its job properly and wait until the JDBC driver vendor get it fixed so that you can upgrade the driver. On the other hand, you aren't supposed to drop a JDBC driver in webapp's?
/WEB-INF/lib, but only in server's?/lib. If you still keep it in webapp's?/WEB-INF/lib, then you should manually register and deregister it using a?ServletContextListener. -
Downgrade to Tomcat 6.0.23 or older so that you will not be bothered with those warnings. But it will silently keep leaking memory. Not sure if that's good to know after all. Those kind of memory leaks are one of the major causes behind?
OutOfMemoryError?issues?during Tomcat hotdeployments. -
Move the JDBC driver to Tomcat's?
/lib?folder and have a connection pooled datasource to manage the driver. Note that Tomcat's builtin DBCP does not deregister drivers properly on close. See also bug?DBCP-322?which is closed as WONTFIX. You would rather like to replace DBCP by another connection pool which is doing its job better then DBCP. For example?HikariCP,?BoneCP, or perhaps?Tomcat JDBC Pool.
按照BalusC的建議中的第三條對JDBC的Driver和連接池進行了調整,但是問題依然存在。
To prevent a memory leak, the JDBC Driver has been forcibly這個報錯非常具有迷惑性,因為日志輸出的錯誤信息中並沒有提供足夠的解決問題的有價值信息。
Sometimes, especially when using Spring application on Tomcat, the error message is misleading - when there is no relation to any JDBC driver error at all but only a failure of some application BEAN init-method (or @PostConstruct). The error stack trace is hidden and appears only in tomcat/logs/localhost.xxx file. Just be aware of this behavior. It costed me a lot of time.
- 結論和解決方案
結論:Tomcat中運行Spring的項目時候,控制台輸出的錯誤非常具有迷惑性,有時候只是一些bean初始化的時候或者@PostConstruct的時候出現錯誤,但是控制台卻輸出JDBC Driver的錯誤,這些錯誤信息對解決問題沒有幫助,而真正的錯誤信息存在於tomcat/logs/localhost.xxx file文件中。
至此,問題的解決辦法就非常清晰了,只需要去tomcat/logs/localhost.xxx 文件中找到真正的錯誤信息,根據真正的錯誤信息解決完代碼中的問題后,這個問題自然也跟着就解決了。
