Author: kahatlen Date: Tue Jun 10 06:09:02 2008 New Revision: 666094 URL: http://svn.apache.org/viewvc?rev=666094&view=rev Log: DERBY-3307: NPE in PooledConnction event notification handling if a null listener is added Merged fix from trunk (revision 666040). Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/ClientPooledConnection.java db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/J2EEDataSourceTest.java Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/ClientPooledConnection.java URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/ClientPooledConnection.java?rev=666094&r1=666093&r2=666094&view=diff ============================================================================== --- db/derby/code/branches/10.4/java/client/org/apache/derby/client/ClientPooledConnection.java (original) +++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/ClientPooledConnection.java Tue Jun 10 06:09:02 2008 @@ -311,6 +311,13 @@ if (logWriter_ != null) { logWriter_.traceEntry(this, "addConnectionEventListener", listener); } + + if (listener == null) { + // Ignore the listener if it is null. Otherwise, an exception is + // thrown when a connection event occurs (DERBY-3307). + return; + } + if (eventIterators > 0) { // DERBY-3401: Someone is iterating over the ArrayList, and since // we were able to synchronize on this, that someone is us. Clone Modified: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/J2EEDataSourceTest.java URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/J2EEDataSourceTest.java?rev=666094&r1=666093&r2=666094&view=diff ============================================================================== --- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/J2EEDataSourceTest.java (original) +++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/J2EEDataSourceTest.java Tue Jun 10 06:09:02 2008 @@ -137,6 +137,8 @@ suite.addTest(new J2EEDataSourceTest("testBadConnectionAttributeSyntax")); suite.addTest(new J2EEDataSourceTest("testDescriptionProperty")); suite.addTest(new J2EEDataSourceTest("testConnectionErrorEvent")); + suite.addTest(new J2EEDataSourceTest( + "testConnectionEventListenerIsNull")); suite.addTest(new J2EEDataSourceTest("testReadOnlyToWritableTran")); suite.addTest(new J2EEDataSourceTest("testAutoCommitOnXAResourceStart")); suite.addTest(new J2EEDataSourceTest("testAllDataSources")); @@ -607,7 +609,64 @@ conn = getConnection(); conn.close(); } - + + /** + * Test that event notification doesn't fail when a null listener has + * been registered (DERBY-3307). + */ + public void testConnectionEventListenerIsNull() throws SQLException { + ConnectionPoolDataSource cpds = + J2EEDataSource.getConnectionPoolDataSource(); + subtestCloseEventWithNullListener(cpds.getPooledConnection()); + subtestErrorEventWithNullListener(cpds.getPooledConnection()); + + XADataSource xads = J2EEDataSource.getXADataSource(); + subtestCloseEventWithNullListener(xads.getXAConnection()); + subtestErrorEventWithNullListener(xads.getXAConnection()); + } + + /** + * Test that notification of a close event doesn't fail when the + * listener is null. + */ + private void subtestCloseEventWithNullListener(PooledConnection pc) + throws SQLException + { + pc.addConnectionEventListener(null); + // Trigger a close event + pc.getConnection().close(); + pc.close(); + } + + /** + * Test that notification of an error event doesn't fail when the + * listener is null. + */ + private void subtestErrorEventWithNullListener(PooledConnection pc) + throws SQLException + { + pc.addConnectionEventListener(null); + Connection c = pc.getConnection(); + // Shut down the database to invalidate all connections + getTestConfiguration().shutdownDatabase(); + try { + // Should trigger an error event since the connection is no + // longer valid + c.prepareStatement("VALUES 1"); + fail("Statement should fail after database shutdown"); + } catch (SQLException e) { + if (usingEmbedded()) { + // No current connection is expected on embedded + assertSQLState("08003", e); + } else { + // The client driver reports communication error + assertSQLState("08006", e); + } + } + c.close(); + pc.close(); + } + /** * Test that a PooledConnection can be reused and closed * (separately) during the close event raised by the