我正在尝试在一个独立的web应用程序中实现jdbc池(自我包含-不依赖server.xml),这样它就可以移动到可能早于7.0的tomcat安装。
我正在用sourceforge驱动程序(net.sourceforge.jtds.jdbc.Driver)连接到MSSQL
除此错误外,一切都运行良好:
严重: web应用程序/jdbc池似乎已经启动了一个名为[Pool:tomcatConnectionPool1-12524859]的线程,但是没有停止它。这很可能造成内存泄漏。
基于,我确定需要关闭jdbc池数据源。不过,我在那篇文章的最后一行中遇到了麻烦:
If --它是在应用程序上下文中配置的,这意味着当web应用程序停止时,您忘记在连接池上调用DataSource.close。
这是令人困惑的建议,因为javax.sql.DataSource没有close()方法。
为了调用close,必须将其转换为using.的数据源。
如何找出我正在使用的数据源类型,以及它的类在哪里?我能从司机罐子里拿出来吗?
除了使用池的servlet之外,我还使用了一个ServletContextListener,这样我就可以从contextInitialized方法开始使用池连接。我开始添加代码以在此contextDestroyed方法中终止连接,但在问号所在的位置被挂起:
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
public class JdbcPoolListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent myServletContextEvent) {
// initialize jdbc-pool datasource to start out with pooled connections
try {
Context myContext = (Context) new InitialContext().lookup("java:comp/env");
DataSource myDataSource = (DataSource) myContext.lookup("jdbc/db");
myServletContextEvent.getServletContext().setAttribute("JdbcPool", myDataSource);
} catch (NamingException e) {
System.out.println("Error initializing jdbc-pool datasource");
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent myServletContextEvent) {
// failed attempt to close the data source
ServletContext myServletContext = myServletContextEvent.getServletContext();
//DataSource myDataSource = (DataSource) myServletContext.getAttribute("JdbcPool");
DataSource dataSource = (DataSource)((???) myServletContext.getAttribute(contextAttribute)).getConfiguration().getEnvironment().getDataSource();
dataSource.close();
myServletContext.removeAttribute("JdbcPool");
// deregister JDBC driver to prevent Tomcat 7 from complaining about memory leaks
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
System.out.println(String.format("Deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
System.out.println(String.format("Error deregistering driver %s", driver));
e.printStackTrace();
}
}
}
}发布于 2012-01-18 01:24:05
解决了这个问题,我注意到tomcat.jdbc.pool.DataSourceProxy有一个close方法,所以我将数据源转换为一个DataSourceProxy,然后在其上调用close。我现在不再获得日志中的tomcat内存泄漏错误。
解决方案:
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
import org.apache.tomcat.jdbc.pool.DataSourceProxy;
public class JdbcPoolListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent myServletContextEvent) {
// initialize jdbc-pool datasource to start out with pooled connections
try {
Context myContext = (Context) new InitialContext().lookup("java:comp/env");
DataSource myDataSource = (DataSource) myContext.lookup("jdbc/cf");
myServletContextEvent.getServletContext().setAttribute("JdbcPool", myDataSource);
} catch (NamingException e) {
System.out.println("Error initializing jdbc-pool datasource");
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent myServletContextEvent) {
// close datasource from proxy?
ServletContext myServletContext = myServletContextEvent.getServletContext();
DataSourceProxy myDataSource = (DataSourceProxy) myServletContext.getAttribute("JdbcPool");
myDataSource.close();
myServletContext.removeAttribute("JdbcPool");
// deregister JDBC driver to prevent Tomcat 7 from complaining about memory leaks
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
System.out.println(String.format("Deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
System.out.println(String.format("Error deregistering driver %s", driver));
e.printStackTrace();
}
}
}
}https://stackoverflow.com/questions/8903379
复制相似问题