Я пытаюсь внедрить jdbc-pool в отдельное веб-приложение (автономное - не полагаясь на server.xml), чтобы его можно было перенести в установки Tomcat, которые могут быть более ранними, чем 7.0.
Iподключаюсь к серверу MSSQL с помощью драйвера sourceforge (net.sourceforge.jtds.jdbc.Driver)
Все работает нормально, кроме этой ошибки:
SEVERE: веб-приложение [/jdbc-pool], по-видимому, запустил поток с именем [[Pool-Cleaner]: пул соединений Tomcat [1-12524859]], но не смог его остановить.Это может привести к утечке памяти.
На основе this Я решил, что мне нужно закрыть источник данных jdbc-pool.У меня проблемы с этой последней строкой из этого поста:
>> Если это настроено в контексте приложения, то это просто означает, что вы забыли вызвать DataSource.close для пула соединений, когда вашвеб-приложение остановлено.
> Это запутанный совет, потому что javax.sql.DataSource не имеет метода close ().
Для вызова close необходимоприведите его к какому-либо источнику данных, который вы используете.
Как мне узнать, какой тип источника данных я использую и где класс для него?Могу ли я как-нибудь извлечь его из jar драйвера?
В дополнение к сервлету, использующему пул, я использую ServletContextListener, чтобы я мог сразу начать с подключений из пула из метода contextInitialized.Я начал добавлять код для уничтожения соединения в методе contextDestroyed этого ServletContextListener, но повесился там, где стоят вопросительные знаки:
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();
}
}
}
}