qh.i: Class 'j' is not registered for polymorphic serialization in the scope of 'h0'.
See original GitHub issueDescribe 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:
- Created a year ago
- Reactions:1
- Comments:8 (1 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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.
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:
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.