Author: psteitz
Date: Tue Jul 17 23:46:16 2007
New Revision: 557176
URL: http://svn.apache.org/viewvc?view=rev&rev=557176
Log:
Changed behavior to allow Connection, Statement, PreparedStatement,
CallableStatement and ResultSet to be closed multiple times. The first time
close is called the resource is closed and any subsequent calls have no effect.
This behavior is required as per the JavaDocs for these classes. Also added
tests for closing all types multiple times and updated any tests that
incorrectly assert that a resource can not be closed more then once.
JIRA: DBCP-233
Patch provided by Dain Sundstrom
Fixes DBCP-134, DBCP-3
Modified:
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DelegatingConnection.java
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDataSource.java
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDriver.java
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestConnectionPool.java
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestManual.java
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterResultSet.java
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterStatement.java
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/managed/TestManagedDataSource.java
jakarta/commons/proper/dbcp/trunk/xdocs/changes.xml
Modified:
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DelegatingConnection.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DelegatingConnection.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DelegatingConnection.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DelegatingConnection.java
Tue Jul 17 23:46:16 2007
@@ -208,10 +208,17 @@
* Closes the underlying connection, and close
* any Statements that were not explicitly closed.
*/
- public void close() throws SQLException
- {
- passivate();
- _conn.close();
+ public void close() throws SQLException {
+ // close can be called multiple times, but PoolableConnection
improperly
+ // throws an exception when a connection is closed twice, so before
calling
+ // close we aren't alreayd closed
+ if (!isClosed()) {
+ try {
+ _conn.close();
+ } finally {
+ _closed = true;
+ }
+ }
}
protected void handleException(SQLException e) throws SQLException {
Modified:
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java
Tue Jul 17 23:46:16 2007
@@ -72,9 +72,8 @@
* Return me to my pool.
*/
public void close() throws SQLException {
- if(isClosed()) {
- throw new SQLException("Already closed");
- } else {
+ // calling close twice should have no effect
+ if (!isClosed()) {
try {
_pool.returnObject(_key,this);
} catch(SQLException e) {
Modified:
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDataSource.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDataSource.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDataSource.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDataSource.java
Tue Jul 17 23:46:16 2007
@@ -177,10 +177,11 @@
}
public void close() throws SQLException {
- checkOpen();
- this.delegate.close();
- this.delegate = null;
- super.setDelegate(null);
+ if (delegate != null) {
+ this.delegate.close();
+ this.delegate = null;
+ super.setDelegate(null);
+ }
}
public boolean isClosed() throws SQLException {
Modified:
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDriver.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDriver.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDriver.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolingDriver.java
Tue Jul 17 23:46:16 2007
@@ -263,12 +263,13 @@
throw new SQLException("Connection is closed.");
}
}
-
+
public void close() throws SQLException {
- checkOpen();
- this.delegate.close();
- this.delegate = null;
- super.setDelegate(null);
+ if (delegate != null) {
+ this.delegate.close();
+ this.delegate = null;
+ super.setDelegate(null);
+ }
}
public boolean isClosed() throws SQLException {
Modified:
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java
Tue Jul 17 23:46:16 2007
@@ -113,9 +113,10 @@
* @exception SQLException The database connection couldn't be closed.
*/
public void close() throws SQLException {
- assertOpen();
- isClosed = true;
- pooledConnection.notifyListeners();
+ if (!isClosed) {
+ isClosed = true;
+ pooledConnection.notifyListeners();
+ }
}
/**
Modified:
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestConnectionPool.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestConnectionPool.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestConnectionPool.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestConnectionPool.java
Tue Jul 17 23:46:16 2007
@@ -148,37 +148,92 @@
}
}
- public void testCantCloseConnectionTwice() throws Exception {
- for(int i=0;i<getMaxActive();i++) { // loop to show we *can* close
again once we've borrowed it from the pool again
+ /**
+ * Verify the close method can be called multiple times on a single
connection without
+ * an exception being thrown.
+ */
+ public void testCanCloseConnectionTwice() throws Exception {
+ for (int i = 0; i < getMaxActive(); i++) { // loop to show we *can*
close again once we've borrowed it from the pool again
Connection conn = newConnection();
assertTrue(null != conn);
assertTrue(!conn.isClosed());
conn.close();
assertTrue(conn.isClosed());
- try {
- conn.close();
- fail("Expected SQLException on second attempt to close (" +
conn.getClass().getName() + ")");
- } catch(SQLException e) {
- // expected
- }
+ conn.close();
assertTrue(conn.isClosed());
}
}
- public void testCantCloseStatementTwice() throws Exception {
+ public void testCanCloseStatementTwice() throws Exception {
+ Connection conn = newConnection();
+ assertTrue(null != conn);
+ assertTrue(!conn.isClosed());
+ for(int i=0;i<2;i++) { // loop to show we *can* close again once we've
borrowed it from the pool again
+ Statement stmt = conn.createStatement();
+ assertNotNull(stmt);
+ assertFalse(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ }
+ conn.close();
+ }
+
+ public void testCanClosePreparedStatementTwice() throws Exception {
Connection conn = newConnection();
assertTrue(null != conn);
assertTrue(!conn.isClosed());
for(int i=0;i<2;i++) { // loop to show we *can* close again once we've
borrowed it from the pool again
PreparedStatement stmt = conn.prepareStatement("select * from
dual");
- assertTrue(null != stmt);
+ assertNotNull(stmt);
+ assertFalse(isClosed(stmt));
stmt.close();
- try {
- stmt.close();
- fail("Expected SQLException on second attempt to close (" +
stmt.getClass().getName() + ")");
- } catch(SQLException e) {
- // expected
- }
+ assertTrue(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ }
+ conn.close();
+ }
+
+ public void testCanCloseCallableStatementTwice() throws Exception {
+ Connection conn = newConnection();
+ assertTrue(null != conn);
+ assertTrue(!conn.isClosed());
+ for(int i=0;i<2;i++) { // loop to show we *can* close again once we've
borrowed it from the pool again
+ PreparedStatement stmt = conn.prepareCall("select * from dual");
+ assertNotNull(stmt);
+ assertFalse(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ stmt.close();
+ assertTrue(isClosed(stmt));
+ }
+ conn.close();
+ }
+
+ public void testCanCloseResultSetTwice() throws Exception {
+ Connection conn = newConnection();
+ assertTrue(null != conn);
+ assertTrue(!conn.isClosed());
+ for(int i=0;i<2;i++) { // loop to show we *can* close again once we've
borrowed it from the pool again
+ PreparedStatement stmt = conn.prepareStatement("select * from
dual");
+ assertNotNull(stmt);
+ ResultSet rset = stmt.executeQuery();
+ assertNotNull(rset);
+ assertFalse(isClosed(rset));
+ rset.close();
+ assertTrue(isClosed(rset));
+ rset.close();
+ assertTrue(isClosed(rset));
+ rset.close();
+ assertTrue(isClosed(rset));
}
conn.close();
}
@@ -529,5 +584,31 @@
assertNotNull(conn2);
assertTrue(conn1.hashCode() != conn2.hashCode());
+ }
+
+ protected boolean isClosed(Statement statement) {
+ try {
+ statement.getWarnings();
+ return false;
+ } catch (SQLException e) {
+ // getWarnings throws an exception if the statement is
+ // closed, but could throw an exception for other reasons
+ // in this case it is good enought to assume the statement
+ // is closed
+ return true;
+ }
+ }
+
+ protected boolean isClosed(ResultSet resultSet) {
+ try {
+ resultSet.getWarnings();
+ return false;
+ } catch (SQLException e) {
+ // getWarnings throws an exception if the statement is
+ // closed, but could throw an exception for other reasons
+ // in this case it is good enought to assume the result set
+ // is closed
+ return true;
+ }
}
}
Modified:
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestManual.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestManual.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestManual.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestManual.java
Tue Jul 17 23:46:16 2007
@@ -91,16 +91,20 @@
public void testReportedBug28912() throws Exception {
Connection conn1 = getConnection();
assertNotNull(conn1);
+ assertFalse(conn1.isClosed());
conn1.close();
-
+
Connection conn2 = getConnection();
assertNotNull(conn2);
-
- try {
- conn1.close();
- fail("Expected SQLException");
- }
- catch (SQLException e) { }
+
+ assertTrue(conn1.isClosed());
+ assertFalse(conn2.isClosed());
+
+ // should be able to call close multiple times with no effect
+ conn1.close();
+
+ assertTrue(conn1.isClosed());
+ assertFalse(conn2.isClosed());
}
/** @see http://issues.apache.org/bugzilla/show_bug.cgi?id=12400 */
Modified:
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterResultSet.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterResultSet.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterResultSet.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterResultSet.java
Tue Jul 17 23:46:16 2007
@@ -79,7 +79,9 @@
}
public void close() throws SQLException {
- checkOpen();
+ if (!_open) {
+ return;
+ }
((TesterStatement)_statement)._resultSet = null;
_open = false;
}
Modified:
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterStatement.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterStatement.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterStatement.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterStatement.java
Tue Jul 17 23:46:16 2007
@@ -79,7 +79,11 @@
}
public void close() throws SQLException {
- checkOpen();
+ // calling close twice has no effect
+ if (!_open) {
+ return;
+ }
+
_open = false;
if (_resultSet != null) {
_resultSet.close();
Modified:
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/managed/TestManagedDataSource.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/managed/TestManagedDataSource.java?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
---
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/managed/TestManagedDataSource.java
(original)
+++
jakarta/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/managed/TestManagedDataSource.java
Tue Jul 17 23:46:16 2007
@@ -126,28 +126,6 @@
connectionB.close();
}
- public void testCantCloseConnectionTwice() throws Exception {
- // this test is invalid... the JavaDoc and spec for the close method
specifically
- // state that the close method on an already closed connection is a
no-op
- }
-
-
- /**
- * Verify the close method can be called multiple times on a single
connection without
- * an exception being thrown.
- */
- public void testCanCloseConnectionTwice() throws Exception {
- for (int i = 0; i < getMaxActive(); i++) { // loop to show we *can*
close again once we've borrowed it from the pool again
- Connection conn = newConnection();
- assertTrue(null != conn);
- assertTrue(!conn.isClosed());
- conn.close();
- assertTrue(conn.isClosed());
- conn.close();
- assertTrue(conn.isClosed());
- }
- }
-
public void testManagedConnectionEqualsSameDelegate() throws Exception {
// Get a maximal set of connections from the pool
Connection[] c = new Connection[getMaxActive()];
Modified: jakarta/commons/proper/dbcp/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/xdocs/changes.xml?view=diff&rev=557176&r1=557175&r2=557176
==============================================================================
--- jakarta/commons/proper/dbcp/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/dbcp/trunk/xdocs/changes.xml Tue Jul 17 23:46:16 2007
@@ -60,6 +60,15 @@
methods to create object pool, connection factory and datasource
instance previously embedded in createDataSource.
</action>
+ <action dev="psteitz" type="fix" issue="DBCP-233" due-to="Dain
Sundstrom">
+ Changed behavior to allow Connection, Statement, PreparedStatement,
+ CallableStatement and ResultSet to be closed multiple times. The first
+ time close is called the resource is closed and any subsequent calls
+ have no effect. This behavior is required as per the JavaDocs for these
+ classes. Also added tests for closing all types multiple times and
+ updated any tests that incorrectly assert that a resource can not be
+ closed more then once. Fixes DBCP-134 and DBCP-3.
+ </action>
</release>
<release version="1.2.2" date="2007-04-04"
description="This is a maintenance release containing bug fixes
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]