我将ojdbc6.jar复制到tomcat安装文件夹中的lib文件夹。 当我部署在JDBC连接中使用Oracle驱动程序的Web应用程序时,服务器说无法找到驱动程序类,我被迫手动执行DriverManager.registerDriver,然后就可以了。
可以这样做,所以驱动程序在启动时注册,我不必手动创建连接池吗?
答案 0 :(得分:3)
您能否澄清“tomcat安装文件夹中的lib文件夹”的含义?它应该直接指向Tomcat根目录下的/ lib。
Tomcat 7 docs这样说:
因此,在其中具有数据库驱动程序的Web应用程序 WEB-INF / lib目录不能依赖服务提供者机制 并应明确注册驱动程序。
正确的做法是设置JNDI data source,而不是使用DriverManager在代码中创建一个。
我还建议将驱动程序版本与Oracle和JVM版本进行匹配。 JDK 6已达到其支持生命的终点。 JDK 7是目前的生产。如果您使用的是JDK 7,我建议您从ojdbc6.jar upgrading。
答案 1 :(得分:2)
在oracle' s jdk 8_31上尝试将ojdbc7.jar与tomcat 8.0.20一起使用时,我遇到了同样的问题。
我已将ojdbc7.jar放在$ CATALINA_BASE / lib中,如下所示:http://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html 然后期望java的服务提供商机制使用tomcat" common"来注册驱动程序。 classloader,但它没有工作,驱动程序也没有注册。
经过一些调试后,似乎tomcat的JreMemoryLeakPreventionListener从"系统"中初始化了DriverManager。 classloader而不是" common" classloader(来自tomcat的代码):
// Use the system classloader as the victim for all this
// ClassLoader pinning we're about to do.
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
/*
* First call to this loads all drivers in the current class
* loader
*/
if (driverManagerProtection) {
DriverManager.getDrivers();
}
这里的问题是系统类加载器(在我的例子中是oracle的Launcher $ AppClassLoader)具有以下类路径:
file:$CATALINA_BASE/bin/bootstrap.jar
file:$CATALINA_BASE/bin/tomcat-juli.jar
由于ojbc7.jar不在此类路径中,因此DriverManager不会发现任何服务提供者,因此您的驱动程序只能显式注册,因为只有在加载DriverManager类时才从静态块进行扫描(这是它的根本缺陷。)
我的第一个想法是将ojdbc jar添加到tomcat的$ CATALINA_BASE / bin / setenv.sh中的系统的类加载器类路径中,如下所示:
CLASSPATH=$CATALINA_BASE/lib/ojdbc7.jar
这样,使用系统类加载器从JreMemoryLeakPreventionListener调用使用服务提供程序机制注册驱动程序。
您必须非常小心,不要将ojdbc驱动程序放在webapp的类加载器中(例如,在您的WEB-INF / lib文件夹中包含ojdbc),因为这些类优先于父类加载器的类。它有点复杂,但是当它使用调用者的类加载器调用Class.forName时,DriverManager本身可能会引起webapp的类加载器的驱动程序的额外注册,因为它知道注册中的类名在启动期间。