開発 PC では動く Spring Boot のアプリが、検証サーバーで java -jar すると次のエラーで起動しませんでした。
エラー: メイン・クラスorg.springframework.boot.loader.launch.JarLauncherのロード中にLinkageErrorが発生しました
java.lang.UnsupportedClassVersionError: org/springframework/boot/loader/launch/JarLauncher 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 が古いと、Maven では次のエラーになります。
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.14.0:compile (default-compile) on project classver: Fatal error compiling: エラー: リリース・バージョン17はサポートされていません -> [Help 1]
結論:Spring Boot 3.0 以降は Java 17 以上が必須です。 起動やビルドに使われている Java が 17 未満になっています。「Java 17 を入れたはずなのに」という場合は、JAVA_HOME や PATH が古い Java を指していることがほとんどです。
躓いたポイント
環境
| 項目 | バージョン |
|---|---|
| OS | Windows 11 |
| Spring Boot | 3.5.16 / 4.1.1(両方で同じ結果) |
| ビルドに使った JDK | Eclipse Temurin 17.0.20 |
| 起動に使った JDK | Eclipse Temurin 11.0.32 |
| Maven | 3.9.16 |
起きたこと
業務システムでは、1台のサーバーで複数のアプリを動かしていて、サーバーの既定の Java が古いまま、ということがよくあります。今回も次の状態でした。
- 開発 PC:JDK 17 でビルドし、そのまま起動できる
- 検証サーバー:既存のアプリに合わせて Java 11 が入っており、
java -jarで起動すると上のエラーになる
ビルドの側でも、同じ原因で2種類のエラーを見ました。
| 状況 | エラー |
|---|---|
mvn が JDK 11 で動いている |
リリース・バージョン17はサポートされていません |
JDK 17 でコンパイル済みのクラスが target に残った状態で、JDK 11 の mvn package を実行 |
RepackageMojo has been compiled by a more recent version of the Java Runtime (class file version 61.0) |
2つ目は、コンパイルが前回の結果を使い回してスキップされ、その次の spring-boot-maven-plugin(Spring Boot 3 用のプラグイン自体が Java 17 向け)で失敗したものです。エラーの出る場所が変わるので、別の問題に見えてしまいます。
どうやって解決したか
1. エラーの数字を読む
class file version 61.0 は「このクラスは Java 17 向けに作られた」、up to 55.0 は「実行している Java は 11 なので 55 までしか読めない」という意味です。主なバージョンの対応は次のとおりです。
| Java | クラスファイルのバージョン |
|---|---|
| 8 | 52 |
| 11 | 55 |
| 17 | 61 |
| 21 | 65 |
数字を見れば「何が新しすぎて、何が古すぎるか」が分かります。
2. 実際に使われている Java を確かめる
インストールされている Java ではなく、そのコマンドが実際に使っている Java を確かめます。Windows のコマンドプロンプトでは次のとおりです。
rem 起動に使われる java
where java
java -version
rem Maven が使う java(JAVA_HOME が優先される)
mvn -v
echo %JAVA_HOME%
mvn -v の2行目以降に、Maven が使っている Java が出ます。
Apache Maven 3.9.16 (2bdd9fddda4b155ebf8000e807eb73fd829a51d5)
Java version: 11.0.32.1, vendor: Eclipse Adoptium, runtime: C:\...\jdk-11.0.32.1+1
java -version が 17 なのに mvn -v が 11、ということがよくあります。java は PATH、Maven は JAVA_HOME を見るためです。
jar の中のクラスが何向けに作られたかは、javap で確かめられます。
javap -v -cp target\classes com.example.demo.DemoApplication | findstr major
major version: 61
3. 起動とビルドに Java 17 以上を使う
サーバーの既定の Java を変えられない場合は、このアプリだけ Java 17 のフルパスで起動します。
"C:\path\to\jdk-17\bin\java" -jar app.jar
Windows のサービスや起動スクリプトから起動している場合は、その設定に書かれている Java のパスも直します。
ビルド側は JAVA_HOME を JDK 17 以上に向け、mvn clean package で前回の結果を消してからビルドし直します。
Java 17 で起動し直すと、Spring Boot 3.5.16 と 4.1.1 のどちらも起動しました。
Started DemoApplication in 0.765 seconds (process running for 1.08)
started on Java 17.0.20.1
Java 17 以上に上げられない環境では、Spring Boot 3 以降は動きません。設定で回避する方法はないので、実行環境の更新を計画に入れる必要があります。
解決できた根拠
Spring Boot 3.0 以降は Java 17 以上が必須
Spring Boot 3.0 の移行ガイドに、最初の確認事項として書かれています。
Spring Boot 3.0 requires Java 17 or later.
現行のバージョンの動作環境のページにも、同じ条件が書かれています。
Spring Boot 3.5.16 requires at least Java 17 and is compatible with versions up to and including Java 25.
Spring Boot 4.1.1 requires at least Java 17 and is compatible with versions up to and including Java 26.
61 は Java 17、55 は Java 11
Java 仮想マシンの仕様書の「Table 4.1-A. class file format major versions」に、Java のバージョンとクラスファイルのバージョンの対応表があります。Java SE 17 が 61、Java SE 11 が 55 で、各バージョンの Java は自分以下の番号のクラスファイルしか読めません。