Author: fhanik
Date: Thu Aug 7 20:15:19 2014
New Revision: 1616584
URL: http://svn.apache.org/r1616584
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=53853
Dynamic class loading of driver, validator and interceptors can be done from
libraries on the context class loader. Behavior is partly backwards compatible,
always try the current loader first, but then attempts the current thread's
context class loader
Added:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
(with props)
Modified:
tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
Modified: tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml?rev=1616584&r1=1616583&r2=1616584&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml Thu Aug 7 20:15:19 2014
@@ -170,6 +170,22 @@
</attribute>
</attributes>
</subsection>
+
+ <subsection name="System Properties">
+ <p>System properties are JVM wide, affect all pools created in the JVM</p>
+ <attributes>
+ <attribute
name="org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader"
required="false">
+ <p>(boolean) Controls classloading of dynamic classes, such as
+ jdbc drivers, interceptors and validators. If set to false, default
value,
+ the pool will first attempt to load using the current loader and if
class loading fails
+ attempt to load using the thread context loader.
+ Set this value to try, if you wish to remain backwards compatible,
+ Apache Tomcat 8.0.8 and earlier, and only attempt the current
loader.
+ If not set then the default value is <code>false</code>.)
+ </p>
+ </attribute>
+ </attributes>
+ </subsection>
<subsection name="Common Attributes">
<p>These attributes are shared between commons-dbcp and tomcat-jdbc-pool, in
some cases default values are different.</p>
Modified:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java?rev=1616584&r1=1616583&r2=1616584&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
Thu Aug 7 20:15:19 2014
@@ -31,6 +31,8 @@ import javax.naming.spi.ObjectFactory;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.ClassLoaderUtil;
+
/**
* Simple way of configuring generic resources by using reflection.
* Example usage:
@@ -57,7 +59,12 @@ public class GenericNamingResourcesFacto
Enumeration<RefAddr> refs = ref.getAll();
String type = ref.getClassName();
- Object o = Class.forName(type).newInstance();
+ Object o =
+ ClassLoaderUtil.loadClass(
+ type,
+ GenericNamingResourcesFactory.class.getClassLoader(),
+ Thread.currentThread().getContextClassLoader())
+ .newInstance();
while (refs.hasMoreElements()) {
RefAddr addr = refs.nextElement();
Added:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java?rev=1616584&view=auto
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
(added)
+++
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
Thu Aug 7 20:15:19 2014
@@ -0,0 +1,61 @@
+/*
+ * 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.tomcat.jdbc.pool;
+
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public class ClassLoaderUtil {
+ private static final Log log = LogFactory.getLog(ClassLoaderUtil.class);
+
+ private static final boolean onlyAttemptFirstLoader =
+
Boolean.getBoolean(System.getProperty("org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader",
"false"));
+
+ public static Class loadClass(String className, ClassLoader...
classLoaders) throws ClassNotFoundException {
+ ClassNotFoundException last = null;
+ StringBuffer errorMsg = null;
+ for (ClassLoader cl : classLoaders) {
+ try {
+ if (cl!=null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Attempting to load class["+className+"]
from "+cl);
+ }
+ return Class.forName(className, true, cl);
+ } else {
+ throw new ClassNotFoundException("Classloader is null");
+ }
+ } catch (ClassNotFoundException x) {
+ last = x;
+ if (errorMsg==null) {
+ errorMsg = new StringBuffer();
+ } else {
+ errorMsg.append(";");
+ }
+ errorMsg.append("ClassLoader:");
+ errorMsg.append(cl.toString());
+ }
+ if (onlyAttemptFirstLoader) {
+ break;
+ }
+ }
+ throw new ClassNotFoundException("Unable to load class:"+className+"
from "+errorMsg, last);
+ }
+
+
+
+}
Propchange:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ClassLoaderUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=1616584&r1=1616583&r2=1616584&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
Thu Aug 7 20:15:19 2014
@@ -767,7 +767,11 @@ public class PoolProperties implements P
try {
@SuppressWarnings("unchecked")
- Class<Validator> validatorClass =
(Class<Validator>)Class.forName(className);
+ Class<Validator> validatorClass =
(Class<Validator>)ClassLoaderUtil.loadClass(
+ className,
+ PoolProperties.class.getClassLoader(),
+ Thread.currentThread().getContextClassLoader()
+ );
validator = validatorClass.newInstance();
} catch (ClassNotFoundException e) {
log.warn("The class "+className+" cannot be found.", e);
@@ -957,12 +961,20 @@ public class PoolProperties implements P
if (log.isDebugEnabled()) {
log.debug("Loading interceptor
class:"+PoolConfiguration.PKG_PREFIX+getClassName());
}
- clazz =
Class.forName(PoolConfiguration.PKG_PREFIX+getClassName(), true,
this.getClass().getClassLoader());
+ clazz = ClassLoaderUtil.loadClass(
+ PoolConfiguration.PKG_PREFIX+getClassName(),
+ this.getClass().getClassLoader(),
+ Thread.currentThread().getContextClassLoader()
+ );
} else {
if (log.isDebugEnabled()) {
log.debug("Loading interceptor class:"+getClassName());
}
- clazz = Class.forName(getClassName(), true,
this.getClass().getClassLoader());
+ clazz = ClassLoaderUtil.loadClass(
+ getClassName(),
+ this.getClass().getClassLoader(),
+ Thread.currentThread().getContextClassLoader()
+ );
}
}
return (Class<? extends JdbcInterceptor>)clazz;
Modified:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java?rev=1616584&r1=1616583&r2=1616584&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
Thu Aug 7 20:15:19 2014
@@ -247,8 +247,12 @@ public class PooledConnection {
//rely on DriverManager
log.warn("Not loading a JDBC driver as driverClassName
property is null.");
} else {
- driver = (java.sql.Driver)
Class.forName(poolProperties.getDriverClassName(),
- true,
PooledConnection.class.getClassLoader()).newInstance();
+ driver = (java.sql.Driver)
+ ClassLoaderUtil.loadClass(
+ poolProperties.getDriverClassName(),
+ PooledConnection.class.getClassLoader(),
+ Thread.currentThread().getContextClassLoader()
+ ).newInstance();
}
}
} catch (java.lang.Exception cn) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]