NoClassDefFoundError と ClassNotFoundException の原因と違いは何ですか?
-
12-09-2019 - |
質問
違いは何ですか NoClassDefFoundError
そして ClassNotFoundException
?
何が原因で投げられるのでしょうか?それらはどうすれば解決できるでしょうか?
既存のコードを変更して新しい jar ファイルを含めるときに、これらのスロー可能ファイルによく遭遇します。Webstart を通じて配布された Java アプリのクライアント側とサーバー側の両方でそれらをヒットしました。
私が遭遇した考えられる理由は次のとおりです。
- 含まれていないパッケージ
build.xml
コードのクライアント側の場合 - 使用している新しい jar のランタイム クラスパスがありません
- バージョンが以前のjarと競合します
今日、これらに遭遇したとき、私は物事をうまく機能させるために試行錯誤のアプローチをとります。もっと明確にして理解する必要があります。
解決
の違いから、Java APIの仕様は以下の通りです。
のための ClassNotFoundException
:
スローされに対応したアプリケーションしようとし 負荷のクラスを通してその文字列 名前:
- の
forName
ソクラスClass
.- の
findSystemClass
ソクラスClassLoader
.- の
loadClass
ソクラスClassLoader
.がクラスの定義と 指定された名前がみられた。
のための NoClassDefFoundError
:
た場合にスローされます。Java仮想マシンや a
ClassLoader
インスタンスをロードしようとする の定義にクラス(一環として、 通常のメソッド呼び出し 新しいインスタンスを作成して使用でき、 式の定義 クラスがみられた。検索したためにクラス定義 存在した場合は、現在実行している クラスが編纂されたものの定義 できなくなります。
なので、その NoClassDefFoundError
る場合に発生したため、実行時には、必要な class
ファイルが見つかりません。この場合もあらゆるトラブルの分布や生産のJARファイルがないすべての必要な class
ファイルが含まれます。
として ClassNotFoundException
, その場合幹を問わずいろいろな料理に使える反射電話のクラスのランタイム時において、その授業のプログラムが呼び出しが存在しません。
二つの違いとは Error
その他は Exception
.と NoClassDefFoundError
は Error
しかしながらJava仮想マシンに問題のクラスと予想されます。プログラムすると予想される仕事のコンパイル時に走らせることができませんで class
ファイルを指定しているか、または同じでないとして制作されたまたは検出された場合コンパイルします。このかわいらしい重要なエラーとしてのプログラムできませんのJVM.
一方で、 ClassNotFoundException
は Exception
, なので少し期待されるものは減損の有無を検討しています。反射ができるエラーが発生しやすいとしても期待のようなものとして期待される。ありませんコンパイル時の状況を定期的に確認し、必要なすべてのクラスが存在し、問題の発見、ご要望の授業が表示されます。
他のヒント
ClassNotFoundException は、報告されたクラスが ClassLoader で見つからない場合にスローされます。これは通常、クラスが CLASSPATH にないことを意味します。また、問題のクラスが親クラスローダーにロードされた別のクラスからロードしようとしており、そのため子クラスローダーのクラスが表示されていないことも意味する可能性があります。これは、App Server などのより複雑な環境で作業する場合に発生することがあります (WebSphere は、このようなクラスローダーの問題で悪名高いです)。
人々はしばしば混乱する傾向があります java.lang.NoClassDefFoundError
と java.lang.ClassNotFoundException
ただし、重要な違いがあります。たとえば、例外(実際にはエラーです) java.lang.NoClassDefFoundError
は java.lang.Error のサブクラスです) のような
java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory
これは、ActiveMQConnectionFactory クラスが CLASSPATH にないという意味ではありません。実際、それはまったく逆です。これは、クラス ActiveMQConnectionFactory が ClassLoader によって検出されたが、クラスをロードしようとしたときにクラス定義の読み取りエラーが発生したことを意味します。これは通常、問題のクラスに、ClassLoader で見つからないクラスを使用する静的ブロックまたはメンバーがある場合に発生します。したがって、原因を見つけるには、問題のクラス (この場合は ActiveMQConnectionFactory) のソースを表示し、静的ブロックまたは静的メンバーを使用しているコードを探します。ソースにアクセスできない場合は、JAD を使用して逆コンパイルしてください。
コードを調べると、たとえば以下のようなコード行が見つかった場合、クラス SomeClass が CLASSPATH に含まれていることを確認してください。
private static SomeClass foo = new SomeClass();
ヒント :クラスがどの jar に属しているかを確認するには、Web サイト jarFinder を使用できます。これにより、ワイルドカードを使用してクラス名を指定でき、jar データベース内でクラスを検索できます。jarhoo を使用すると同じことができますが、無料では使用できなくなりました。
クラスがどの jar に属しているかをローカル パスで見つけたい場合は、jarscan () のようなユーティリティを使用できます。 http://www.inetフィードバック.com/jarscan/ )。検索したいクラスと、jar および zip ファイル内のクラスの検索を開始するルート ディレクトリ パスを指定するだけです。
NoClassDefFoundError
は、基本的にリンクエラーです。それはコンパイル時にいたとき、あなたがしようとすると(静的に「新」で)オブジェクトをインスタンス化し、それが見つかっていないとき、それが発生します。
ClassNotFoundException
は、より一般的であり、あなたが存在しないクラスを使用しようとすると、実行時例外です。たとえば、機能インタフェースを受け入れ、誰かがそのインターフェイスを実装するクラスに渡していますが、クラスへのアクセスを持っていないのパラメータを持っています。それはまた、loadClass()
又はClass.forName()
を使用して、動的クラスローディングのケースをカバーしています。
のNoClassDefFoundError(NCDFE)が起こります。
これは単に他のコメントが示唆するように、Yは、あなたのクラスローダから欠落していることかもしれないが、それはYが表示されていない別のクラスローダによってロードされていることをYクラスが署名されていないことであるか、または無効な署名を持っている、または可能性がありあなたのコードに、またはYは、上記のいずれかの理由によりロードできませんでしたZに依存してもこと。
この問題が発生した場合、JVMはロードX(NCDFE)の結果を覚えているだろうし、それは単に、なぜあなたを伝えることなく、新しいNCDFEあなたがYを求めるたびにスローされます。
class a { static class b {} public static void main(String args[]) { System.out.println("First attempt new b():"); try {new b(); } catch(Throwable t) {t.printStackTrace();} System.out.println("\nSecond attempt new b():"); try {new b(); } catch(Throwable t) {t.printStackTrace();} } }
のa.javaどこかにの
としてこれを保存しますのコードは、単にそれ以外の、二回新しい「B」クラスをインスタンス化しようとすると、それはどんなバグを持っていない、それは何もしません。
javac a.java
を呼び出すことによって実行し、java -cp . a
でコードをコンパイルします - 。それはちょうど2行のテキストを印刷する必要があり、それはエラーなしで正常に動作する必要があります。
そして、「$のb.class」ファイルを削除(またはゴミでそれを埋める、またはそれを超えるa.classコピー)が存在しないか、または破損したクラスをシミュレートします。ここでは何が起こるかです:
First attempt new b(): java.lang.NoClassDefFoundError: a$b at a.main(a.java:5) Caused by: java.lang.ClassNotFoundException: a$b at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) ... 1 more Second attempt new b(): java.lang.NoClassDefFoundError: a$b at a.main(a.java:7)
質問(new b()
)内のコードから、未チェックのNoClassDefFoundErrorに包まれなければならない、(それがクラスを見つけることができないクラスローダによってスロー)にClassNotFoundExceptionでの最初の呼び出しの結果だけで動作するはずです。
第二の試みは、当然のことながら、あまりにも失敗しませんが、あなたが見ることができるようにクラスローダが失敗したクラスローダを覚えているようですので、ラップされた例外は、それ以上です。あなたは本当に何が起こったかについての全く手掛かりとだけNCDFEを参照してください。
あなたは今までに無い根本的な原因でNCDFEを参照してください場合は、だから、あなたはあなたがクラスは、エラーの原因を見つけるために、ロードされた非常に最初の時間に戻って追跡することができるかどうかを確認する必要があります。
から http://www.javaroots.com/2013/02/classnotfoundexception-vs.html:
ClassNotFoundException
:がクラスローダることができません必要なクラスのクラスパスです。なので、基本的に確認しておきましょうクラスパスに追加のクラスのクラスパス.
NoClassDefFoundError
:ことが難しいデバッグを見つの理由です。この場合にスローされコンパイル時に必要なクラスが実行時のクラスに変更または削除されたクラスのstatic初期化を投げることができます。このクラスがロードはクラスパスが一つの授業で必要となるこのクラスは削除に失敗したりした荷重によるコンパイラです。っていることを確認して下さいクラスに依存することができる。
例:
public class Test1
{
}
public class Test
{
public static void main(String[] args)
{
Test1 = new Test1();
}
}
今後の編集の授業をお持ちの方がおられましたTest1.class ファイルとテストクラスをスローします
Exception in thread "main" java.lang.NoClassDefFoundError: Test
at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
ClassNotFoundException
:スローされに対応したアプリケーションをロードしようとするクラスを通してその名がクラスの定義を指定した名前がみられた。
NoClassDefFoundError
:た場合にスローされます。Java仮想マシンがロードの定義にクラスは、定義しないクラスがみられた。
それらのそれぞれと、このようなエラーに対処する方法上の任意の思考プロセスを取得するための理由は何ですか?
彼らは密接に関連しています。 Javaは名前で特定のクラスを探していると正常に読み込むことができませんでした行ったときClassNotFoundException
がスローされます。 NoClassDefFoundError
は、Javaは、いくつかの既存のコードにリンクされたクラスを探しに行ったときにスローされますが、一つの理由または別の(例えば、間違ったクラスパス、ジャワ、ライブラリの間違ったバージョンの間違ったバージョン)のためにそれを見つけることができなかったし、徹底的ですそれとして致命的な何かがひどく間違っていることを示しています。
、CNFEは/ dlopen()
をdlsym()
の失敗のようなもので、NCDFEは、リンカの問題です。後者の場合には、該当するクラスファイルは、実際にあなたがそれらを使用しようとしている設定でコンパイルされていないんます。
例1:
class A{
void met(){
Class.forName("com.example.Class1");
}
}
com/example/Class1
は、クラスパスのいずれかに存在しない場合には、それはClassNotFoundException
をスローします。
例2:
Class B{
void met(){
com.example.Class2 c = new com.example.Class2();
}
}
com/example/Class2
はBのコンパイル中に存在していたが、実行には、それはNoClassDefFoundError
をスローしながら見つからない場合ます。
の両方が、時間の例外を実行されます。
ClassNotFoundException があった場合にスローされますが試行のクラスを参照する文字列です。例えば、パラメータクラスです。forName()は文字列は、この昇の可能性を無効バイナリ名が渡されるクラスローダ.
にClassNotFoundExceptionがスローされますが潜在的に無効なバイナリ名が検出された;たとえば、クラス名には'/'文字まで、ClassNotFoundException.また場合にスローされますので直接参照するクラスではご利用いただけませんのクラスパス.
一方で、 NoClassDefFoundError がスローされます
- 実際の物理的表現クラスとなります。●クラスファイルが利用でき
- または、クラスにロードされていて、異なるクラスローダ(通常は親クラスローダがロードのクラスに面したこのクラスを読み込むことはできません)
- た場合に互換性のないクラス定義が見いだされたの名前、クラスファイルと一致しない要求された名前
- 又は(もの)の場合は、依存のクラスにあるとみなされます。この場合には、直接参照するクラスがあり取り込んだものの、依存のクラスは読み込むことはできません。これはシナリオを直接参照するクラスを読み出す事が可能。forNameまたは同等の方法。このことを示し、失敗の連携です。
にNoClassDefFoundErrorは常にスローされる新しい()諸表またはメソッド呼び出しされたクラス欠席に対して、文字列に基づく負荷の授業のためにClassNotFoundExceptionが、classloaderがきまたは負荷のクラス定義します。
それまでのクラスローダ実装に投げのインスタンスClassNotFoundExceptionができない負荷できます。最もカスタムクラスローダの実装を行うこれらのURLClassLoader.通常はたclassloaderな明示的にスNoClassDefFoundErrorのいずれかの方法で実装-この例外は、通常投げられたのJVMのホットスポットコンパイラによるのではなく、クラスローダです。
の名前そのものができますか
Exception
その他については,Error
.
例外: 例外発生時の実行時にプログラム。プログラマ対応できるこれらの例外のようcatchブロックです。いつの例外をスローしました。確認の例外をスローコンパイルす。実行時例外がスローされ実行時に、これらの例外は通常起こして悪いプログラミング
エラー: これらの例外ではなく、この範囲を超えてプログラマを交換してください。これらのエラーは通常、スローされるJVM.
差:
ClassNotFoundException:
- クラスローダに失敗した 確認 クラスのバイトコードを出すこと リンクの相 の クラスローディングサブシステム ま
ClassNotFoundException
. ClassNotFoundException
は確認の例外から直接導き出java.lang.Exception
クラスを提供する必要があります明示的な取扱いClassNotFoundException
が登場合があり 明示的な積載 のクラスは提供により名前のクラスの実行時に使用ClassLoader.loadClass(),クラスです。forName()は、ClassLoader.findSystemClass().
NoClassDefFoundError:
- クラスローダに失敗した 解決 参考文献のクラス リンクの相 の クラスローディングサブシステム ま
NoClassDefFoundError
. NoClassDefFoundError
エラーから派生LinkageError
クラス上に表示するために使用されるエラーの場合、クラスに依存したその他のクラスとこのクラスはincompatibly変更後に作成する。NoClassDefFoundError
結果 暗黙的載荷 クラスのメソッドの呼び出しからこのクラスまたは変更登録が可能です。
類似性:
- 両
NoClassDefFoundError
やClassNotFoundException
関連する収束作用のクラスを実行します。 - 両
ClassNotFoundException
やNoClassDefFoundError
関連するJavaクラスパス.
このクラスローダsussystem。
こはっく理解の違い: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
エラーが発生した場合はクラスローディング、インスタンスの サブクラス LinkageError 必ずれの時点のプログラム (直接または間接的に使用のクラスまたはインタフェースとみなされます。
場合は、Java仮想マシンが初の試みでクラスをロード中C 検証(§5.4.1)または分解能(§5.4.3)が初期化 (§5.5)、クラスローダを使用することの組込C スローのインスタンス ClassNotFoundException, は、Java仮想 機械をスローする必要があのインスタンス NoClassDefFoundError その原因 インスタンスの ClassNotFoundException.
なので、 ClassNotFoundException は、サプライチェーンのなかで多様な NoClassDefFoundError.
や NoClassDefFoundError 特にタイプの負荷エラーが発生 リンク ます。
追加の一因で実践:
- ClassNotFoundException:としてcletusと、インターフェースが継承されたクラスのインタフェースのクラスパス.例えば、サービスプロバイダのパターン(または サービスロケータ に特定のチームの存在しないクラス
- NoClassDefFoundError:指定されたクラスが見つかりながら、依存関係の指定されたクラスが見つからなかった
に実践, エラー 場合にスローされ 黙々と, る。gを提出すタイマータスクのタイマータスクです エラー, がほとんどの場合、プログラムのみを捕 例外.その後、 タイマー メインループを終了しな情報です。同様のエラーはNoClassDefFoundError ExceptionInInitializerError, がstatic初期化子または初期化のための静的変数の例外がスローされます。
ClassNotFoundException はチェック例外が発生してたくさんのJVMへの負荷のクラスにより、その文字列名を使用。forName()またはClassLoader.findSystemClass()またはClassLoader.loadClass()メソッドは、上記のクラスが見つからなかったのclasspath.
ほとんどの時間をこようとすると例外が発生しますが、申請を更新しないクラスパスに対し、必要なJARファイルです。例えば、この例外がこのJDBCコードを接続するデータベースのi.e.MySQLがクラスパスはJARます。
NoClassDefFoundError エラーが発生した場合、JVMをロードしようとする特定のクラスは、一部のコード実行の一環として、通常のメソッド呼び出しをインスタンス用の新しいキーワードとクラスは存在しないclasspathたが、現在のコンパイル時間で実行するために、プログラムが必要でコンパイルできない使用しないコンパイラを作成エラーになります。
下記の簡単な説明
てみましょう自分のもってリフレッシュ
ClassNotFoundException
クラス階層
ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable
なデバッグ
- 必要なjarンクをクラスパス.
- 検証し、必要なすべてのjarはclasspathのjvm.
NoClassDefFoundError
クラス階層
NoClassDefFoundError extends LinkageError extends Error extends Throwable
なデバッグ
- 問題への積み込みクラスを動的に作成と適正な
- 問題静ブロック、コンストラクタは、init()メソッドの依存のクラスは、実際のエラーに包まれる複数の層"特ご利用の際は春休止状態実際の例外に包まれますNoClassDefError]
- き顔"ClassNotFoundException"の下での静電気をブロックのクラスに依存
- 問題はバージョンのクラスです。この場合のいいバージョンv1,v2の同じクラスの異なるjar/パッケージの作成と実用v1とv2がロードされ、実行時あるいは、関連法/vars&されます。[Iは一気に解消にこの問題を取り除き、複製のlog4j関連するクラスの下には複数のjarファイ"に登場するclasspath]
にClassNotFoundExceptionとNoClassDefFoundErrorが、特定のクラスがruntime.Howeverで見つからない場合、それらは異なるシナリオで起こる起こる。
ClassNotFoundExceptionが、あなたがClass.forNameのを(使用して実行時にクラスをロードしようとするときに発生する例外です)、またはのloadClass()メソッドやクラスがクラスパスに見つからない言及しています。
public class MainClass
{
public static void main(String[] args)
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
}catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at pack1.MainClass.main(MainClass.java:17)
のNoClassDefFoundErrorは、特定のクラスをコンパイル時に存在している場合に発生するエラーですが、実行時に欠落していました。
class A
{
// some code
}
public class B
{
public static void main(String[] args)
{
A a = new A();
}
}
あなたは上記のプログラムをコンパイルすると、、2つの.classファイルが生成されます。一つはA.classであり、もう一つはB.classです。あなたはA.classファイルを削除し、B.classファイルを実行すると、Javaランタイムシステムは、以下のようにNoClassDefFoundErrorがスローされます。
Exception in thread "main" java.lang.NoClassDefFoundError: A
at MainClass.main(MainClass.java:10)
Caused by: java.lang.ClassNotFoundException: A
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)