I'm trying to use tomcat jdbc connection pool and I define it in my application context.xml file.
<Context>
<Resource auth="Container" name="jdbc/iup" type="javax.sql.DataSource"
maxActive="300" maxIdle="30" maxWait="20000"
username="${db.username}" password="${db.password}" driverClassName="net.sf.log4jdbc.DriverSpy"
url="jdbc:log4jdbc:sqlserver://${db.server};databaseName=${db.name}"/>
</Context>
Class net.sf.log4jdbc.DriverSpy
is defined in log4jdbc4-1.2.jar
, which is placed in my application lib folder. And it works fine for me. But here it's said, that jar with driver class should be placed ONLY in tomcat lib folder.
Tomcat uses it's BasicDataSource
class to load driver:
if (driverClassName != null) {
try {
try {
if (driverClassLoader == null) {
Class.forName(driverClassName);
} else {
Class.forName(driverClassName, true, driverClassLoader);
}
} catch (ClassNotFoundException cnfe) {
driverFromCCL = Thread.currentThread(
).getContextClassLoader().loadClass(
driverClassName);
}
} catch (Throwable t) {
String message = "Cannot load JDBC driver class '" +
driverClassName + "'";
logWriter.println(message);
t.printStackTrace(logWriter);
throw new SQLNestedException(message, t);
}
}
driverClassLoader
is null, and driver class is trying to be loaded via Class.forName(driverClassName)
. As I understand, in this this case driver class is being loaded with the same classloader instance as BasicDataSource
is. And this is StandardClassLoader
, which will load the class if my jar is in tomcat libs. In my case exception is thrown and Thread.currentThread().getContextClassLoader()
is used, which is WebappClassLoader
instance and can load classes from webapp lib and it does. So I'm confused. Why is it said, that I must put my driver class in tomcat libs if I use datasource from container resource.
Please, explain, thanks