Open6

【Android】Facebook SDKのバージョンを上げるとKotlinバージョンの互換関連でビルドエラーする、この原因が分からない

mrky125mrky125

環境

  • 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.
mrky125mrky125

とりあえずのワークアラウンドとそのエラー

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

https://stackoverflow.com/questions/67448034/module-was-compiled-with-an-incompatible-version-of-kotlin-the-binary-version

mrky125mrky125

kotlinx.serialization をマイグレーション

https://github.com/Kotlin/kotlinx.serialization/blob/1.0.0-RC/docs/migration.md
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 はバージョン上げないといけないらしい↓。
https://qiita.com/Teramonte4/items/041c792339d28189a787

多分マイグレーション必要なのは、正確には Kotlin 1.4.0 からだと思う。
↓ kotlinx-serialization が 1.0.0 RC に上がるときに、Kotlinバージョンを 1.3.70 → 1.4.0 に上げている。
https://github.com/Kotlin/kotlinx.serialization/commit/f0a6546284a630a45f6ca3b5deb8ea35c321a917

mrky125mrky125

結局原因はなんなの?→よく分からない

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)への更新差分は以下。
https://github.com/facebook/facebook-android-sdk/compare/sdk-version-11.1.1...sdk-version-11.2.0
↑の差分で気になるのはKotlinバージョンの更新。

ここで 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:
mrky125mrky125

追記

./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.
mrky125mrky125

知りたいこと

  • 推移的依存関係により一番高いバージョンを参照しないようにexclude?する方法
  • 一番高いバージョンを指定してしまっているライブラリは誰か確認する方法
  • このエラー起きる前、kotlin-stdlib-jdk8 が Kotlin 1.1.16 を期待していたようだが、それはどこに書かれているのか?