You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ps...@apache.org on 2015/01/18 19:59:59 UTC
svn commit: r1652830 - in /commons/proper/dbcp/trunk/src: changes/
main/java/org/apache/commons/dbcp2/
main/java/org/apache/commons/dbcp2/datasources/
main/resources/org/apache/commons/dbcp2/
test/java/org/apache/commons/dbcp2/ test/java/org/apache/com...
Author: psteitz
Date: Sun Jan 18 18:59:59 2015
New Revision: 1652830
URL: http://svn.apache.org/r1652830
Log:
Made Datasources implement AutoCloseable. JIRA: DBCP-423.
Modified:
commons/proper/dbcp/trunk/src/changes/changes.xml
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolingDataSource.java
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2/LocalStrings.properties
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPStmtPooling.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPoolingDataSource.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestInstanceKeyDataSource.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestKeyedCPDSConnectionFactory.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestSharedPoolDataSource.java
commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/managed/TestTransactionContext.java
Modified: commons/proper/dbcp/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/changes/changes.xml?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/changes/changes.xml (original)
+++ commons/proper/dbcp/trunk/src/changes/changes.xml Sun Jan 18 18:59:59 2015
@@ -60,7 +60,12 @@ The <action> type attribute can be add,u
-->
<body>
- <release version="2.1" date="TBD" description="This is minor release, including bug fixes and enhancements.">
+ <release version="2.1" date="TBD" description=
+ "This is minor release, including bug fixes and enhancements. Note that
+ one of the enhancements (DBCP-423) is to implement AutoCloseable in
+ BasicDataSource, PoolingDataSource and the InstanceKeyDataSource
+ implementations.
+ ">
<action issue="DBCP-420" dev="sebb" type="fix">
InstanceKeyDataSource discards native SQLException when given password does not match
password used to create the connection.
@@ -86,6 +91,9 @@ The <action> type attribute can be add,u
Made expired connection logging configurable in BasicDataSource. Setting
logExpiredConnections to false suppresses expired connection log messages.
</action>
+ <action issue="DBCP-423" dev="psteitz" type="update">
+ Made Datasources implement AutoCloseable.
+ </action>
</release>
<release version="2.0.1" date="24 May 2014" description="This is a bug fix release.">
<action dev="markt" type="fix">
Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java Sun Jan 18 18:59:59 2015
@@ -66,7 +66,7 @@ import org.apache.commons.pool2.impl.Gen
* @version $Id$
* @since 2.0
*/
-public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBeanRegistration {
+public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBeanRegistration, AutoCloseable {
private static final Log log = LogFactory.getLog(BasicDataSource.class);
@@ -1861,7 +1861,7 @@ public class BasicDataSource implements
} catch(RuntimeException e) {
throw e;
} catch(Exception e) {
- throw new SQLException("Cannot close connection pool", e);
+ throw new SQLException(Utils.getMessage("pool.close.fail"), e);
}
}
Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolingDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolingDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolingDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolingDataSource.java Sun Jan 18 18:59:59 2015
@@ -43,7 +43,7 @@ import org.apache.commons.pool2.impl.Gen
* @version $Id$
* @since 2.0
*/
-public class PoolingDataSource<C extends Connection> implements DataSource {
+public class PoolingDataSource<C extends Connection> implements DataSource, AutoCloseable {
private static final Log log = LogFactory.getLog(PoolingDataSource.class);
@@ -70,6 +70,21 @@ public class PoolingDataSource<C extends
}
}
+ /**
+ * Close and free all {@link Connections}s from the pool.
+ * @since 2.1
+ */
+ @Override
+ public void close() throws Exception {
+ try {
+ _pool.close();
+ } catch(RuntimeException rte) {
+ throw new RuntimeException(Utils.getMessage("pool.close.fail"), rte);
+ } catch(Exception e) {
+ throw new SQLException(Utils.getMessage("pool.close.fail"), e);
+ }
+ }
+
/**
* Returns the value of the accessToUnderlyingConnectionAllowed property.
*
Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java Sun Jan 18 18:59:59 2015
@@ -85,7 +85,7 @@ import org.apache.commons.pool2.impl.Gen
* @since 2.0
*/
public abstract class InstanceKeyDataSource
- implements DataSource, Referenceable, Serializable {
+ implements DataSource, Referenceable, Serializable, AutoCloseable {
private static final long serialVersionUID = -6819270431752240878L;
Modified: commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2/LocalStrings.properties
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2/LocalStrings.properties?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2/LocalStrings.properties (original)
+++ commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2/LocalStrings.properties Sun Jan 18 18:59:59 2015
@@ -21,3 +21,4 @@ swallowedExceptionLogger.onSwallowedExce
poolingDataSource.factoryConfig=PoolableConnectionFactory not linked to pool. Calling setPool() to fix the configuration.
+pool.close.fail=Cannot close connection pool.
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java Sun Jan 18 18:59:59 2015
@@ -428,6 +428,61 @@ public class TestBasicDataSource extends
assertEquals(0, ds.getNumActive());
}
+
+ /**
+ * Verifies correct handling of exceptions generated by the underlying pool as it closes
+ * connections in response to BDS#close. Exceptions have to be either swallowed by the
+ * underlying pool and logged, or propagated and wrapped.
+ */
+ @Test
+ public void testPoolCloseCheckedException() throws Exception {
+ ds.setAccessToUnderlyingConnectionAllowed(true); // Allow dirty tricks
+
+ // Get an idle connection into the pool
+ Connection conn = ds.getConnection();
+ TesterConnection tc = (TesterConnection) ((DelegatingConnection<?>) conn).getInnermostDelegate();
+ conn.close();
+
+ // After returning the connection to the pool, bork it.
+ // Don't try this at home - bad violation of pool contract!
+ tc.setFailure(new SQLException("bang"));
+
+ // Now close Datasource, which will cause tc to be closed, triggering SQLE
+ // Pool 2.x swallows and logs exceptions on pool close. Below verifies that
+ // Either exceptions get logged or wrapped appropriately.
+ try {
+ StackMessageLog.lock();
+ StackMessageLog.clear();
+ ds.close();
+ // Exception must have been swallowed by the pool - verify it is logged
+ assertTrue(StackMessageLog.popMessage().indexOf("bang") > 0);
+ } catch (SQLException ex) {
+ assertTrue(ex.getMessage().indexOf("Cannot close") > 0);
+ assertTrue(ex.getCause().getMessage().indexOf("bang") > 0);
+ } finally {
+ StackMessageLog.unLock();
+ }
+ }
+
+ @Test
+ public void testPoolCloseRTE() throws Exception {
+ // RTE version of testPoolCloseCheckedException - see comments there.
+ ds.setAccessToUnderlyingConnectionAllowed(true);
+ Connection conn = ds.getConnection();
+ TesterConnection tc = (TesterConnection) ((DelegatingConnection<?>) conn).getInnermostDelegate();
+ conn.close();
+ tc.setFailure(new IllegalStateException("boom"));
+ try {
+ StackMessageLog.lock();
+ StackMessageLog.clear();
+ ds.close();
+ assertTrue(StackMessageLog.popMessage().indexOf("boom") > 0);
+ } catch (IllegalStateException ex) {
+ assertTrue(ex.getMessage().indexOf("boom") > 0); // RTE is not wrapped by BDS#close
+ } finally {
+ StackMessageLog.unLock();
+ }
+ }
/**
* Bugzilla Bug 29054:
@@ -613,6 +668,7 @@ public class TestBasicDataSource extends
public void testMaxConnLifetimeExceededMutedLog() throws Exception {
try {
StackMessageLog.lock();
+ StackMessageLog.clear();
ds.setMaxConnLifetimeMillis(100);
ds.setLogExpiredConnections(false);
Connection conn = ds.getConnection();
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPStmtPooling.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPStmtPooling.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPStmtPooling.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPStmtPooling.java Sun Jan 18 18:59:59 2015
@@ -141,7 +141,7 @@ public class TestPStmtPooling {
new GenericObjectPool<>(pcf, config);
pcf.setPool(connPool);
- DataSource ds = new PoolingDataSource<>(connPool);
+ PoolingDataSource<?> ds = new PoolingDataSource<>(connPool);
try (Connection conn = ds.getConnection()) {
Statement stmt1 = conn.prepareStatement("select 1 from dual");
@@ -165,6 +165,7 @@ public class TestPStmtPooling {
assertNotSame(ustmt1, ustmt3);
assertNotSame(ustmt3, ucstmt1);
}
+ ds.close();
}
@Test
@@ -182,7 +183,7 @@ public class TestPStmtPooling {
ObjectPool<PoolableConnection> connPool = new GenericObjectPool<>(pcf);
pcf.setPool(connPool);
- DataSource ds = new PoolingDataSource<>(connPool);
+ PoolingDataSource<?> ds = new PoolingDataSource<>(connPool);
((PoolingDataSource<?>) ds).setAccessToUnderlyingConnectionAllowed(true);
Connection conn = ds.getConnection();
@@ -197,6 +198,7 @@ public class TestPStmtPooling {
} catch (SQLException ex) {
assertTrue(ex.getMessage().endsWith("invalid PoolingConnection."));
}
+ ds.close();
}
@Test
@@ -213,7 +215,7 @@ public class TestPStmtPooling {
ObjectPool<PoolableConnection> connPool = new GenericObjectPool<>(pcf);
pcf.setPool(connPool);
- DataSource ds = new PoolingDataSource<>(connPool);
+ PoolingDataSource<?> ds = new PoolingDataSource<>(connPool);
Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement("select 1 from dual");
@@ -223,5 +225,6 @@ public class TestPStmtPooling {
ps.close();
conn.close();
Assert.assertFalse(inner.isClosed());
+ ds.close();
}
}
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPoolingDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPoolingDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPoolingDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestPoolingDataSource.java Sun Jan 18 18:59:59 2015
@@ -17,7 +17,9 @@
package org.apache.commons.dbcp2;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.sql.Connection;
@@ -67,7 +69,7 @@ public class TestPoolingDataSource exten
@After
public void tearDown() throws Exception {
- pool.close();
+ ds.close();
super.tearDown();
}
@@ -169,4 +171,34 @@ public class TestPoolingDataSource exten
assertTrue(f.getPool().equals(p));
ds.getConnection();
}
+
+ @Test
+ public void testClose() throws Exception {
+
+ Properties props = new Properties();
+ props.setProperty("user", "username");
+ props.setProperty("password", "password");
+ PoolableConnectionFactory f =
+ new PoolableConnectionFactory(
+ new DriverConnectionFactory(new TesterDriver(),
+ "jdbc:apache:commons:testdriver", props),
+ null);
+ f.setValidationQuery("SELECT DUMMY FROM DUAL");
+ f.setDefaultReadOnly(Boolean.TRUE);
+ f.setDefaultAutoCommit(Boolean.TRUE);
+ GenericObjectPool<PoolableConnection> p = new GenericObjectPool<>(f);
+ p.setMaxTotal(getMaxTotal());
+ p.setMaxWaitMillis(getMaxWaitMillis());
+
+ try ( PoolingDataSource<PoolableConnection> dataSource =
+ new PoolingDataSource<PoolableConnection>(p) ) {
+ Connection connection = dataSource.getConnection();
+ assertNotNull(connection);
+ connection.close();
+ }
+
+ assertTrue(p.isClosed());
+ assertEquals(0, p.getNumIdle());
+ assertEquals(0, p.getNumActive());
+ }
}
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java Sun Jan 18 18:59:59 2015
@@ -72,6 +72,7 @@ public class TestCPDSConnectionFactory {
assertEquals(2, ds.getNumIdle("username"));
conn3.close(); // Return to pool will trigger destroy -> close sequence
assertEquals(2, ds.getNumIdle("username"));
+ ds.close();
}
/**
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestInstanceKeyDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestInstanceKeyDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestInstanceKeyDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestInstanceKeyDataSource.java Sun Jan 18 18:59:59 2015
@@ -54,7 +54,8 @@ public class TestInstanceKeyDataSource {
} catch (SQLException ex) {
//Expected
}
- assertEquals(numConnections,tds.getNumActive());
+ assertEquals(numConnections,tds.getNumActive());
+ tds.close();
}
private static class ThrowOnSetupDefaultsDataSource
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestKeyedCPDSConnectionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestKeyedCPDSConnectionFactory.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestKeyedCPDSConnectionFactory.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestKeyedCPDSConnectionFactory.java Sun Jan 18 18:59:59 2015
@@ -73,6 +73,7 @@ public class TestKeyedCPDSConnectionFact
assertEquals(2, ds.getNumIdle());
conn3.close(); // Return to pool will trigger destroy -> close sequence
assertEquals(2, ds.getNumIdle());
+ ds.close();
}
/**
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestSharedPoolDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestSharedPoolDataSource.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestSharedPoolDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestSharedPoolDataSource.java Sun Jan 18 18:59:59 2015
@@ -538,6 +538,7 @@ public class TestSharedPoolDataSource ex
assertTrue(l3HashCode == l4HashCode);
conn.close();
conn = null;
+ tds.close();
}
@Test
Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/managed/TestTransactionContext.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/managed/TestTransactionContext.java?rev=1652830&r1=1652829&r2=1652830&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/managed/TestTransactionContext.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/managed/TestTransactionContext.java Sun Jan 18 18:59:59 2015
@@ -46,6 +46,7 @@ public class TestTransactionContext {
final TransactionContext transactionContext =
new TransactionContext(basicManagedDataSource.getTransactionRegistry(), transaction);
transactionContext.setSharedConnection(conn);
+ basicManagedDataSource.close();
}
/**