X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=test%2Fenterprise%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsupport%2Fpersistence%2FAbstractDatabase.java;h=6eaba50b880f9a218e35ed54a0a3d22aea8168e4;hb=185601ca79008d99e5c2293bc3686fc501720484;hp=80de9d82f2bc07c8c0d167f0863e8f78aa51db73;hpb=8de36ff0206c996baf3ee4adc3e2293b12ff5f39;p=utils diff --git a/test/enterprise/src/main/java/org/wamblee/support/persistence/AbstractDatabase.java b/test/enterprise/src/main/java/org/wamblee/support/persistence/AbstractDatabase.java index 80de9d82..6eaba50b 100644 --- a/test/enterprise/src/main/java/org/wamblee/support/persistence/AbstractDatabase.java +++ b/test/enterprise/src/main/java/org/wamblee/support/persistence/AbstractDatabase.java @@ -1,7 +1,27 @@ +/* + * Copyright 2005-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.wamblee.support.persistence; +import java.util.logging.Level; +import java.util.logging.Logger; + import javax.sql.DataSource; +import junit.framework.Assert; + import org.apache.commons.dbcp.ConnectionFactory; import org.apache.commons.dbcp.DriverManagerConnectionFactory; import org.apache.commons.dbcp.PoolableConnectionFactory; @@ -9,10 +29,22 @@ import org.apache.commons.dbcp.PoolingDataSource; import org.apache.commons.pool.impl.GenericObjectPool; public abstract class AbstractDatabase implements Database { + + /** + * Set this system property to a non-null value to ignore connection leaks + * when {@link #stop()} is called. + */ + private static final String IGNORE_CONNECTION_LEAK_PROPERTY = "org.wamblee.database.ignoreconnectionleaks"; + + private static final Logger LOGGER = Logger + .getLogger(AbstractDatabase.class.getName()); + private static final int CONNECTION_POOL_SIZE = 16; private DataSource itsDataSource; + private GenericObjectPool connectionPool; + private boolean started; protected AbstractDatabase() { @@ -27,7 +59,7 @@ public abstract class AbstractDatabase implements Database { * This method must be called from the start method. */ protected final void createDataSource() { - GenericObjectPool connectionPool = new GenericObjectPool(null); + connectionPool = new GenericObjectPool(null); connectionPool.setMaxActive(CONNECTION_POOL_SIZE); ConnectionFactory connectionFactory = new DriverManagerConnectionFactory( getJdbcUrl(), getUsername(), getPassword()); @@ -36,9 +68,19 @@ public abstract class AbstractDatabase implements Database { // constructed object at the connection pool. PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory( connectionFactory, connectionPool, null, null, false, true); + ingoredVariable(poolableConnectionFactory); itsDataSource = new PoolingDataSource(connectionPool); } + @Override + public int getActiveConnections() { + return connectionPool.getNumActive(); + } + + private static void ingoredVariable(PoolableConnectionFactory aFactory) { + // Empty + } + // / BELOW THIS LINE IS NOT OF INTEREST TO SUBCLASSES. public final DataSource start() { @@ -55,6 +97,22 @@ public abstract class AbstractDatabase implements Database { return; // nothing to do. } started = false; + try { + if (connectionPool.getNumActive() > 0) { + String msg = "JDBC connection pool still has " + + connectionPool.getNumActive() + + " active connection(s), this is a potential resource leak in the code\n"; + // backdoor to ignore connection leaks. Use this system property only if you + // can safely ignore the connection leaks. + if (System.getProperty(IGNORE_CONNECTION_LEAK_PROPERTY) == null) { + Assert.fail(msg); + } + } + connectionPool.close(); + connectionPool.close(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Could not close pool", e); + } doStop(); }