ゆるくエンジニア日記

職業はシステムエンジニア。日々の学びや感じたことをゆるく記録していきます。

エラー備忘録 NoClassDefFoundError

個人的に別のツールにまとめている除法を整理している中で、少し印象に残っていたエラーがあったので、ご紹介。
ただ、あまり詳しく書きすぎるとあれなので、少し抽象化した形で記載します。

NoClassDefFoundErrorとは

以下公式ドキュメントより

通常のメソッド呼び出し、あるいはnew式を使った新しいインスタンスの生成で、Java仮想マシンまたはClassLoaderインスタンスがクラス定義をロードしようとしたが、クラス定義が見からない場合にスローされます。 検索されるクラス定義は、現在実行中のクラスをコンパイルする時点では存在していましたが、その後見つからなくなっています。
NoClassDefFoundError (Java SE 17 & JDK 17)

直接的な原因は別の UnsatisfiedLinkError

当時対応していた時は、ひたすらNoClassDefFoundErrorに関する情報を収集していたが、実は潜在的な問題が別にあり、このエラーは直接的なエラーではないことがわかった。
直接的なエラーは、UnsatisfiedLinkErrorというもの。
このエラーがでてしまった場合、JVMがそのエラーがでたクラスを記憶し、再度そのクラスにアクセスしようとすると、NoClassDefFoundErrorがでるという事象だった。
そのため、このエラーは初回起動してから初回クラスアクセス時にはコンソールに出力されるが、その後は何回処理を実行しても、でてこなくなる。

UnsatisfiedLinkErrorとは

Java仮想マシンが、nativeと宣言されたメソッドの適切なネイティブ言語の定義を見つけることができない場合にスローされます。
UnsatisfiedLinkError (Java SE 17 & JDK 17)

結局のところの原因

結局のところは、必要なDLLなどのモジュールが配置されている箇所へのパスが通っていないことが原因でした。
わかった時は、そんな凡ミスか、、、と嘆いたのはいい思い出ですが、、、
長く時間を費やしても解決できないようなエラーって、経験上こういう凡ミスやそもそもの前提の認識が誤っていたとか往々にしてあると思います。

ついでに ClassNotFoundException との違いは?

当時調査している中で調べてみたので、ついでに。
大きな違いは、ClassNotFoundExceptionは、コンパイルすらできるかわからない状況であるということ。
NoClassDefFoundErrorの場合は、公式にも記載されている通り、コンパイル時点では存在していたはずのクラスということ。
もう少し具体的になると、ClassNotFoundExceptionは以下のパターンで発生する。

補足

ここで記載しているエラーは、あくまで一例なので、NoClassDefFoundErrorUnsatisfiedLinkErrorが発生する原因は、他の場合も多々あります。
特にNoClassDefFoundErrorなんかは、ClassLoaderの読み込み優先順位や参照権限の問題なども取り上げられており、頭が混乱していました。
もし同じようなことでお困りの方の助けになれば。。。