開発 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.0 Migration Guide

現行のバージョンの動作環境のページにも、同じ条件が書かれています。

Spring Boot 3.5.16 requires at least Java 17 and is compatible with versions up to and including Java 25.

— System Requirements(3.5)

Spring Boot 4.1.1 requires at least Java 17 and is compatible with versions up to and including Java 26.

— System Requirements(4.1)

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 は自分以下の番号のクラスファイルしか読めません。

参考