我正在尝试使用 tomcat jdbc 连接池,并在我的应用程序 context.xml 文件中定义它。
<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>
类net.sf.log4jdbc.DriverSpy
定义在 中log4jdbc4-1.2.jar
,它放在我的应用程序 lib文件夹中。它对我来说很好。但是这里说,带有驱动程序类的 jar 应该只放在 tomcat lib 文件夹中。
Tomcat 使用它的BasicDataSource
类来加载驱动程序:
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
为 null,并且驱动程序类正试图通过Class.forName(driverClassName)
. 据我了解,在这种情况下,驱动程序类正在加载与原样相同的类加载器实例BasicDataSource
。这是StandardClassLoader
,如果我的 jar 在 tomcat 库中,它将加载类。在我的情况下,异常被抛出并被Thread.currentThread().getContextClassLoader()
使用,它是WebappClassLoader
实例,可以从 webapp lib 加载类,它确实如此。所以我很困惑。为什么说,如果我使用来自容器资源的数据源,我必须将我的驱动程序类放在 tomcat 库中。
请解释一下,谢谢