我想使用tomcat jdbc連接池,並在我的應用程序context.xml文件中定義它。通過資源(Tomcat 7)加載jdbc驅動程序
<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文件夾中定義。對我來說它工作得很好。但here據說,帶驅動程序類的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
爲空,而驅動程序類是嘗試通過Class.forName(driverClassName)
被加載。據我所知,在這種情況下,驅動程序類正在加載與BasicDataSource
相同的類加載器實例。這是StandardClassLoader
,如果我的jar在tomcat庫中,它將加載這個類。在我的情況下,拋出異常,並使用Thread.currentThread().getContextClassLoader()
,這是WebappClassLoader
實例,並可以從Web應用程序庫中加載類,它會。所以我很困惑。爲什麼說,如果我從容器資源使用數據源,我必須將我的驅動程序類放在tomcat庫中。
請解釋一下,謝謝
我知道。從代碼中可以看到,當通用加載程序無法加載驅動程序時,上下文類加載程序(指的是webapp classloader)會成功加載驅動程序。這就是爲什麼我很困惑 –
嗯。讓我去挖掘源代碼。你確定你在使用Tomcat 7嗎?究竟是哪個版本? (Tomcat 8有上面的代碼,但Tomcat 7沒有 - 該源代碼片段從哪裏來?) –
我使用的是7.0.27版本。此外,我已經檢查過版本6,並看到代碼的相同部分 –