私は小さな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.jarおよびOracle11gを使用しています
編集済み-アプリケーションログファイル
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$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)
誰かがこの問題の解決のために私に近づいたとき。今投稿しています。
ドライバー名を静的な方法で保持しないでください。 JDBC + Java APIを使用して、次のようなドライバークラス名を取得します。
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がビルドパスに適切に設定されているかどうかを確認できる場合は、より良い方法です。
この情報がお役に立てば幸いです...
考えられる解決策は次のとおりです。[イベントビューア]-> [Windowsアーカイブ]に移動し、アプリケーションイベントとシステムイベントを削除します(セキュリティイベントは削除しないでください)。その後、PCを再起動すると問題ありません。
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日に機能したことを示していません!それはそれによってスローされたエラーがなかったことを示しただけです。これは、メソッドが呼び出されなかったことを意味している可能性があります(したがって、接続は試行されませんでした)。
Eclipseを使用している場合は、jarをojdbc14.jarに置き換えてクラスパスに追加しようとすると、問題が発生するようです。-Eclipse->(プロジェクトを選択)[プロパティ]に移動-> Javaビルドパス-> AddJarまたはAddExternalJarを選択します。
可能であれば、DriverManager.getConnection()メソッドのprintlnを表示します。失敗時に、例外なくDBからnull接続オブジェクトを取得している可能性があります。
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");
それが役立つかどうかはわかりませんが、これは私が同じことをしなければならないコードです、
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のクラスは必須であり、クラスローダーがOraclejdbcドライバをロードしたことを確認します。
発生している可能性があるのは、コードが実行されているマシンの接続の問題であるため、実際のojdbc6.jar(クラスパスで示されている)を含む場所に常にアクセスできるとは限りません(ローカルディスク上にない場合)。 。
「ojdbc6.jar」がアプリケーションサーバーのCLASSPATHにないようです。
クラスが見つからないと表示された場合、クラスが見つかりません。
私の経験から、この種の問題は時々機能し、時には機能しないので、スレッドに関連しています。私の仮定は、ClassLoader
がクラスを非同期でロードしているため、ロード直後に接続を呼び出すことが問題になる可能性があります。静的な部分にOracleクラスをロードしようとしましたか?何かのようなもの:
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());
}
}
}
別の問題:コードは毎日コンパイルされていますか(継続的デリバリーまたは...)?
私は「スケジュール」に慣れていませんが、最新の更新では、以前のアンデプロイ/再デプロイから完全に停止されなかったスレッドがあることが示唆されています。 スレッドをクリーンにシャットダウンする方法に関するJavaSpecialistsニュースレター があります。
サーブレットのシャットダウンコードがデータベースドライバの登録を解除するのではないかと思いますか?スタックトレースからは、Tomcatで実行しているように見えます。コードでドライバーの登録が直接解除されない場合でも、Tomcat 7以降では、Tomcatのメモリリーク検出/軽減の一環としてドライバーの登録が解除されると思います。
それは、ドライバーが存在する場合と存在しない場合がある理由を説明している可能性があります。