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

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

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

你能澄清一下“tomcat安装文件夹中的lib文件夹”是什么意思吗? 它应该直接指向Tomcat根目录下的/ lib。

Tomcat 7文档说这个:

因此,在WEB-INF / lib目录中具有数据库驱动程序的Web应用程序不能依赖于服务提供程序机制,而应该显式注册驱动程序。

正确的做法是设置JNDI数据源,而不是使用DriverManager在代码中创建一个。

我还建议将驱动程序版本与Oracle和JVM版本进行匹配。 JDK 6已达到其支持寿命的终点。 JDK 7是目前的生产。 如果您使用的是JDK 7,我建议您从ojdbc6.jar 升级 。

尝试在oracle的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的“通用”类加载器,但它不起作用,驱动程序没有注册。

经过一些调试后,似乎tomcat的JreMemoryLeakPreventionListener从“system”类加载器而不是“common”类加载器(来自tomcat的代码)初始化DriverManager:

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