分享

registered the JDBC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the

 瑶疏影 2016-08-05


严重: The web application [/testweb] registered the JDBC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

Google Answers

 

Since version 6.0.24, Tomcat ships with a memory leak detection feature, which in turn can lead to this kind of warning messages when there's a JDBC 4.0 compatible driver in the webapp's /WEB-INF/lib which auto-registers itself during webapp's startup using the ServiceLoader API, but which did not auto-deregister itself during webapp's shutdown. This message is purely informal, Tomcat has already taken the memory leak prevention action accordingly.

What can you do?

  1. 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.

  2. 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.

  3. 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. The DBCP project is however currently stalling. I wouldn't expect quick updates. You would rather like to replace DBCP by another connection pool which is doing its job better then DBCP. For example BoneCP or Tomcat JDBC Pool maybe?


I found that implementing a simple destroy() method to de-register any JDBC drivers works nicely.
  1. /** 
  2.  * Destroys the servlet cleanly by unloading JDBC drivers. 
  3.  *  
  4.  * @see javax.servlet.GenericServlet#destroy() 
  5.  */  
  6. public void destroy() {  
  7.     String prefix = getClass().getSimpleName() +" destroy() ";  
  8.     ServletContext ctx = getServletContext();  
  9.     try {  
  10.         Enumeration<Driver> drivers = DriverManager.getDrivers();  
  11.         while(drivers.hasMoreElements()) {  
  12.             DriverManager.deregisterDriver(drivers.nextElement());  
  13.         }  
  14.     } catch(Exception e) {  
  15.         ctx.log(prefix + "Exception caught while deregistering JDBC drivers", e);  
  16.     }  
  17.     ctx.log(prefix + "complete");  
  18. }  

I will add to this something I found on the Spring forums. If you move your JDBC driver jar to the tomcat lib folder, instead of deploying it with your webapp, the warning seems to disappear. I can confirm that this worked for me

http://forum./showthread.php?87335-Failure-to-unregister-the-MySQL-JDBC-Driver&p=334883#post334883


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多