question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

qh.i: Class 'j' is not registered for polymorphic serialization in the scope of 'h0'.

See original GitHub issue

Describe the bug

After building the app in the release variant polymorphic serialization doesn’t work.

To Reproduce

SocketEvent.kt

@Serializable
sealed interface SocketEvent

AnalyticsEvent.kt

@Serializable
sealed interface AnalyticsEvent : SocketEvent {
    @Serializable
    data class PlayerState(
        @SerialName("player_state") val playerState: State,
     ) : AnalyticsEvent

    @Serializable
    data class ButtonClick(
        @SerialName("screen_name") val screenName: String,
     ) : AnalyticsEvent
}

SocketConnectionEvent.kt

@Serializable
sealed class SocketConnectionEvent(
    @SerialName("event") open val event: String,
) : SocketEvent {

    @Serializable
    class PingEvent : SocketConnectionEvent(
        event = SocketEventName.PING.event
    )
}

WebSocketClient.kt

override suspend fun send(event: SocketEvent) {
        val trimmed = event.trimType()
        session?.run {
            sendSerialized(trimmed)
        } ?: Timber.e("No session")
    }

    /**
     * As kotlinx-serialization adds type discriminator to serialized object we need to trim it.
     * See: https://github.com/Kotlin/kotlinx.serialization/issues/464
     */
    private fun SocketEvent.trimType(): JsonElement {
        val json = Json.encodeToJsonElement(this) // <- here we get the Exception
        val valuesWithoutType = json.jsonObject.filterNot { it.key == "type" }
        return Json.encodeToJsonElement(valuesWithoutType)
    }

Proguard configuration

# Keep `Companion` object fields of serializable classes.
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
    static <1>$Companion Companion;
}

# Keep `serializer()` on companion objects (both default and named) of serializable classes.
-if @kotlinx.serialization.Serializable class ** {
    static **$* *;
}
-keepclassmembers class <2>$<3> {
    kotlinx.serialization.KSerializer serializer(...);
}

# Keep `INSTANCE.serializer()` of serializable objects.
-if @kotlinx.serialization.Serializable class ** {
    public static ** INSTANCE;
}
-keepclassmembers class <1> {
    public static <1> INSTANCE;
    kotlinx.serialization.KSerializer serializer(...);
}

# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault

Expected behavior

Object serialization works for release build as it works for debug

Environment

  • Kotlin version: 1.7.10
  • Library version: 1.4.0
  • Kotlin platforms: JVM
  • Gradle version: 7.5.1
  • Android Gradle Plugin: 7.4.0-beta02

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
bubenheimercommented, Oct 13, 2022

So to wrap this up as far as R8 fullMode goes, I suggest adding the following to the sample Proguard in the README. It should not hurt or change anything when not using R8 fullMode, yet without these rules, running fullMode is borked.

-keep, allowoptimization, allowobfuscation class kotlinx.serialization.Serializable { *; }

-if @kotlinx.serialization.Serializable class **
-keep, allowshrinking, allowoptimization, allowobfuscation class <1>

There is more context in the linked Android issuetracker reference.

Edit: based on the update to the R8 FAQ, the least restrictive rule would actually be as follows, but this one only works for R8 users, it sounds like Proguard would show an error:

-if @kotlinx.serialization.Serializable class **
-keep, allowshrinking, allowoptimization, allowobfuscation, allowaccessmodification class <1>
1reaction
bubenheimercommented, Oct 8, 2022

I just ran into this same problem, except I even have a custom serializer on the base class to eclipse the polymorphism. So it seems that the custom serializer is lost entirely as well, despite using the standard recommended Proguard config from the kotlinx.serialization repo. Or at least this is what I think the error implies. (I use R8.)

The custom serializer class is still there, but it seems like it is not being used, as if the annotation parameter had gone missing or did not get obfuscated the same way.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Kotlin Serialization issues: Class is not registered for ...
SerializationException : Class 'CustomConvertible' is not registered for polymorphic serialization in the scope of 'Convertible'.
Read more >
Class 'ArrayList' is not registered for polymorphic serialization ...
I get runtime exception as shown. import kotlinx.serialization.* import kotlinx.serialization.json.
Read more >
2004-April.txt - Python mailing list
Answer : the > >>method signature should not change because polymorphic calls would be > >>greatly endangered. The base class defines the signature...
Read more >
Polymorphic serialization doesn't work for deeper sealed class ...
Class 'Department' is not registered for polymorphic serialization in the scope of 'Component'. Mark the base class as 'sealed' or register ...
Read more >
https://huggingface.co/Sentdex/GPyT/commit/9983190...
... :3585,"ĠGNU":3586,"TYPE":3587,"poly":3588,"Ġ23":3589,"ĠPEP":3590,"HO":3591 ... Ġbi":5234,"orld":5235,"Proxy":5236,"Ġcodes":5237,"lineno":5238,"NOT":5239 ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found