ZacSweers / MoshiX

Extensions for Moshi including IR plugins, moshi-sealed, and more.
Apache License 2.0
518 stars 37 forks source link

[Android] No JsonAdapter for NestedSealed interface if R8 enabled #411

Closed proninyaroslav closed 1 year ago

proninyaroslav commented 1 year ago

Kotlin: 1.8.20 KSP: 1.8.20-1.0.10 Android libray: 8.0.0 Moshi: 1.14.0 moshi_sealed: 1.22.0

Faced the same problem again on version 0.22.0: https://github.com/ZacSweers/MoshiX/issues/324. I couldn't test this on version 0.21.0 due to a build error (https://github.com/ZacSweers/MoshiX/issues/392).

@JsonClass(generateAdapter = true, generator = "sealed:type")
sealed interface PrefWikiCharactersFilter {
    @NestedSealed
    sealed interface Name : PrefWikiCharactersFilter {
        @TypeLabel("name_unknown")
        object Unknown : Name

        @TypeLabel("name_contains")
        @JsonClass(generateAdapter = true)
        data class Contains(val nameValue: String) : Name
    }

   ....
}
Log ```console java.lang.IllegalArgumentException: No JsonAdapter for interface org.proninyaroslav.opencomicvine.data.preferences.PrefWikiCharactersFilter$Name (with no annotations) for interface org.proninyaroslav.opencomicvine.data.preferences.PrefWikiCharactersFilter$Name name for class org.proninyaroslav.opencomicvine.data.preferences.PrefWikiCharactersFilterBundle at com.squareup.moshi.Moshi$LookupChain.exceptionWithLookupStack(SourceFile:82) at com.squareup.moshi.Moshi.adapter(SourceFile:31) at org.proninyaroslav.opencomicvine.data.preferences.PrefWikiCharactersFilterBundleJsonAdapter.(SourceFile:39) at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at com.squareup.moshi.MapJsonAdapter$1.create(SourceFile:34) at com.squareup.moshi.Moshi.adapter(SourceFile:25) at com.squareup.moshi.Moshi.adapter(SourceFile:4) at org.proninyaroslav.opencomicvine.model.AppPreferencesImpl.(SourceFile:65) at org.proninyaroslav.opencomicvine.DaggerOpenComicVineApplication_HiltComponents_SingletonC$SingletonCImpl$SwitchingProvider.get(SourceFile:24) at dagger.internal.DoubleCheck.get(SourceFile:14) at org.proninyaroslav.opencomicvine.DaggerOpenComicVineApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(SourceFile:22) at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$1.create(SourceFile:631) at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(SourceFile:9) at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(SourceFile:2) at androidx.lifecycle.ViewModelProvider.get(SourceFile:13) at androidx.lifecycle.ViewModelProvider.get(SourceFile:2) at coil.util.-Logs.get(SourceFile:19) at coil.util.-Logs.viewModel(SourceFile:6) at androidx.compose.foundation.layout.RowScope$-CC.m(SourceFile:32) at org.proninyaroslav.opencomicvine.ui.MainActivity$onCreate$1.invoke(SourceFile:28) at org.proninyaroslav.opencomicvine.ui.MainActivity$onCreate$1.invoke(SourceFile:2) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:8) at coil.util.-Logs.CompositionLocalProvider(SourceFile:181) at org.proninyaroslav.opencomicvine.ui.CompositionLocalKt.AppCompositionLocalProvider(SourceFile:65) at org.proninyaroslav.opencomicvine.ui.MainActivity$onCreate$1.invoke(SourceFile:21) at org.proninyaroslav.opencomicvine.ui.MainActivity$onCreate$1.invoke(SourceFile:1) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:8) at androidx.compose.ui.platform.ComposeView.Content(SourceFile:25) at androidx.paging.HintHandler$processHint$1.invoke(SourceFile:142) at androidx.paging.HintHandler$processHint$1.invoke(SourceFile:36) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:8) at coil.util.-Logs.CompositionLocalProvider(SourceFile:181) at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(SourceFile:346) at androidx.compose.material.ButtonKt$Button$3.invoke(SourceFile:34) at androidx.compose.material.ButtonKt$Button$3.invoke(SourceFile:4) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:8) at coil.util.-Logs.CompositionLocalProvider(SourceFile:181) at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(SourceFile:522) at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:19) at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:2) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:8) at coil.util.-Logs.CompositionLocalProvider(SourceFile:181) at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:16) at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:1) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:8) at okio.Okio__OkioKt.invokeComposable(SourceFile:20) at androidx.compose.runtime.ComposerImpl.doCompose(SourceFile:133) at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(SourceFile:14) at androidx.compose.runtime.CompositionImpl.composeContent(SourceFile:19) at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(SourceFile:30) at androidx.compose.runtime.CompositionImpl.setContent(SourceFile:11) at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(SourceFile:18) at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(SourceFile:12) at androidx.compose.ui.platform.WrappedComposition.setContent(SourceFile:14) at androidx.compose.ui.platform.WrappedComposition.onStateChanged(SourceFile:19) at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(SourceFile:23) at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:107) at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(SourceFile:15) at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(SourceFile:119) at android.view.View.dispatchAttachedToWindow(View.java:21290) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3491) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3498) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2820) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2328) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9087) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239) at android.view.Choreographer.doCallbacks(Choreographer.java:899) at android.view.Choreographer.doFrame(Choreographer.java:832) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Caused by: java.lang.IllegalArgumentException: No JsonAdapter for interface org.proninyaroslav.opencomicvine.data.preferences.PrefWikiCharactersFilter$Name (with no annotations) at com.squareup.moshi.Moshi.adapter(SourceFile:30) ... 82 more ```
proninyaroslav commented 1 year ago

And after the project upgrade of after the release of Android Studio Flamingo, my old hack doesn't work even on version 0.19.0:

-keep @com.squareup.moshi.JsonClass class *
-keep @com.squareup.moshi.JsonClass interface *
ZacSweers commented 1 year ago

Can you make a minimally reproducible sample project?

proninyaroslav commented 1 year ago

I updated the dependencies in the old example and also fixed the build config that didn't allow testing then https://github.com/proninyaroslav/moshi_sealed_R8_crash The problem is reproduced in it with 0.22.0 version.

ZacSweers commented 1 year ago

There's no readme there. What are the exact steps please?

proninyaroslav commented 1 year ago

Everything is in the MainActivity.kt file. Just install the app on the device and run it, the crash will happen immediately.

ZacSweers commented 1 year ago

Figured it out, thanks for the repro. See #413, you should also be able to paste that proguard rule to work around locally for now

proninyaroslav commented 1 year ago

Works fine, thank you.