Skip to content

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

@dawidhyzy

Description

@dawidhyzy

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions