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 2014/05/03 01:32:44 UTC

svn commit: r1592119 - in /commons/proper/dbcp/trunk/src: changes/ main/java/org/apache/commons/dbcp2/ main/resources/org/apache/commons/dbcp2/ test/java/org/apache/commons/dbcp2/

Author: psteitz
Date: Fri May  2 23:32:43 2014
New Revision: 1592119

URL: http://svn.apache.org/r1592119
Log:
Added check in PoolingDataSource constructor to make sure connection factory and pool are linked.  JIRA: DBCP-412.

Modified:
    commons/proper/dbcp/trunk/src/changes/changes.xml
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolingDataSource.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/TestPoolingDataSource.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=1592119&r1=1592118&r2=1592119&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/changes/changes.xml (original)
+++ commons/proper/dbcp/trunk/src/changes/changes.xml Fri May  2 23:32:43 2014
@@ -64,6 +64,10 @@ The <action> type attribute can be add,u
       <action dev="markt" type="fix">
         Small performance improvements when returning connections to the pool.
       </action>
+      <action issue="DBCP-412" dev="psteitz" type="update">
+        Added check in PoolingDataSource constructor to ensure that the connection factory
+        and pool are properly linked.
+      </action>
     </release>
     <release version="2.0" date="3 March 2014" description=
 "This release includes new features as well as bug fixes and enhancements.

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=1592119&r1=1592118&r2=1592119&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 Fri May  2 23:32:43 2014
@@ -17,7 +17,6 @@
 package org.apache.commons.dbcp2;
 
 import java.io.PrintWriter;
-
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
@@ -26,7 +25,10 @@ import java.util.logging.Logger;
 
 import javax.sql.DataSource;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.commons.pool2.ObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPool;
 
 /**
  * A simple {@link DataSource} implementation that obtains
@@ -43,6 +45,8 @@ import org.apache.commons.pool2.ObjectPo
  */
 public class PoolingDataSource<C extends Connection> implements DataSource {
 
+    private static final Log log = LogFactory.getLog(PoolingDataSource.class);
+    
     /** Controls access to the underlying connection */
     private boolean accessToUnderlyingConnectionAllowed = false;
 
@@ -51,6 +55,19 @@ public class PoolingDataSource<C extends
             throw new NullPointerException("Pool must not be null.");
         }
         _pool = pool;
+        // Verify that _pool's factory refers back to it.  If not, log a warning and try to fix.
+        if (_pool instanceof GenericObjectPool<?>) {
+            PoolableConnectionFactory pcf = (PoolableConnectionFactory) ((GenericObjectPool<?>) _pool).getFactory();
+            if (pcf == null) {
+                throw new NullPointerException("PoolableConnectionFactory must not be null.");
+            }
+            if (pcf.getPool() != _pool) {
+                log.warn(Utils.getMessage("poolingDataSource.factoryConfig"));
+                @SuppressWarnings("unchecked") // PCF must have a pool of PCs
+                ObjectPool<PoolableConnection> p = (ObjectPool<PoolableConnection>) _pool;
+                pcf.setPool(p);
+            }
+        }
     }
 
     /**

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=1592119&r1=1592118&r2=1592119&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 Fri May  2 23:32:43 2014
@@ -18,3 +18,5 @@ connectionFactory.lifetimeExceeded=The l
 poolableConnectionFactory.validateObject.fail=Failed to validate a poolable connection
 
 swallowedExceptionLogger.onSwallowedException=An internal object pool swallowed an Exception
+
+poolingDataSource.factoryConfig="PoolableConnectionFactory not linked to pool. Calling setPool() to fix the configuration."

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=1592119&r1=1592118&r2=1592119&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 Fri May  2 23:32:43 2014
@@ -135,4 +135,29 @@ public class TestPoolingDataSource exten
         assertTrue(con2.innermostDelegateEquals(inner));
         assertFalse(con.equals(con2));
     }
+    
+    /**
+     * DBCP-412
+     * Verify that omitting factory.setPool(pool) when setting up PDS does not
+     * result in NPE.
+     */
+    public void testFixFactoryConfig() 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());
+        ds = new PoolingDataSource<>(p);
+        assertTrue(f.getPool().equals(p));
+        ds.getConnection();
+    }
 }