Java で「UnsupportedClassVersionError(class file version)」が解決できない
実行側の JVM がクラスファイルより古いと出る。
エラー文の数値はクラスファイル形式のメジャーバージョンで、Java 8 が 52、11 が 55、17 が 61、21 が 65 に対応する。
JVM を上げるか --release を下げて解決する。
公開:
要約
UnsupportedClassVersionError は、クラスファイルの形式バージョンが実行側の JVM の対応範囲を超えているときに出る。
コードの誤りではなく、ビルドした Java と実行している Java の食い違いである。
Error: LinkageError occurred while loading main class com.example.App
java.lang.UnsupportedClassVersionError: com/example/App has been compiled by a
more recent version of the Java Runtime (class file version 61.0), this version
of the Java Runtime only recognizes class file versions up to 55.0この例では「61.0 のクラスを 55.0 までしか読めない JVM で動かした」と言っている。
まず数値を Java のバージョンに読み替える。
よくある原因
- ビルドと実行で JDK が違う: 手元は最新 JDK、サーバやコンテナは古い JRE という組み合わせが典型である。
JAVA_HOMEと IDE の実行構成がずれている: ターミナルでは通るのに IDE から実行すると落ちる、あるいはその逆になる。- 依存 jar だけが新しい: 自分のコードは古い形式でも、ロードされるライブラリが新しければそこで落ちる。
クラス名がライブラリ側のものになっていれば原因を特定しやすい。 - CI のセットアップ Java がビルドツールの設定と別: ツールチェーンで 17 を指定しているのに、実行ステップは 11 のままというケースがある。
解決策
1. 数値を Java のバージョンに読み替える
主な対応は次のとおりで、JVM 仕様書の class File Format(新しいタブで開く) に一覧がある。
52 → Java 8
55 → Java 11
59 → Java 15
61 → Java 17
65 → Java 212. 実行側の JVM を上げる
java -version
javac -version # この2つが食い違っていないかを最初に見る数値が示す Java 版以上の JVM を用意すれば、それだけで解消する。
3. 上げられないなら出力側を下げる
javac --release 11 -d out src/com/example/App.java--release は形式バージョンだけでなく、その版に存在しない標準 API の使用もコンパイル時に弾く。
古い -source / -target の組み合わせでは API の互換までは見てくれないため、--release を使うほうが安全である。
4. 原因の jar を特定する
エラーに出るクラス名が自分のコードでなければ、依存側が原因である。
バージョン表記からビルドに使われた Java 版を逆算し、そのライブラリを実行環境に合う版へ落とす。