title: standalone jdbc-pool implementation memory leak
body: <p>I am trying to implement jdbc-pool in a standalone web app (self contained - not relying on server.xml) so that it can be moved to tomcat installations that may be earlier than 7.0.</p>
  
  <p>I am connecting to MSSQL Server with the sourceforge driver (net.sourceforge.jtds.jdbc.Driver)</p>
  
  <p>Everything runs fine except for this error:</p>
  
  <blockquote>
    <p>SEVERE: The web application [/jdbc-pool] appears to have started a
    thread named [[Pool-Cleaner]:Tomcat Connection Pool[1-12524859]] but
    has failed to stop it. This is very likely to create a memory leak.</p>
  </blockquote>
  
  <p>Based on <a href="http://tomcat.10.n6.nabble.com/Cleaning-up-after-tomcat-jdbc-pool-td2108107.html" rel="nofollow"><strong>this</strong></a> I determined that I need to close the jdbc-pool datasource. I am having trouble with this last line from that post though:</p>
  
  <blockquote>
    <p>>> If it is configured in the application context, then this simply
    means you forgot to call DataSource.close on the connection pool when
    your web application is stopped.</p>
    
    <p>> This is confusing advice because javax.sql.DataSource doesn't have
    a close() method.</p>
    
    <p><strong>In order to call close, one has to cast it to what ever the data
    source you are using.</strong></p>
  </blockquote>
  
  <p>How do I find out what type of datasource I am using and where is the class for it? Can I extract it from the driver jar somehow?</p>
  
  <p>In addition to a servlet which uses the pool, I am using a ServletContextListener so that I can start out with pooled connections immediately from the contextInitialized method. I started adding the code to kill the connection in the contextDestroyed method of this ServletContextListener but got hung up where the question marks are:</p>
  
  <pre><code>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&lt;Driver&gt; 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();
              }
          }
      }
  }
  </code></pre>