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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20224222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 00:24:44  来源:igfitidea点击:

How to register oracle jdbc driver on Tomcat 7.0.47 startup?

javaoracletomcatjdbcdriver

提问by tonlika

I copied ojdbc6.jar to the lib folder in the tomcat installation folder. When I deploy my Web App which makes use of the Oracle Driver in a JDBC Connection, the server says that the driver class can't be found, and I am forced to do DriverManager.registerDriver manually, then it works.

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

Can it be done so the driver is registered at startup and I don't have to do it manually neither create a connection pool?

是否可以这样做,以便在启动时注册驱动程序并且我不必手动执行此操作,也不必创建连接池?

采纳答案by duffymo

Can you clarify what you mean by "lib folder in the tomcat installation folder"? It should mean the /lib directly under your Tomcat root.

你能解释一下“tomcat安装文件夹中的lib文件夹”是什么意思吗?它应该是 Tomcat 根目录下的 /lib。

The Tomcat 7 docssay this:

Tomcat的7文档这样说:

Thus, the web applications that have database drivers in their WEB-INF/lib directory cannot rely on the service provider mechanism and should register the drivers explicitly.

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

The right thing to do is to set up a JNDI data sourcerather than creating one in your code using DriverManager.

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

I'd also recommend matching the driver version to both your Oracle and JVM versions. JDK 6 has reached the end of its support life. JDK 7 is current production. I'd recommend upgradingfrom ojdbc6.jar if you're using JDK 7.

我还建议将驱动程序版本与您的 Oracle 和 JVM 版本相匹配。JDK 6 的支持生命周期已结束。JDK 7 是当前产品。如果您使用的是 JDK 7,我建议您从 ojdbc6.jar升级

回答by mryan

I had the same issue when trying to use ojdbc7.jar with tomcat 8.0.20 on oracle's jdk 8_31.

尝试在 oracle 的 jdk 8_31 上使用 ojdbc7.jar 和 tomcat 8.0.20 时遇到了同样的问题。

I have put the ojdbc7.jar in $CATALINA_BASE/lib as suggested here : http://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.htmland then expected java's service provider mechanism to register the driver using tomcat's "common" classloader, but it doesn't work and the driver does not get registered.

我已经按照这里的建议将 ojdbc7.jar 放在 $CATALINA_BASE/lib 中:http: //tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html然后期望 java 的服务提供者机制进行注册驱动程序使用 tomcat 的“通用”类加载器,但它不起作用并且驱动程序未注册。

After a bit of debugging, It seems that tomcat's JreMemoryLeakPreventionListener initializes the DriverManager from the "system" classloader and not the "common" classloader (from tomcat's code) :

经过一些调试,似乎tomcat的JreMemoryLeakPreventionListener从“系统”类加载器而不是“普通”类加载器(来自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();
}

The problem here is that the system classloader (in my case oracle's Launcher$AppClassLoader) has the following classpath :

这里的问题是系统类加载器(在我的例子中是 oracle 的 Launcher$AppClassLoader)具有以下类路径:

file:$CATALINA_BASE/bin/bootstrap.jar
file:$CATALINA_BASE/bin/tomcat-juli.jar

Since ojbc7.jar is not in this classpath, no service provider will be discovered by the DriverManager, so your driver can only be explicitly registered since the scan is only done from a static block when the DriverManager class is loaded (which is it's fundamental flaw).

由于 ojbc7.jar 不在这个类路径中,DriverManager 将不会发现任何服务提供者,因此您的驱动程序只能显式注册,因为扫描仅在加载 DriverManager 类时从静态块完成(这是它的基本缺陷)。

My first idea to fix this was to add the ojdbc jar to the system's classloader classpath in tomcat's $CATALINA_BASE/bin/setenv.sh like so :

我解决这个问题的第一个想法是将 ojdbc jar 添加到 tomcat 的 $CATALINA_BASE/bin/setenv.sh 中系统的类加载器类路径,如下所示:

CLASSPATH=$CATALINA_BASE/lib/ojdbc7.jar

With this, the driver is registered using the service provider mechanism from the JreMemoryLeakPreventionListener invocation using the system classloader.

有了这个,驱动程序使用系统类加载器从 JreMemoryLeakPreventionListener 调用中使用服务提供者机制注册。

You have to be very careful not to bring the ojdbc driver in your webapp's classloader (by having ojdbc in your WEB-INF/lib folder for instance) as those classes have priority over the ones from parent classloaders. It's a bit complex but the DriverManager itself may cause and additional registration of the driver from the webapp's classloaders when it calls Class.forName using the caller's classloader because it knows the class name from the registration during startup.

您必须非常小心,不要将 ojdbc 驱动程序带入您的 web 应用程序的类加载器(例如,通过将 ojdbc 放在您的 WEB-INF/lib 文件夹中),因为这些类的优先级高于来自父类加载器的类。这有点复杂,但是当 DriverManager 使用调用者的类加载器调用 Class.forName 时,DriverManager 本身可能会导致从 webapp 的类加载器中额外注册驱动程序,因为它在启动期间从注册中知道类名。