Android Studio にて、 Jetpack Compose の @Preview アノテーションを使ってプレビューをしたかったのだが、エラーが出て表示されない。
java.lang.NoClassDefFoundError: _layoutlib_/_internal_/kotlinx/datetime/serializers/InstantIso8601Serializer
at com.natsuneko.catalyst.models.CatalystStatus$$serializer.deserialize(CatalystStatus.kt:13)
at com.natsuneko.catalyst.models.CatalystStatus$$serializer.deserialize(CatalystStatus.kt:13)
at _layoutlib_._internal_.kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at _layoutlib_._internal_.kotlinx.serialization.json.Json.decodeFromString(Json.kt:149)
at com.natsuneko.catalyst.models.mocks.MockedCatalystStatus.mocked_delegate$lambda$0(CatalystStatus.kt:93)
at _layoutlib_._internal_.kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:86)
at com.natsuneko.catalyst.models.mocks.MockedCatalystStatus$Companion.getMocked(CatalystStatus.kt:8)
at com.natsuneko.catalyst.ui.parts.TimelineStatusKt.TimelineStatusPreview(TimelineStatus.kt:26)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at androidx.compose.ui.tooling.ComposableInvoker.invokeComposableMethod(ComposableInvoker.jvm.kt:185)
at 略
Caused by: java.lang.ClassNotFoundException: _layoutlib_._internal_.kotlinx.datetime.serializers.InstantIso8601Serializer
... 87 more
どうやらクラスが無いと言われている様子だが、ライブラリも build.gradle.kts で定義しているしなぁ、と考えていたら、依存関係のミスがあった。
具体的には、ライブラリ側では次のような形で依存を定義していた:
// @build.gradle.kts dependencies { // ... // Kotlinx Serialization implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") // DateTime implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1") }
そして、 Android プロジェクト側では、次のように定義していた:
# @libs.versions.toml [libraries] kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version = "0.7.1" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.10.0" }
// @build.gradle.kts dependencies { // ... 略 implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) implementation(files("../../CatalystSDK/packages/kotlin/build/libs/catalyst-kotlin-0.1.0.jar")) }
ポイントは org.jetbrans.kotlinx.kotlinx-datetime のバージョン違いで、 kotlinx-datetime の 0.7.0 にて破壊的変更があり、該当クラスが無くなったことが影響している様子。
なので、解決策としては:
- ライブラリ側のバージョンを上げる
- Android プロジェクト側のバージョンを下げる
のどちらか。
バージョンを下げるという選択肢はあまりとりたくないので、ライブラリ側のバージョンを上げることで解決する。 といっても、一番の諸悪の根源は jar を直接指定していることが原因な気がする (依存関係が使われない) ので、 git submodule とかで同一リポジトリ内にすべてを含める方が、 Gradle にサブプロジェクトとして認識させられて、解決する気がする......。 ということで、ビルド時/プレビュー時の依存関係のバージョンには気をつけましょう、という記事でした。つらい。