【Android】Facebook SDKのバージョンを上げるとKotlinバージョンの互換関連でビルドエラーする、この原因が分からない
環境
- Mac Big Sur 11.6
- Android Studio Bumblebee | 2021.1.1 Patch 2
- Kotlin 1.3.72
- Gradle 6.7.1
- AGP 4.2.2
現象
com.facebook.android:facebook-android-sdk
を 11.1.1 から 11.2.0 に上げた。
するとアプリのビルド :app:kaptGenerateStubsDebugKotlin でエラー。
/<user>/.gradle/caches/transforms-2/files-2.1/55c601fdc50ab3a141360952a3160eb8/jetified-kotlin-stdlib-jdk8-1.5.10.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.16.
とりあえずのワークアラウンドとそのエラー
facebook-android-sdk と同じになるよう、Kotlinバージョンを 1.5.10 に上げた。
そうしたら別のところ、:app:compileDebugKotlin でエラー。
Your current kotlinx.serialization core version is too low, while current Kotlin compiler plugin 1.4.20 requires at least 1.0-M1-SNAPSHOT. Please update your kotlinx.serialization runtime dependency.
@Serializable を使うための kotlinx-serialization がバージョン古いらしい。正確には変えたKotlinバージョンに対応してない。
実際のバージョンは以下。
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
ちなみに Gradle バージョン上げろというのがstack overflowにあったけど、試したら最初のエラーのままだった。
Just go to gradle-wrapper.properties and change this line
kotlinx.serialization をマイグレーション
kotlinx-serialization-core より kotlinx-serialization-json の方が使いやすそう?使い方わかるので、そっちを使用。
before
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
after
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0"
コード上でシリアライズ箇所は適宜メソッド置き換え。
これで一旦ビルドエラーは解消した。
公式ソースは調べきれてないが、(少なくとも)Kotlin 1.4.10 からは kotlinx-serialization-runtime はバージョン上げないといけないらしい↓。
多分マイグレーション必要なのは、正確には Kotlin 1.4.0 からだと思う。
↓ kotlinx-serialization が 1.0.0 RC に上がるときに、Kotlinバージョンを 1.3.70 → 1.4.0 に上げている。
結局原因はなんなの?→よく分からない
facebook-android-sdk をバージョンアップしたことがきっかけで、あちこちバージョンを上げて解決した。
けれどそもそものエラー↓はどうして発生したのか?
/<user>/.gradle/caches/transforms-2/files-2.1/55c601fdc50ab3a141360952a3160eb8/jetified-kotlin-stdlib-jdk8-1.5.10.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.16.
プロジェクトでのKotlinバージョンは 1.3.72 なので、(古いが)このエラーで言われている 1.1.16 とは関係なさそう。
facebook-android-sdk の該当バージョン(1.1.1 → 1.2.0)への更新差分は以下。
ここで 1.5.10 に上げてる。kotlinx-serialization-runtime はこのKotlinバージョンに何か影響される? のか?
実際、:app:kaptGenerateStubsDebugKotlin で下記のワーニング出てるので、調べきれてないもののそんな感じっぽい。
w: Runtime JAR files in the classpath should have the same version. These files were found in the classpath:
追記
./gradlew app:dependencies
で確認(今回のエラー前、つまりFacebook SDKのバージョン上げる前の状態)。
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.31
まだ見方がよくわかってないけど、Gradleの推移的依存関係により、ライブラリ達はプロジェクトのKotlinバージョンより高いのを参照していた↑。
参考: http://kkoudev.github.io/blog/2014/03/30/gradle-tips/
Mavenの場合は推移的依存関係における階層が高い方が優先されます。 しかしGradleでは、バージョンが一番高いものが優先されます。
これが facebook-android-sdk を上げたことで、他のライブラリも Kotlin 1.5.10 が参照されるようになった。
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.10 (*)
それで kotlin-stdlib-jdk8 などがKotlin 1.5系の変更に対応してなくてビルドエラーしたのか?
/<user>/.gradle/caches/transforms-2/files-2.1/55c601fdc50ab3a141360952a3160eb8/jetified-kotlin-stdlib-jdk8-1.5.10.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.16.
知りたいこと
- 推移的依存関係により一番高いバージョンを参照しないようにexclude?する方法
- 一番高いバージョンを指定してしまっているライブラリは誰か確認する方法
- このエラー起きる前、kotlin-stdlib-jdk8 が Kotlin 1.1.16 を期待していたようだが、それはどこに書かれているのか?