You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2009/02/22 22:41:53 UTC

svn commit: r746827 - in /commons/proper/dbcp/trunk/src: java/org/apache/commons/dbcp/ test/org/apache/commons/dbcp/

Author: markt
Date: Sun Feb 22 21:41:52 2009
New Revision: 746827

URL: http://svn.apache.org/viewvc?rev=746827&view=rev
Log:
DBCP-212. Remove the sync from makeObject() again. Make sure DriverManager is initialised in a single thread. Add a test case for this. Note test case must run before any other tests.

Added:
    commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java   (with props)
Modified:
    commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DriverManagerConnectionFactory.java
    commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java
    commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestAll.java

Modified: commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DriverManagerConnectionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DriverManagerConnectionFactory.java?rev=746827&r1=746826&r2=746827&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DriverManagerConnectionFactory.java (original)
+++ commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/DriverManagerConnectionFactory.java Sun Feb 22 21:41:52 2009
@@ -31,6 +31,16 @@
  */
 public class DriverManagerConnectionFactory implements ConnectionFactory {
 
+    static {
+        // Related to DBCP-212
+        // Driver manager does not sync loading of drivers that use the service
+        // provider interface. This will cause issues is multi-threaded
+        // environments. This hack makes sure the drivers are loaded before
+        // DBCP tries to use them.
+        DriverManager.getDrivers();
+    }
+
+
     /**
      * Constructor for DriverManagerConnectionFactory.
      * @param connectUri a database url of the form 

Modified: commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java?rev=746827&r1=746826&r2=746827&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java (original)
+++ commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java Sun Feb 22 21:41:52 2009
@@ -294,7 +294,7 @@
         _defaultCatalog = defaultCatalog;
     }
 
-    synchronized public Object makeObject() throws Exception {
+    public Object makeObject() throws Exception {
         Connection conn = _connFactory.createConnection();
         if (conn == null) {
             throw new IllegalStateException("Connection factory returned null from createConnection");

Modified: commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestAll.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestAll.java?rev=746827&r1=746826&r2=746827&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestAll.java (original)
+++ commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestAll.java Sun Feb 22 21:41:52 2009
@@ -41,6 +41,9 @@
 
     public static Test suite() {
         TestSuite suite = new TestSuite();
+        // The test *must* execute first since it tests the initialisation
+        // of DriverManager
+        suite.addTest(TestDriverManagerConnectionFactory.suite());
         // o.a.c.dbcp
         suite.addTest(TestAbandonedBasicDataSource.suite());
         suite.addTest(TestAbandonedObjectPool.suite());

Added: commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java?rev=746827&view=auto
==============================================================================
--- commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java (added)
+++ commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java Sun Feb 22 21:41:52 2009
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.dbcp;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.pool.impl.GenericObjectPool;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * This test *must* execute before all other tests to be effective as it tests
+ * the initialisation of DriverManager.
+ * Based on the test case for DBCP-212 written by Marcos Sanz
+ *
+ * @version $Revision$ $Date$
+ */
+public class TestDriverManagerConnectionFactory extends TestCase {
+    
+    public TestDriverManagerConnectionFactory(String testName) {
+        super(testName);
+    }
+
+    public static Test suite() {
+        return new TestSuite(TestDriverManagerConnectionFactory.class);
+    }
+
+    public void testDriverManagerInit() throws Exception {
+        System.setProperty("jdbc.drivers",
+                "org.apache.commons.dbcp.TesterDriver");
+        GenericObjectPool connectionPool = new GenericObjectPool(null, 10,
+                GenericObjectPool.WHEN_EXHAUSTED_BLOCK, -1, 0);
+        final ConnectionFactory connectionFactory =
+            new DriverManagerConnectionFactory(
+                    "jdbc:apache:commons:testdriver",
+                    "foo", "bar");
+        final PoolableConnectionFactory poolableConnectionFactory =
+            new PoolableConnectionFactory(connectionFactory, connectionPool,
+                    null, null, false, true);
+        connectionPool.setFactory(poolableConnectionFactory);
+        PoolingDataSource dataSource =
+            new PoolingDataSource(connectionPool);
+
+        ConnectionThread[] connectionThreads = new ConnectionThread[10];
+        Thread[] threads = new Thread[10];
+        
+        for (int i = 0; i < 10; i++) {
+            connectionThreads[i] = new ConnectionThread(dataSource);
+            threads[i] = new Thread(connectionThreads[i]);
+        }
+        for (int i = 0; i < 10; i++) {
+            threads[i].start();
+        }
+        for (int i = 0; i < 10; i++) {
+            while (threads[i].getState() != Thread.State.TERMINATED) {
+                Thread.sleep(100);
+            }
+            if (!connectionThreads[i].getResult()) {
+                fail("Exception during getConnection");
+            }
+        }
+    }
+    
+    private static class ConnectionThread implements Runnable {
+        private DataSource ds;
+        private volatile boolean result = true;
+        
+        private ConnectionThread(DataSource ds) {
+            this.ds = ds;
+        }
+
+        public void run() {
+            Connection conn = null;
+            try {
+                conn = ds.getConnection();
+            } catch (Exception e) {
+                e.printStackTrace();
+                result = false;
+            } finally {
+                if (conn != null) {
+                    try {
+                        conn.close();
+                    } catch (Exception e) {
+                        e.printStackTrace();                    
+                        result = false;
+                    }
+                }
+            }
+        }
+        
+        public boolean getResult() {
+            return result;
+        }
+    }
+
+}

Propchange: commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestDriverManagerConnectionFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision