找不到适合 Oracle 数据库连接的驱动程序

No suitable driver found for Oracle Database connection

我有一个小的 Java 应用程序,它每天执行并使用 Cronj Schedular 检查数据库中的数据,一切正常,但最近我观察到,由于

java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@160.110.xx.xxx:1521/test

同时,当我 运行 我的测试代码检查数据库连接时,没有上述异常工作正常。我想不通。虽然只是轻微的代码更改,但这与数据库或数据库连接无关。有人帮我解决这个问题吗?

dbconf.java

public class dbconf {

    private Connection connect;
    private String connstr;

    public Connection getConnection() throws SQLException {
        connstr = "jdbc:oracle:thin:@160.110.xx.xxx:1521/test";

        try {
                String uname = "scott";
                String pass = "tiger";
                Class.forName("oracle.jdbc.OracleDriver").newInstance();
                connect = DriverManager.getConnection(connstr, uname, pass);

        } catch (Exception e) {
            System.out.println(e.toString());
        }

            return connect;
    }
}

我正在使用 ojdbc6.jarOracle11g

已编辑 - 应用程序日志文件

Wed Jul 01 09:25:17 IST 2015:------- Initializing -------------------
Wed Jul 01 09:25:17 IST 2015:------- Scheduling Jobs ----------------
Wed Jul 01 09:25:17 IST 2015:------- Job Started Running ----------------
Thu Jul 02 06:00:00 IST 2015 : Job Executed..!! Bschedularv2.2
java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@160.xxx.67.xxx:1521/test
Sat Jul 04 06:00:00 IST 2015 : Job Executed..!! Bschedularv2.2
Sun Jul 05 06:00:00 IST 2015 : Job Executed..!! Bschedularv2.2
java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@160.xxx.67.xxx:1521/test

所以,你可以看到,它在 7 月 3 日和 6 日失败了。但是,在它之间 运行 很好。

==更新1==

看来,没有人正确阅读我的问题,我已经明确提到,运行宁某天很好,但某天它失败了。如果是类路径问题,那么它不应该有 运行 任何一天。

===更新2===

下面的许多答案都是毫无意义的,但很少有人有一些逻辑观点。我已经使用 printStracktrace 并尝试调试每个点,最后我得到了一些线索。 3 天前,我在同一台服务器上部署了新版本的应用程序(包括 printStackTrace 和 SysOut),前 2 天它 运行 很好,今天它失败并出现以下错误。

INFO: Illegal access: this web application instance has been stopped already.  Could not load com.schedular.job.BirthdayJob.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at org.quartz.simpl.LoadingLoaderClassLoadHelper.loadClass(LoadingLoaderClassLoadHelper.java:59)
    at org.quartz.simpl.CascadingClassLoadHelper.loadClass(CascadingClassLoadHelper.java:99)
    at org.quartz.simpl.CascadingClassLoadHelper.loadClass(CascadingClassLoadHelper.java:138)
    at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:852)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2816)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.execute(JobStoreSupport.java:2759)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.execute(JobStoreSupport.java:2757)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3787)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2756)
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:272)

Jul 13, 2015 6:00:00 AM org.apache.catalina.loader.WebappClassLoader loadClass
INFO: Illegal access: this web application instance has been stopped already.  Could not load com.schedular.job.BirthdayJob.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at org.quartz.simpl.LoadingLoaderClassLoadHelper.loadClass(LoadingLoaderClassLoadHelper.java:59)
    at org.quartz.simpl.CascadingClassLoadHelper.loadClass(CascadingClassLoadHelper.java:99)
    at org.quartz.simpl.CascadingClassLoadHelper.loadClass(CascadingClassLoadHelper.java:138)
    at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:852)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1385)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggerFired(JobStoreSupport.java:2964)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.execute(JobStoreSupport.java:2908)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.execute(JobStoreSupport.java:2901)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3787)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggersFired(JobStoreSupport.java:2900)
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:336)

该错误表示您使用的驱动程序不接受连接 URL。您的 URL 似乎使用 MySQL 语法(数据库名称以“/”分隔)。尝试使用 Oracle 特定定义:jdbc:oracle:thin:@160.110.xx.xxx:1521:test

您 JDBC URL 的正确格式与您所写的不符:

connstr = "jdbc:oracle:thin:@160.110.xx.xxx:1521/test";

但要么

connstr = "jdbc:oracle:thin:@//160.110.xx.xxx:1521/test";

connstr = "jdbc:oracle:thin:@160.110.xx.xxx:1521:test";

取决于 'test' 是服务还是 SID。

您显示的日志片段并未显示 getConnection 方法在 4 日有效!它只表明它没有抛出错误。这可能只是意味着从未调用该方法(因此未尝试连接)。

不确定是否有帮助,但这是我必须做同样事情的代码,

    try { 
        Class.forName("oracle.jdbc.driver.OracleDriver"); 
    } catch (ClassNotFoundException e) { 
        System.out.println("Could not load the driver"); 
    } 

    Connection conn = DriverManager.getConnection                                     ("jdbc:oracle:thin:@ten10:1521:acdb", user, pass); 

因此,不完全相同 Class.forName,但协议形式相同。

name 的 class 是必不可少的,它确保 class 加载器已经加载了 Oracle jdbc 驱动程序。

可能发生的是代码为 运行 的机器上的一些连接问题,因此包含实际 ojdbc6.jar 的位置(如 class 上所指) path) 并不总是可访问的(如果它不在本地磁盘上?)。

看来,"ojdbc6.jar" 不在您的应用服务器的 CLASSPATH 中。

当它说找不到 class 它找不到 class.

根据我的经验,这类有时有效有时无效的问题与线程相关。我的假设是 ClassLoader 正在加载您的 class 异步,因此在加载后立即调用连接可能是问题所在。您是否尝试在静态部分加载 oracle class?类似于:

public class dbconf {

static {
  Class.forName("oracle.jdbc.OracleDriver");
}

public Connection getConnection() throws SQLException {
    String connstr = "jdbc:oracle:thin:@160.110.xx.xxx:1521/test";
    try {
        String uname = "scott";
        String pass = "tiger";
        return DriverManager.getConnection(connstr, uname, pass);
    } catch (Exception e) {
        System.out.println(e.toString());
    }
}
}

另一个问题:您的代码是否每天都在编译(通过持续交付或...)?

看来问题出在您的 jar 上,如果您使用的是 Eclipse,请尝试用 ojdbc14.jar 替换并将其添加到 Class-path 中,请按照以下步骤操作:- Eclipse --> (Select 项目)转到属性 --> Java 构建路径 --> 选择添加 Jar 或添加外部 Jar。

如果可能,查看 DriverManager.getConnection 的 println () 方法。在失败期间,您可能毫无例外地从数据库中获取空连接对象。

SQLException reason = null;
for(DriverInfo aDriver : registeredDrivers) {
    if(isDriverAllowed(aDriver.driver, callerCL)) {
        try {
            println("    trying " + aDriver.driver.getClass().getName());
            Connection con = aDriver.driver.connect(url, info);
            if (con != null) {
                println("getConnection returning " + aDriver.driver.getClass().getName());
                return (con);
            }
        } catch (SQLException ex) {
            if (reason == null) {
                reason = ex;
            }
        }

    } else {
        println("    skipping: " + aDriver.getClass().getName());
    }

}
if (reason != null)    {
    println("getConnection failed: " + reason);
    throw reason;
}
println("getConnection: no suitable driver found for "+ url);
throw new SQLException("No suitable driver found for "+ url, "08001");

一个可能的解决方案是:转到事件查看器 -> Windows 存档并删除应用程序事件和系统事件。(不要删除安全事件!)。之后重新启动你的电脑,你就可以了.

我不熟悉 "schedular",但你的最新更新表明你有一些线程没有从之前的 undeploy/redeploy 中完全停止。有一个JavaSpecialists newsletter about how to shutdown threads cleanly.

我想知道您的 servlet 关闭代码是否注销了数据库驱动程序?从您的堆栈跟踪来看,您似乎在 Tomcat 中 运行。即使您的代码没有直接注销驱动程序,我相信 Tomcat 7 及更高版本将注销驱动程序作为 Tomcat 内存泄漏的一部分 detection/mitigation。

这或许可以解释为什么驱动程序有时存在有时不存在。

不要以静态方式保留驱动程序名称。使用 JDBC + Java API 获取驱动程序 class 名称,如下所示:

public class dbconf {

    private Connection connect;
    private String connstr;

    public Connection getConnection() throws SQLException {
        connstr = "jdbc:oracle:thin:@160.110.xx.xxx:1521/test";

        try {
                String uname = "scott";
                String pass = "tiger";
                Class.forName(OracleDriver.class.getClass().getName().toString()).newInstance();
                connect = DriverManager.getConnection(connstr, uname, pass);

        } catch (Exception e) {
            System.out.println(e.toString());
        }

            return connect;
    }
}

最好,如果你打错了或者你可以检查ojdbc6.jar是否在构建路径中设置好了..

希望此信息对您有所帮助...

有人来找我解决这个问题。我现在发布。

  1. 我取消部署了出现此问题的应用程序,并从服务器上清除了所有相关文件。
  2. 然后,我重新启动了 tomcat 服务器。因此,它将刷新所有临时文件和缓存。
  3. 然后,我部署了相同的应用程序,它开始正常工作。

确保以下事项。

  • ojdbc 库已添加到您的项目中。
  • 库已添加到您的项目 class 路径。
  • 确保在创建数据库连接时正确找到您的连接配置,例如 URL、用户名和密码。