Gradleでビルドすると'Task :resolveMainClassName FAILED'で失敗する

こんにちは。

この記事を閲覧しているということはエラーメッセージをピンポイントで検索したと思われますので、細かい話は抜きにして早速見ていきましょう。

# 環境
自分の環境はこちらです。

:::note info
Gradle：v8.10.2
Java：__Amazon Corretto v23.0.1_8__
SpringBoot：v3.2.2
IDE：IntelliJ IDEA 2024.1.4 (Community Edition)
:::
後述しますがJava22以降で同様の現象が起こるようです。
IDEやGradleではなくJavaのバージョンが強く影響していました。
　

# エラーメッセージ
```powershell
PS C:\Users\User\IdeaProjects\sample-project> gradle build                                                                                                                                  
> Task :resolveMainClassName FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':resolveMainClassName'.
> Unsupported class file major version 67

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.10.2/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 2s
3 actionable tasks: 3 executed
PS C:\Users\User\IdeaProjects\sample-project>
```
　

# 暫定的な解決策
`build.gradle`に以下の記述を追記することで回避できるようです。
```gradle:build.gradle
springBoot {
    mainClass = 'com.example.ExampleApplication'
}

// 当然こちらでもOK
springBoot.mainClass = 'com.example.ExampleApplication'
```
　

# 解説
まずはエラーメッセージを読みます。
```powershell
* What went wrong:
Execution failed for task ':resolveMainClassName'.
> Unsupported class file major version 67
```
`resolveMainClassName`タスクでエラーが発生したことを示しています。
このタスクはクラスファイルのメジャーバージョン67をサポートしていないようです。
　

## クラスファイルのメジャーバージョンって？
`javap -v [classファイルのパス]`で確認できます。
```powershell
PS C:\Users\User> javap -v C:\Users\User\IdeaProjects\sample-project\build\classes\java\main\net\hollage\sampleproject\domain\Sample.class
Classfile /C:/Users/User/IdeaProjects/sample-project/build/classes/java/main/net/hollage/sampleproject/domain/Sample.class
  Last modified 2024/11/07; size 136 bytes
  SHA-256 checksum xxxxxxd6a6c201e8e150cff228c957b372b1abd9d588ec36309d771a06235b61
  Compiled from "Sample.java"
public interface net.hollage.sampleproject.domain.Sample
  minor version: 0
  major version: 67
  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
  this_class: #1                          // net/hollage/sampleproject/domain/Sample
  super_class: #3                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 0, attributes: 1
Constant pool:
  #1 = Class              #2              // net/hollage/sampleproject/domain/Sample
  #2 = Utf8               net/hollage/sampleproject/domain/Sample
  #3 = Class              #4              // java/lang/Object
  #4 = Utf8               java/lang/Object
  #5 = Utf8               SourceFile
  #6 = Utf8               Sample.java
{
}
SourceFile: "Sample.java"
PS C:\Users\User>
```
ここでいう`major version: 67`がメジャーバージョンに当たり、
簡単に書くと `- 44` したものがJavaのバージョンになる･･･ようです。
自分はJava23を利用しているので`67 - 44 = 23`となります。
詳しくは [ひしだま's 技術メモページ](https://www.ne.jp/asahi/hishidama/home/tech/java/version.html) などを参考にしてください。

なので`Unsupported class file major version 66`と出た方はJava22を使っているのでしょう。
　

# 恒久的な解決策
__ないです！！！__

こちらの [SpringBootのissue](https://github.com/spring-projects/spring-boot/issues/40074) を投稿したSpringプロジェクトメンバーのwilkinsonaによると、
```
2024-3-24
Not at this time, I'm afraid. Please use the workaround for now.
（残念だけど現時点では対応予定はないよ。回避策を利用してね。）
```
とのこと。
22, 23はLTSじゃないですし、完全に回避したい方は21にダウングレードするしかなさそう。