如何在Tomcat 7.0.47启动时注册oracle jdbc驱动程序?

时间:2013-11-26 17:42:03

标签: java oracle tomcat jdbc driver

我将ojdbc6.jar复制到tomcat安装文件夹中的lib文件夹。 当我部署在JDBC连接中使用Oracle驱动程序的Web应用程序时,服务器说无法找到驱动程序类,我被迫手动执行DriverManager.registerDriver,然后就可以了。

可以这样做,所以驱动程序在启动时注册,我不必手动创建连接池吗?

2 个答案:

答案 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的类加载器的驱动程序的额外注册,因为它知道注册中的类名在启动期间。