Kotlin - Cannot serialize polymorphic classes. No serializer found

Viewed 3693

I am trying to serialize polymorphic classes using kotlinx.serialization with kotlin/native. I am using the sample provided in the serialization guide:

val module = SerializersModule {
    polymorphic(Project::class) {
        subclass(OwnedProject::class)
    }
}

val format = Json { serializersModule = module }

@Serializable
abstract class Project {
    abstract val name: String
}
            
@Serializable
@SerialName("owned")
class OwnedProject(override val name: String, val owner: String) : Project()

fun main() {
    val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
    println(format.encodeToString(data))
} 

This code works when run with JVM, but when compiled and run with kotlin native for linuxX64 it throws an error:

Uncaught Kotlin exception: kotlinx.serialization.SerializationException: Serializer for class 'Project' is not found. Mark the class as @Serializable or provide the serializer explicitly.
    at kfun:kotlin.Throwable#<init>(kotlin.String?){} (0x294767)
    at kfun:kotlin.Exception#<init>(kotlin.String?){} (0x28ea25)
    at kfun:kotlin.RuntimeException#<init>(kotlin.String?){} (0x28e725)
    at kfun:kotlin.IllegalArgumentException#<init>(kotlin.String?){} (0x28e925)
    at kfun:kotlinx.serialization.SerializationException#<init>(kotlin.String?){} (0x350185)
    at kfun:kotlinx.serialization.internal#serializerNotRegistered@kotlin.reflect.KClass<*>(){}kotlin.Nothing (0x36fa0d)
    at kfun:kotlinx.serialization#serializer@kotlin.reflect.KClass<0:0>(){0§<kotlin.Any>}kotlinx.serialization.KSerializer<0:0> (0x3505c8)
    at kfun:kotlinx.serialization.serializer$serializerByKTypeImpl#internal (0x3512d2)
    at kfun:kotlinx.serialization#serializer(kotlin.reflect.KType){}kotlinx.serialization.KSerializer<kotlin.Any?> (0x3503c8)
    ...

Do I understand it incorrectly, that the code should be working on both platforms ? How to make it work on native ?

3 Answers

As i found out from github issues its current limitation.

It is a current limitation that should be properly documented (cc @qwwdfsad ). Please try format.encodeToString(PolymorphicSerializer(Project::class), data). In case of sealed classes, it should work. If it doesnt, simply use format.encodeToString(Project.serializer(), data)

You missed to declare serializer for the OwnedProject class while define as subclass of SerializersModule.

val module = SerializersModule {
        polymorphic(Project::class) {
            subclass(OwnedProject::class, OwnedProject.serializer()) // add here OwnedProject class serializer
        }
    }
Related