Javaアプリケーションを実行すると,NoClassDefFoundError
が発生します。 この原因は何でしょうか?
コンパイル時とランタイム時のクラスパスの不一致が原因である可能性はありますが、必ずしもそうではありません。
この場合、2つまたは3つの異なる例外を頭の中で整理しておくことが重要です。
java.lang.ClassNotFoundException
この例外は、クラスパス上にクラスが見つからなかったことを示します。 これは、クラス定義をロードしようとして、クラスがクラスパス上に存在しなかったことを示しています。
java.lang.NoClassDefFoundError
この例外は、JVMが内部のクラス定義データ構造の中にクラスの定義を探したが、見つからなかったことを示しています。 これは、クラスパスからロードできなかったということとは異なります。 通常これは、以前クラスパスからクラスをロードしようとしたが、何らかの理由で失敗したことを示しています。今、再びそのクラスを使おうとしていますが(前回失敗したので、ロードする必要があります)、以前にロードに失敗した(また失敗するのではないかと合理的に考えられる)ため、ロードしようとはしていません。 前回の失敗は、ClassNotFoundException や ExceptionInInitializerError (静的初期化ブロックでの失敗を示す)など、さまざまな問題が考えられます。 重要なのは、NoClassDefFoundError が必ずしもクラスパスの問題ではないということです。
実行時に見つかったクラスと互換性のないバージョンでコードがコンパイルされると、NoClassDefFoundエラーが発生することがありました。 具体的な例としては、apache axis library が挙げられます。 ランタイムのクラスパスには実際には2つのバージョンがあり、正しいバージョンではなく、古くて互換性のないバージョンがピックアップされ、NoClassDefFoundエラーが発生していました。 これは、コマンドラインアプリで、以下のようなコマンドを使用していました。
set classpath=%classpath%;axis.jar
を使うことで、適切なバージョンをピックアップすることができました。
set classpath=axis.jar;%classpath%;