◀ 3.

java.lang.UnsupportedClassVersionError の原因と対処 (JDK バージョン違い)

▶
この記事の要点
  • java.lang.UnsupportedClassVersionError は実行する Java より新しい Java でコンパイルしたクラスを読み込んだときに出る
  • エラー中の数字は「クラスファイルのバージョン」。52 = Java 8、55 = Java 11、61 = Java 17、65 = Java 21、69 = Java 25
  • 対処は 2 通り: 実行側の Java を上げるか、ビルド時のターゲットを下げる(--release)
  • 「java -version と javac -version が違う」「Tomcat や IDE が別の JDK を使っている」が典型的な原因
  • javap -v でクラスファイルのバージョン、java -version で実行側を確認して突き合わせる

エラー内容

実行する Java のバージョンによって、メッセージの形が 2 種類あります。

# 古い Java(Java 8 以前)で実行した場合
java.lang.UnsupportedClassVersionError: com/example/Main : Unsupported major.minor version 55.0

# 新しい Java で実行した場合
java.lang.UnsupportedClassVersionError: com/example/Main has been compiled by a more recent version
of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes
class file versions up to 61.0

どちらも意味は同じで、「このクラスは自分より新しい Java 向けに作られているので読み込めない」という意味です。Web アプリでは、jar や war をサーバーにデプロイしてアクセスしたとき、またはアプリの起動時に発生します。

原因: コンパイルした Java と実行する Java のバージョン違い

Java のソースを javac でコンパイルすると、.class ファイルの先頭に「クラスファイルのバージョン(major version)」が書き込まれます。JVM は自分が対応しているバージョンより大きい番号のクラスを読み込めないため、このエラーで停止します。

つまり、サーバーの JRE のバージョンより新しいバージョンでビルドした jar をデプロイすると起きるエラーです。逆に、古い Java でコンパイルしたクラスを新しい Java で動かすのは基本的に問題ありません。

エラー中の数字と Java バージョンの対応表

class file versionJava バージョン備考
50Java 6
51Java 7
52Java 8LTS。古いサーバーで今も多い
55Java 11LTS
61Java 17LTS。Spring Boot 3 系の最低要件
65Java 21LTS
69Java 25LTS(2025 年 9 月リリース)

規則は「Java のバージョン + 44 = class file version」です。たとえば「class file version 61.0 … only recognizes up to 52.0」なら、Java 17 でビルドしたものを Java 8 で動かそうとしている、と読めます。

対処法 1: 実行側の Java を新しくする

ビルドに使った Java と同じか、それより新しい Java で実行すれば解決します。ライブラリやフレームワークが新しい Java を前提にしている場合(例: Spring Boot 3 は Java 17 以上が必要)は、この方法しかありません。

  • コマンドラインのアプリ: JAVA_HOME と PATH を新しい JDK に向ける
  • Tomcat: JAVA_HOME または JRE_HOME(bin/setenv.sh などで設定)を新しい Java に変える
  • Docker: ベースイメージを eclipse-temurin:21-jre のように合ったバージョンにする

対処法 2: ビルド時のターゲットを下げる

サーバーの Java を変えられない場合は、古い Java 向けにコンパイルします。JDK 9 以降の --release オプションを使うと、クラスファイルのバージョンと使える標準 API の両方を指定バージョンに合わせてくれます。

# Java 21 の JDK で、Java 8 で動くクラスを作る
javac --release 8 -d out src/com/example/Main.java

Maven では pom.xml に次のように書きます(maven-compiler-plugin 3.6 以降で有効)。

<properties>
    <maven.compiler.release>11</maven.compiler.release>
</properties>

Gradle ではツールチェーンか options.release で指定します。

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}
// または
tasks.withType(JavaCompile).configureEach {
    options.release = 11
}

Eclipse では、プロジェクトのプロパティ →「Java コンパイラー」の「コンパイラー準拠レベル」を実行環境に合わせます。IntelliJ IDEA では Project Structure の SDK と Language level、Maven / Gradle 側の設定を揃えます。

注意点として、-source / -target だけを下げる古い方法では、新しい Java にしかない API を使ってもコンパイルが通ってしまい、実行時に NoSuchMethodError になることがあります。可能な限り --release を使ってください。

よくある落とし穴

  • java と javac のバージョンが違う: PATH 上に複数の JDK があり、javac は 21、java は 8 を指している
  • IDE は動くのにサーバーで落ちる: IDE 内蔵の JDK でビルドし、サーバーは古い JRE で動いている
  • 依存ライブラリが新しい: 自分のコードを --release 8 にしても、依存 jar が Java 11 以上向けだとそのライブラリのクラスで同じエラーになる。ライブラリのバージョンを下げるか、実行環境を上げる
  • Maven 自体を動かす JDK: mvn -v に表示される Java が、想定した JDK と違うことがある
  • CI とローカルの差: CI のビルドイメージの JDK が更新され、気づかないうちにターゲットが上がる

確認方法

# 実行側の Java バージョン
java -version

# コンパイラのバージョン
javac -version

# クラスファイルのバージョンを確認(major version: 61 なら Java 17)
javap -v com/example/Main.class | grep major

# jar の中のクラスを確認する場合
unzip -o app.jar com/example/Main.class -d /tmp/chk
javap -v /tmp/chk/com/example/Main.class | grep major

Windows のコマンドプロンプトでは grep の代わりに findstr major を使います。javap が示す major version が、実行側の Java が対応する番号(上の表)以下になっていれば解決です。

関連

子ページ

子ページはありません

同階層のページ
  1. java.lang.NoSuchMethodError
  2. java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
  3. java.lang.UnsupportedClassVersionError
  4. version less than X.X is not supported.
  5. パッケージ~は存在しません
  6. org.apache.jasper.JasperException: ...The jsp:param action must not be...
  7. java.io.FileNotFoundException: ファイル名 (許可がありません)
  8. java.sql.SQLException: Cannot convert value 'YYYY-MM-DD ...' from column n(YYYY-MM-DD ...) to TIMESTAMP.
  9. 警告: この文字は、エンコーディング[文字コード]にマップできません
  10. java.text.ParseException: Unparseable date
  11. Unsupported major.minor version 52.0
  12. エンティティ" ... "への参照は';'デリミタで終了する必要があります。
  13. java.math.BigDecimal cannot be cast to java.lang.String

最近更新/作成されたページ