简体   繁体   中英

No suitable driver found for Oracle Database connection

I have small Java Application, which execute every day and checks for data in database using Cronj Schedular and everything works fine, but recently I have observed that, it is failing due to

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

At the same time, when I run my test code to check Database connectivity that works fine without above exception. I'm unable to figure it out. Although, there was just slight code change, but that was nowhere related to Database or Database connection. Anyone, help me on this?

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;
    }
}

I'm using ojdbc6.jar and Oracle11g

Edited - Application Log file

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

So, you can see, It failed on 3rd and 6th July. But, in between it ran fine.

==Update 1==

It seems, nobody is reading my question properly, I have clearly mentioned that, It is running fine for someday, but someday it is failing. If it was classpath issue, then It shouldn't have ran any day.

===Update 2===

Many of below answers were pointless, but few were having some logical view. I have used printStracktrace and tried to debug each point and finally I got some clue. 3 Days back, I deployed new version of application on the same server (included printStackTrace and SysOut), First 2 days It ran fine, today it Failed with following error.

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$40.execute(JobStoreSupport.java:2759)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$40.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$43.execute(JobStoreSupport.java:2908)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$43.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)

The correct format for your JDBC URL is not what you wrote:

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

but either

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

or

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

depending on whether 'test' is a service or a SID.

The log fragment you showed doesn't show that the getConnection method worked on the 4th! It only showed there was no error thrown by it. This may just have meant that the method was never called (so no connection was attempted).

Not sure if it helps, but this is the code I have to do the same thing,

    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); 

So, not quite the same Class.forName, but same form for protocol.

The class for name is essential, it ensures that the class loader has loaded the Oracle jdbc driver.

What could be happening is some connectivity problem on the machine where the code is running, so that the location that contains the actual ojdbc6.jar (as pointed to on the classpath) is not always accessible (if it's not on a local disk ?).

看来,“ojdbc6.jar”不在您的应用程序服务器的CLASSPATH中。

When it says it can not find class it can not find the class.

From my experience, this sort of problems that sometimes work and sometime not are thread related. My assumption is ClassLoader is loading your class async, so calling connection just after loading it may be the problem. did u try loading oracle class in a static part? something like:

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());
    }
}
}

Another issue: Is your Code getting Compiled every day(By Continuous Delivery or ...)?

似乎问题是你的jar尝试用ojdbc14.jar替换它并将它添加到Class-path如果你使用Eclipse遵循以下步骤: - Eclipse - >(选择项目)转到属性 - > Java构建路径 - - >选择添加Jar或添加外部Jar。

If possible, view the println for DriverManager.getConnection () method. You may be getting a null connection object from DB without any exception, during failures.

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归档并删除应用程序事件和系统事件。(不要删除安全事件!)。之后重新启动电脑,你就可以了。

I'm unfamiliar with "schedular" but your latest update suggests that you have threads that weren't cleanly stopped from a previous undeploy/redeploy. There is a JavaSpecialists newsletter about how to shutdown threads cleanly .

I wonder if perhaps your servlet shutdown code unregisters the database driver? From your stacktrace it looks like you are running in Tomcat. Even if your code doesn't directly de-register the driver I believe Tomcat 7 and up will unregister drivers as part of Tomcat's memory leak detection/mitigation.

That might explain why the driver is sometimes present and sometimes not.

Don't keep the driver name in static way. Use the JDBC + Java API to get the driver class name like the following :

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;
    }
}

It is better, if you made any typo or and you can check whether the ojdbc6.jar is set in the build path in a good way..

Hope this information helps...

As someone approached me for the solution of this issue. I'm posting it now.

  1. I undeployed the application, which was having this issue and cleaned up all related files from the server.
  2. Then, I restarted the tomcat server. So that, it will flush up all temporary files and cache.
  3. Then, I deployed the same application and it started working without any issue.

Ensure the following things.

  • ojdbc Library is added to your project.
  • The library is added to your project class path.
  • Make sure your Connection Configuration such as URL, username and password are found properly while creating the DB connection.

The error means driver you are using doesn't accept connection URL. It seems like your URL uses MySQL syntax (DB name separated with '/'). Try to use Oracle specific definition: jdbc:oracle:thin:@160.110.xx.xxx:1521:test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM