Skip to content

Contextual serializers do not work for derived classes #1276

@martinraison

Description

@martinraison

Describe the bug

It seems contextual serializers only work for concrete classes currently.

To Reproduce

Example setup:

@Serializable
abstract class Message

@Serializable
class SimpleMessage(val body: String) : Message()

@Serializable
class Holder(@Contextual val message: Message)

// A custom serializer for Message
object MessageAsStringSerializer : KSerializer<Message> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("kotlinx.serialization.MessageAsStringSerializer", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: Message) {
        // dummy serializer that assumes Message is always SimpleMessage
        check(value is SimpleMessage)
        encoder.encodeString(value.body)
    }

    override fun deserialize(decoder: Decoder): Message {
        return SimpleMessage(decoder.decodeString())
    }
}

val module = SerializersModule {
    contextual(MessageAsStringSerializer)
}
val format = Json { serializersModule = module }

Now when we try to do this

val data = Holder(SimpleMessage("hello"))
println(format.encodeToString(data))

we get the following error:

Class 'SimpleMessage' is not registered for polymorphic serialization in the scope of 'Message'.
Mark the base class as 'sealed' or register the serializer explicitly.
kotlinx.serialization.SerializationException: Class 'SimpleMessage' is not registered for polymorphic serialization in the scope of 'Message'.
Mark the base class as 'sealed' or register the serializer explicitly.

Expected behavior

In the scenario above, the message field of the Holder class should be serialized using MessageAsStringSerializer.

Environment

  • Kotlin version: 1.4.20
  • Library version: 1.0.1
  • Kotlin platforms: JVM
  • Gradle version: 6.7.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions