You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by bu...@apache.org on 2003/08/20 00:22:15 UTC
DO NOT REPLY [Bug 21182] -
[dbcp] removing a webapp does not force connections closed
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21182>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21182
[dbcp] removing a webapp does not force connections closed
------- Additional Comments From dirk.verbeeck@pandora.be 2003-08-19 22:22 -------
More info from Michael Holly (commons-user 11/08/2003)
------------------------------------------------------------
I had much the same problem. Starting/Stopping webapps did not deal with
cleaning up the pool correctly.
Since I was trying to implement junit and other testing mechanisims I wanted
my build script to stop, build, and
start the the app, then test it. My problem was that the pools were being
treated as a quasi server/webapp resource.
For the current configurations I couldn't find one that would take ownership
of the pool. Then somebody told me
to create a Context listener and use it to clean up the pool when the webapp
shutdown occurs. After several
iterations I go this to work. I have checked it against my db through
several shutdown startup cycles and
it has yet to lose track of a connection.
Here is my Context Listener
/**
* The listener runs when the app is started and shutdown
*
* @author Michael Holly
* created Apr 18, 2003
*/
package net.talisen.tsr;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import org.apache.commons.dbcp.BasicDataSource;
import javax.servlet.*;
import org.apache.log4j.Logger;
import java.util.ResourceBundle;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.*;
import java.util.*;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.PropertyConfigurator;
public final class ContextListener
implements ServletContextListener
{
//get a logger
Logger log = Logger.getLogger(ContextListener.class);
private InitialContext initialContext = null;
private Context namingContext = null;
private ServletContext context = null;
public void contextInitialized (ServletContextEvent servletContextEvent)
{
context = servletContextEvent.getServletContext ();
try
{
System.out.println(" \n\n Intializing Context");
log.info("Initializing logging");
// configure the Log4j system
String file = new String( "/WEB-INF/classes/log4j.properties" );
URL url = context.getResource(file);
PropertyConfigurator.configure( url );
System.out.println("Log4j Properties @ " + url.toString() );
log.info("Cataloging Context Resources");
initialContext = new InitialContext();
namingContext = (Context) initialContext.lookup("java:comp/env");
DataSource ds1 =
(DataSource)namingContext.lookup("jdbc/oracle_myapp");
DataSource ds2 =
(DataSource)namingContext.lookup("jdbc/oracle_company_db");
context.setAttribute("dataSource1", ds1);
context.setAttribute("dataSource2", ds2);
log.info("oracle_myapp connection pool cataloged");
log.info("oracle_company_db connection pool cataloged");
}
catch (NamingException ne)
{
log.error("Couldn't create context attribute: " + ne.getMessage
());
ne.printStackTrace();
}
catch (Exception e)
{
log.error("Couldn't create context attribute: " + e.getMessage ());
e.printStackTrace();
}
}
public void contextDestroyed (ServletContextEvent servletContextEvent)
{
DataSource ds1 = ((DataSource) context.getAttribute("dataSource1"));
DataSource ds2 = ((DataSource) context.getAttribute("dataSource2"));
try
{
log.info("Cleaning up Context Resources");
if (ds1 instanceof org.apache.commons.dbcp.BasicDataSource) {
log.info("Found oracle_tsr connection pool " + ds1.toString());
((org.apache.commons.dbcp.BasicDataSource) ds1).close();
ds1 = null;
}
log.info("Removed oracle_myapp connection ");
if (ds2 instanceof org.apache.commons.dbcp.BasicDataSource) {
log.info("Found oracle_talisen connection pool " +
ds2.toString() );
((org.apache.commons.dbcp.BasicDataSource) ds2).close();
ds2 = null;
}
log.info("Removed oracle_company_db connection");
context.removeAttribute ("dataSource1");
context.removeAttribute ("dataSource2");
}
catch (Exception e)
{
log.error("Error destroying Context: " + e.getMessage ());
e.printStackTrace();
}
finally
{
System.out.println("########################################################
###########################################");
System.out.println("########################################################
###########################################");
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("");
}
}
}
then I add the Contect Listener to the web.xml file
<!-- CONTEXT LISTENER -->
<listener>
<listener-class>net.talisen.tsr.ContextListener</listener-class>
</listener>
My server.xml does not contain any of the config info for the pools. This
is
contained in a context xml file. This file get stuffed into the META-INF
dir.
Then the whole thing gets jared up. I deploy using Tomcat Manager.
<!--Context path="/tsr" docBase="/tsr" debug="9" reloadable="true"
crossContext="true"-->
<!--Context path="/tsr" docBase="tsr.war" debug="9" reloadable="true"
crossContext="true"-->
<Context path="/tsr" debug="9" privileged="true" docBase="C:\Tomcat
4.1\webapps\tsr" useNaming="true">
<Loader checkInterval="6"/>
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="localhost_tsrdb_log."
suffix=".txt"
timestamp="true"/>
<Resource name="jdbc/oracle_tsr" auth="Container" scope="Shareable"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/oracle_myapp">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<!--value>oracle.jdbc.OracleDriver</value-->
<!--value>oracle.jdbc.pool.OracleConnectionPoolDataSource</value-->
<value>oracle.jdbc.pool.OracleDataSource</value>
</parameter>
<parameter>
<name>url</name>
<!--value>jdbc:oracle:thin:@myserver:1521:myco</value-->
</parameter>
<parameter>
<name>username</name>
<value>myapp</value>
</parameter>
<parameter>
<name>password</name>
<value>????????</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>20</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>10</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>-1</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>300</value>
</parameter>
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>validationQuery</name>
<value>select 'validationQuery' from dual</value>
</parameter>
<parameter>
<name>testOnBorrow</name>
<value>true</value>
</parameter>
</ResourceParams>
<Resource name="jdbc/oracle_talisen" auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/oracle_talisen">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.OracleDriver</value>
<!--value>oracle.jdbc.pool.OracleConnectionPoolDataSource</value-->
<!--value>oracle.jdbc.pool.OracleDataSource</value-->
</parameter>
<parameter>
<name>url</name>
<!--value>jdbc:oracle:thin:@myserver:1521:myco</value-->
</parameter>
<parameter>
<name>username</name>
<value>company_db</value>
</parameter>
<parameter>
<name>password</name>
<value>?????????</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>20</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>10</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>-1</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>300</value>
</parameter>
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>validationQuery</name>
<value>select 'validationQuery' from dual</value>
</parameter>
<parameter>
<name>testOnBorrow</name>
<value>true</value>
</parameter>
</ResourceParams>
</Context>
Hope this helps.
Michael