but failed to unregister it when the web .....

2014/02/14 11:09
阅读数 2.1W

     在Intellij IDEA中运行web项目,抛出了一大顿异常。仔细看了下控制台,发现如下关键信息:

org.apache.catalina.loader.WebappClassLoader.clearReferencesJdbc The web application [*(项目名)] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

不知问题出在哪里,Google了一下,找到了解决办法,如下:

一. 
一个web应用程序注册的JBDC驱动程序[com.mysql.jdbc.Driver],但Web应用程序时停止时未能注销。为了防止内存泄漏,JDBC驱动程序已被强行注册。 
解决办法 : 
在服务器保持运行的状态中,redeploy这个项目, 就出现了异常, 
要stop之后 再redeploy,就可以了【先将tomcat kill掉,等进程完全死了,再重新启动】 
二. 
tomcat 6.0.33启动时,报错 
he web application [/aaa] registered the JDBC driver [com.ibm.db2.jcc.DB2Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 

在网上搜索得知,一般是项目应用到了SSH组合会出这种问题,多半是Hibernate版本问题。 

原因是Hibernate3.2.3已经包含hibernate-annotations-3.2.1.GA.jar,错误在于我重新加入了Annotation.jar等jar文件 ,一般如果用集成开发环境,如Eclipse,MyEclipse等,他会自带有hibernate等框架的jar包,如果我们自己再加入相同的框架(但版本不同)的jar包,就容易引起冲突【这个方法没有试,具体去掉哪些包,不知道。。。】 
三. 
经查发现开发环境的tom为6.0.20,而出错的生产环境为6.0.29(据查6.0.24、6.0.26均会出现此问题)遂重装tomcat6.0.20解决,此问题的tom只要不高过6.0.20都可以,如6.0.18【没有试验】 
四. 
使用Sping org.apache.commons.dbcp.BasicDataSource 配置数据源时警告 
SEVERE: A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 
问题是tomcat的版本问题,tomcat新检测机制导致的这个问题,换版本可以解决问题,但不建议这么做,租用服务器不是你说换就换的。 
其实问题根源是BasicDataSource,BasicDataSource类close()的一个Bug。 
BasicDataSource's method close() doesn't deregister JDBC driver. This causes permgen memory leaks in web server environments, during context reloads. For example, using Tomcat 6.0.26 with Spring, and BasicDataSource declared in Spring context, there is a message printed at web application reload: 
SEVERE: A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 
上面是问题,翻译的不好,自己看英文吧。 
解决方法: 
继承org.apache.commons.dbcp.BasicDataSource 重写close() 
import java.sql.DriverManager; 
import java.sql.SQLException; 

import org.apache.commons.dbcp.BasicDataSource; 

public class FixedBasicDataSource extends BasicDataSource { 

@Override 
public <T> T unwrap(Class<T> iface) throws SQLException { 
  // TODO Auto-generated method stub 
  return null; 


@Override 
public boolean isWrapperFor(Class<?> iface) throws SQLException { 
  // TODO Auto-generated method stub 
  return false; 

@Override  
    public synchronized void close() throws SQLException {  
        DriverManager.deregisterDriver(DriverManager.getDriver(url));  
        super.close();  
    }  



然后用 FixedBasicDataSource 替换spring配置文件中的数据源bean的class【我用的c3p0的数据库连接池的包】

展开阅读全文
打赏
1
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部