Gradle / AGP 8系アップデート: 直面したエラーと解決策

GradleおよびAGP(Android Gradle Plugin)を7系(7.3.0)から8系(v8.2.0)にアップグレードした際に、ビルドプロセス中にいくつかのエラーに直面しました。
AGP8.0.0には破壊的変更がいくつかありました。[release-notes](https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes
)

ここでは、発生したエラーの解決方法を記録しておきます。
この記事がいずれ同じ問題に直面した方々の参考になれば幸いです。


バージョン差分 ↓
```diff_gradle
plugins {
-  id "com.android.application" version "7.3.0" apply false
+  id "com.android.application" version "8.2.0" apply false
}
```
```diff_gradle
dependencies {
-  classpath 'com.android.tools.build:gradle:7.3.0'
+  classpath 'com.android.tools.build:gradle:8.2.0'
}
```

## プラグインのリクエストエラー

```
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.version-check'.
   > Minimum supported Gradle version is 8.2. Current version is 7.5. If using the gradle wrapper, try editing the distributionUrl in */android/gradle/wrapper/gradle-wrapper.properties to gradle-8.2-all.zip
```
### 解決策
ログに従い、バージョンを上げることで解決しました。

```diff_properties:gradle-wrapper.properties
- distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip 
```

## JDKエラー
```
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 15.
      Your current JDK is located in /Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
      You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.
```

### 解決策
AGP8.0.0以降からは、JDK17の使用が必須になりました。
app/build.gradleの設定を編集し、JDKバージョンを17に更新します。

```diff_gradle:app/build.gradle
-  compileOptions {
-       sourceCompatibility JavaVersion.VERSION_1_8
-       targetCompatibility JavaVersion.VERSION_1_8
-   }
-    
-   kotlinOptions {
-       jvmTarget = '1.8'
-   }

+   compileOptions {
+       sourceCompatibility JavaVersion.VERSION_17
+       targetCompatibility JavaVersion.VERSION_17
+   }
+    
+   kotlinOptions {
+       jvmTarget = JavaVersion.VERSION_17.toString()
+   }
```


### JDK17をインストールする（Macにインストールされていない場合）
Mac上にJDK17がない場合はインストールする必要があります。下記のコマンドを実行して自身のバージョンを確認してみてください。
```
$ java -version
>java version "15.0.1" 2020-10-20
>Java(TM) SE Runtime Environment (build 15.0.1+9-18)
>Java HotSpot(TM) 64-Bit Server VM (build 15.0.1+9-18, mixed mode, sharing)
```

MacにJDK 17がインストールされていない場合は、以下の手順でインストールします。

```
brew install openjdk@17
sudo ln -sfn $(brew --prefix)/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk
```

~/.zshrcに以下の設定を追加し、`source ~/.zshrc`を実行して更新します。

```~/.zshrc
# JDK17↲
export PATH="/usr/local/opt/openjdk@17/bin:$PATH"
export JAVA_HOME=`/usr/libexec/java_home -v "17"`
export CPPFLAGS="-I/usr/local/opt/openjdk@17/include"
```
バージョンを確認し、更新されていることが確認できればOK
```
java -version
>openjdk version "17.0.9" 2023-10-17
>OpenJDK Runtime Environment Homebrew (build 17.0.9+0)
>OpenJDK 64-Bit Server VM Homebrew (build 17.0.9+0, mixed mode, sharing)
```

ここまでの対応でデバッグビルドはできるようになりました！
ただし、リリースビルドは未だできず。。。

## リリースビルド時のR8エラー
```
ERROR: */build/app/intermediates/merged_java_res/release/base.jar: R8:
com.android.tools.r8.ResourceException: com.android.tools.r8.internal.vc: I/O exception while reading '*/build/app/intermediates/merged_java_res/release/base.jar':
```

### 解決策
この調査にめちゃくちゃ時間を費やしてしまったのですが、
[Google Issue Tracker](https://issuetracker.google.com/issues/277166577#comment6
)に解決策が書いてありました。
`whenTaskAdded`を使っている箇所があれば、`configureEach`に置き換えよとのことでした。（そんなことログには一切書かれていなかったよ😇）

```diff_gradle:app/build.gradle
- tasks.whenTaskAdded { task ->
+ tasks.configureEach { task ->
```

## Google Play Coreライブラリに関連するクラスが見つからないエラー
```
ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in */build/app/outputs/mapping/release/missing_rules.txt.
ERROR: R8: Missing class com.google.android.play.core.splitcompat.SplitCompatApplication (referenced from: void io.flutter.app.FlutterPlayStoreSplitApplication.<init>() and 5 other contexts)
Missing class com.google.android.play.core.splitinstall.SplitInstallException (referenced from: void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.lambda$installDeferredComponent$1(int, java.lang.String, java.lang.Exception))
Missing class com.google.android.play.core.splitinstall.SplitInstallManager (referenced from: com.google.android.play.core.splitinstall.SplitInstallManager io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.splitInstallManager and 5 other contexts)
Missing class com.google.android.play.core.splitinstall.SplitInstallManagerFactory (referenced from: void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.<init>(android.content.Context, io.flutter.embedding.engine.FlutterJNI))
```
ビルド中にR8最適化ツールがGoogle Play Coreライブラリに関連するクラスを見つけることができず、その結果ビルドが失敗してるみたいです。

### 解決策

#### Google Play Coreライブラリの依存関係を追加
明示的にGoogle Play Coreライブラリの依存関係を追加しました。
（Flutterプロジェクトが間接的にGoogle Play Coreライブラリを使用しているっぽい。）

```app/build.gradle
dependencies {
    implementation 'com.google.android.play:core:1.10.3'
}
```


## ついに
これでようやくリリースビルドも可能になりました！

バージョンアップに伴い、いくつかの問題に直面しましたが、これらの解決策が他の方の助けになれば幸いです。




## 参考資料
https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes

https://zenn.dev/hayato94087/articles/c0345e6c2c53e7