java.lang.UnsupportedClassVersionError の修正:より新しいJavaランタイムでコンパイルされたクラス

beginner Java2026-05-14| Java(JDK/JRE)、Linux / macOS / Windows、任意のJavaアプリケーションまたはSpring Boot / Maven / Gradleプロジェクト

Error Message

java.lang.UnsupportedClassVersionError: com/example/MyClass has been compiled by a more recent version of the Java Runtime
#java#バージョン#jdk#jre

何が起きたのか

JARをデプロイし、クラスを実行するか、サーバーを起動した瞬間、JVMが以下のエラーをスローしました:

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/example/MyClass 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

Javaはコンパイルされたすべての.classファイルにバージョン番号を埋め込みます。そのファイルを読み込むJREが、コンパイルに使われたJDKより古い場合、このエラーが発生します。JVMは推測しません——クラスのロードを完全に拒否します。

バージョン番号を解読する

エラーメッセージにはクラスファイルバージョンが含まれています。Javaリリースとの対応表:

  • 45.0 → Java 1
  • 52.0 → Java 8
  • 55.0 → Java 11
  • 56.0 → Java 12
  • 57.0 → Java 13
  • 58.0 → Java 14
  • 59.0 → Java 15
  • 60.0 → Java 16
  • 61.0 → Java 17
  • 62.0 → Java 18
  • 63.0 → Java 19
  • 64.0 → Java 20
  • 65.0 → Java 21

つまりclass file version 61.0は、そのクラスがJava 17でコンパイルされたことを意味しますが、ランタイムは55.0(Java 11)までしか対応していません。バージョンの不一致が確定です。

診断:実際のバージョンを確認する

実行中のJREを確認する

java -version

出力例:

openjdk version "11.0.20" 2023-07-18
OpenJDK Runtime Environment (build 11.0.20+8)
OpenJDK 64-Bit Server VM (build 11.0.20+8, mixed mode)

コンパイルに使われたJDKを確認する

javac -version

javacが17で、javaが11——このギャップが問題の原因です。

クラスファイルを直接検査する

javap -verbose com/example/MyClass.class | grep "major version"

クラスを実行せずに、クラスファイルの正確なバージョンを出力します。

Linux:インストール済みのJDKをすべて確認する

update-alternatives --list java
# または
ls /usr/lib/jvm/

修正方法1 — JREをアップグレードする(推奨)

JARを再コンパイルできない場合は?サードパーティライブラリやCIビルドの成果物では一般的なケースです。対象マシンのJREを、コンパイルに使われたバージョンに合わせてアップグレードしましょう。

Ubuntu / Debian

sudo apt install openjdk-17-jdk
sudo update-alternatives --config java

macOS(Homebrew)

brew install openjdk@17
export JAVA_HOME=$(brew --prefix openjdk@17)
export PATH="$JAVA_HOME/bin:$PATH"

Windows

adoptium.netから対応するJDKをダウンロードしてインストールし、システム環境変数のJAVA_HOMEPATHを更新してください。

確認する

java -version
# 17.x以上が表示されるはずです

修正方法2 — 古いJavaバージョンをターゲットに再コンパイルする

ソースコードを持っている場合は、--releaseを使ってランタイムがサポートするバージョン向けにコンパイルダウンしましょう。

javacを直接使用する

javac --release 11 com/example/MyClass.java

Maven(pom.xml)

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

またはコンパイラープラグインを使用する場合:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.11.0</version>
  <configuration>
    <release>11</release>
  </configuration>
</plugin>

Gradle(build.gradle)

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

Gradle 6.7以降ではツールチェーンが導入されました——バージョンを固定するより明確な方法です:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(11)
    }
}

Spring Bootプロジェクト

# application.propertiesまたはpom.xmlのプロパティ
<java.version>11</java.version>

その後、再ビルドします:

./mvnw clean package
# または
./gradlew build

修正方法3 — 実行時に正しいJVMを指定する

複数のJDKがインストールされている場合は、システムデフォルトを完全に無視してフルパスを指定します:

/usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar myapp.jar

または実行前にJAVA_HOMEを設定します:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
java -jar myapp.jar

システムデフォルトを変更したくないCI/CDパイプラインやDockerコンテナで重宝します。

よくあるシナリオ:ベースイメージが間違っているDockerコンテナ

コンテナ化されたアプリでは頻繁に発生します。DockerfileがJava 17でコンパイルされたJARを実行するのにopenjdk:11を使用している場合——バージョンが最初から一致していません。

# 誤り
FROM openjdk:11-jre-slim
COPY target/myapp.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
# 正しい — コンパイルターゲットに合わせる
FROM eclipse-temurin:17-jre-alpine
COPY target/myapp.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

確認手順

  • JREのバージョンがコンパイルターゲット以上であることを確認する:``` java -version
  - 再コンパイルした場合、新しいクラスファイルのバージョンを確認する:```
javap -verbose target/classes/com/example/MyClass.class | grep "major version"
  • アプリケーションを実行して、UnsupportedClassVersionErrorが出なければ完了です:``` java -jar target/myapp.jar
  - Dockerの場合:コンテナを再ビルドして実行し、起動ログを確認する。

## 得られた教訓

  - **CI/CDでJavaバージョンを固定する。**パイプラインがJava 21でコンパイルし、本番環境がJava 11で動いている——このエラーはデプロイのたびに発生します。両方を同じバージョンに固定して、ずれが生じないようにしましょう。
  - **`-source`/`-target`ではなく`--release`を使う。**古いフラグはバイトコードバージョンを設定するだけです。Java 11に存在しないJava 17のAPIを呼び出しても止めてくれません。`--release`はバイトコードバージョンとAPI利用可能性の両方を強制します。
  - **サードパーティJARを確認する。**エラーが常に自分のコードを指しているわけではありません。スタックトレースに記載されたクラスに対して`javap -verbose`を実行し、どの依存関係から来たものかを特定してから、そのライブラリの最低Java要件を確認しましょう。
  - **GradleツールチェーンとMavenラッパーは「自分の環境では動く」問題を解消します。**ローカルに何がインストールされているかに関わらず、宣言されたJavaバージョンでビルドが行われることを保証します。

Related Error Notes