Java ClassNotFoundExceptionスタックトレースの解析

Java ClassNotFoundExceptionとNoClassDefFoundErrorスタックトレースを解析。クラスローダーチェーン、欠落クラス名、クラスパス解決の詳細を抽出します。

Java

詳細な説明

Java ClassNotFoundExceptionの理解

ClassNotFoundExceptionはJVMがクラスローダーを通じてランタイムでクラスを見つけられない場合にスローされます。関連するNoClassDefFoundErrorはコンパイル時には利用可能だったクラスがランタイムで欠落している場合に発生します。

スタックトレースの例

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
    at java.base/java.lang.Class.forName(Class.java:375)
    at com.example.database.ConnectionFactory.createConnection(ConnectionFactory.java:34)

ClassNotFoundException vs NoClassDefFoundError

  • ClassNotFoundException --- ランタイムクラスロード失敗(Class.forName()、JDBCドライバーロード、リフレクション)
  • NoClassDefFoundError --- コンパイル時には存在したがランタイムで欠落(通常デプロイメント/パッケージングの問題)

一般的な原因

  • クラスパスにJARファイルが欠落
  • Maven/Gradle依存関係スコープの誤り(compile vs runtime vs provided)
  • アプリケーションサーバーのクラスローダー分離
  • fat JARパッケージングが推移的依存関係を除外
  • バージョン競合によりクラスが異なるパッケージに

診断手順

  1. エラーメッセージから完全修飾クラス名を抽出する
  2. そのクラスを提供するライブラリを特定する
  3. ビルドツール(Maven pom.xml / Gradle build.gradle)で依存関係を確認する
  4. デプロイメントターゲットに対して依存関係スコープが正しいか確認する
  5. -verbose:class JVMフラグでランタイムの実際のクラスパスを確認する

ユースケース

ClassNotFoundExceptionエラーはデプロイメント中、特にJava EE/Jakarta EE環境、複雑な依存関係ツリーを持つマイクロサービス、動的クラスロードを使用するアプリケーションで一般的です。失敗したデプロイメントをデバッグするDevOpsチームは、欠落クラスをすばやく特定し、正しい依存関係とパッケージング設定までたどる必要があります。

試してみる — Stack Trace Parser & Formatter

フルツールを開く