首页 文章

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

提问于
浏览
4

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

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

2 回答

  • 2

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

    Tomcat 7 docs这样说:

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

    正确的做法是使用DriverManager设置JNDI data source而不是在代码中创建一个_1574980 .

    如果您使用的是JDK 7,我建议_j7c ._d从ojdbc6.jar推荐upgrading .

  • 3

    尝试在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 's service provider mechanism to register the driver using tomcat' s "common" classloader,但它不起作用且驱动程序未注册 .

    经过一些调试后,似乎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的类加载器中的驱动程序的额外注册,因为它知道启动期间注册的类名 .

相关问题