Я пытаюсь реализовать jdbc-pool в отдельном веб-приложении (самостоятельно - не полагаясь на server.xml), чтобы его можно было переместить в установки tomcat, которые могут быть раньше, чем 7.0.
Я подключаюсь к MSSQL Server с помощью драйвера sourceforge (net.sourceforge.jtds.jdbc.Driver)
Все работает нормально, кроме этой ошибки:
СЕРЬЕЗНЫЙ: веб-приложение [/jdbc-pool], похоже, запустило поток с именем [[Pool-Cleaner]:Tomcat Connection Pool[1-12524859]], но не смогло его остановить. Это очень вероятно, чтобы создать утечку памяти.
На основе этого Я решил, что мне нужно закрыть источник данных jdbc-pool. Однако у меня возникают проблемы с этой последней строкой из этого сообщения:
>> Если он настроен в контексте приложения, это просто означает, что вы забыли вызвать DataSource.close в пуле соединений, когда ваше веб-приложение остановлено.
> Это сбивает с толку совет, потому что javax.sql.DataSource не имеет метода close().
Чтобы вызвать close, нужно привести его к тому источнику данных, который вы используете.
Как узнать, какой тип источника данных я использую и где находится класс для него? Могу ли я как-то извлечь его из банки с драйверами?
В дополнение к сервлету, который использует пул, я использую 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();
}
}
}
}