Author: markt
Date: Tue Mar 22 20:45:34 2011
New Revision: 1084346

URL: http://svn.apache.org/viewvc?rev=1084346&view=rev
Log:
Fix DBCP-333. Correctly implement the option to configure the class loader used 
to load the JDBC driver.

Added:
    
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterClassLoader.java
   (with props)
Modified:
    
commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/BasicDataSource.java
    
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestBasicDataSource.java

Modified: 
commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/BasicDataSource.java
URL: 
http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/BasicDataSource.java?rev=1084346&r1=1084345&r2=1084346&view=diff
==============================================================================
--- 
commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/BasicDataSource.java 
(original)
+++ 
commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp/BasicDataSource.java 
Tue Mar 22 20:45:34 2011
@@ -1444,8 +1444,20 @@ public class BasicDataSource implements 
     }
 
     /**
-     * Creates a JDBC connection factory for this datasource.  This method only
-     * exists so subclasses can replace the implementation class.
+     * Creates a JDBC connection factory for this datasource.  The JDBC driver
+     * is loaded using the following algorithm:
+     * <ol>
+     * <li>If {@link #driverClassName} is specified that class is loaded using
+     * the {@link ClassLoader} of this class or, if {@link #driverClassLoader}
+     * is set, {@link #driverClassName} is loaded with the specified
+     * {@link ClassLoader}.</li>
+     * <li>If {@link #driverClassName} is specified and the previous attempt
+     * fails, the class is loaded using the context class loader of the current
+     * thread.</li>
+     * <li>If a driver still isn't loaded one is loaded via the
+     * {@link DriverManager} using the specified {@link #url}.
+     * </ol>
+     * This method exists so subclasses can replace the implementation class.
      */
     protected ConnectionFactory createConnectionFactory() throws SQLException {
         // Load the JDBC driver class
@@ -1454,9 +1466,10 @@ public class BasicDataSource implements 
             try {
                 try {
                     if (driverClassLoader == null) {
-                        Class.forName(driverClassName);
+                        driverFromCCL = Class.forName(driverClassName);
                     } else {
-                        Class.forName(driverClassName, true, 
driverClassLoader);
+                        driverFromCCL = Class.forName(
+                                driverClassName, true, driverClassLoader);
                     }
                 } catch (ClassNotFoundException cnfe) {
                     driverFromCCL = Thread.currentThread(

Modified: 
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestBasicDataSource.java
URL: 
http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestBasicDataSource.java?rev=1084346&r1=1084345&r2=1084346&view=diff
==============================================================================
--- 
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestBasicDataSource.java
 (original)
+++ 
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TestBasicDataSource.java
 Tue Mar 22 20:45:34 2011
@@ -62,6 +62,7 @@ public class TestBasicDataSource extends
         ds.setPassword("password");
         ds.setValidationQuery("SELECT DUMMY FROM DUAL");
         ds.setConnectionInitSqls(Arrays.asList(new String[] { "SELECT 1", 
"SELECT 2"}));
+        ds.setDriverClassLoader(new TesterClassLoader());
     }
 
     protected BasicDataSource createDataSource() throws Exception {
@@ -500,4 +501,16 @@ public class TestBasicDataSource extends
         // Allow one extra thread for JRockit compatibility
         assertTrue(Thread.activeCount() <= threadCount + 1);
     }
+    
+    /**
+     * JIRA DBCP-333: Check that a custom class loader is used.
+     * @throws Exception 
+     */
+    public void testDriverClassLoader() throws Exception {
+        getConnection();
+        ClassLoader cl = ds.getDriverClassLoader();
+        assertNotNull(cl);
+        assertTrue(cl instanceof TesterClassLoader);
+        assertTrue(((TesterClassLoader) cl).didLoad(ds.getDriverClassName()));
+    }
 }

Added: 
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterClassLoader.java
URL: 
http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterClassLoader.java?rev=1084346&view=auto
==============================================================================
--- 
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterClassLoader.java
 (added)
+++ 
commons/proper/dbcp/trunk/src/test/org/apache/commons/dbcp/TesterClassLoader.java
 Tue Mar 22 20:45:34 2011
@@ -0,0 +1,40 @@
+/*
+ * 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.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple class loader that just records the classes it was asked to load.
+ */
+public class TesterClassLoader extends ClassLoader {
+
+    private Set<String> loadedClasses = new HashSet<String>();
+    
+    @Override
+    protected synchronized Class<?> loadClass(String name, boolean resolve)
+            throws ClassNotFoundException {
+        Class<?> clazz =  super.loadClass(name, resolve);
+        loadedClasses.add(name);
+        return clazz;
+    }
+
+    public boolean didLoad(String className) {
+        return loadedClasses.contains(className);
+    }
+}

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


Reply via email to