Kotlinx.serialization: Exception is kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null')

Created on 11 Jan 2021  路  8Comments  路  Source: Kotlin/kotlinx.serialization

I'm getting Exception is kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null').

    @kotlinx.serialization.Serializable
    abstract class BaseShape

    @kotlinx.serialization.Serializable
    class Rectangle(
        val edges: Int
    ) : BaseShape()

    @kotlinx.serialization.Serializable
     internal data class Test(
        val name: String,
        val shape: BaseShape,
    )

``` kotlin
val testData = Json {
ignoreUnknownKeys = true
prettyPrint = true
}.decodeFromString(jsonString)

I'm trying to deserialize the json to get `Test` object. And here it's my json;
``` json
{ 
    "name": "Lorem Ipsum", 
    "shape": { 
        "edges": 4  
    }
}

Environment

  • Kotlin version: 1.4.21
  • Library version: 1.0.1
  • Kotlin platforms: JVM
  • Gradle version: 6.5
  • IDE version: Android Studio 4.1.1

All 8 comments

Could you please show the code how you serialize and deserialize instances of the Test class?

I've updated the issue. @shanshin

If you using an abstract class for shape polymorphic serialization then expected a special discriminator column with information about the concrete type of shape property.

e.g. for classes

    @kotlinx.serialization.Serializable
    abstract class BaseShape

    @kotlinx.serialization.Serializable
    @SerialName("Rectangle")
    class Rectangle(
        val edges: Int
    ) : BaseShape()

    @kotlinx.serialization.Serializable
     internal data class Test(
        val name: String,
        val shape: BaseShape,
    )

deserialization will be looks like

    val module = SerializersModule {
        polymorphic(BaseShape::class) {
            subclass(Rectangle::class, Rectangle.serializer())
        }
    }

val testData = Json {
            serializersModule = module
            ignoreUnknownKeys = true
            prettyPrint = true
        }.decodeFromString<Test>(jsonString)

and valid JSON is

{        
    "name": "Lorem Ipsum", 
    "shape": { 
        "type": "Rectangle", 
        "edges": 4  
    }
}

see https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism

After decodeFromString<Test>(jsonString), shape is BaseShape not Rectangle 馃槙

        val jsonString = """{        
    "name": "Lorem Ipsum", 
    "shape": { 
        "type": "Rectangle", 
        "edges": 4  
    }
}"""
        val testData = Json {
            serializersModule = module
            ignoreUnknownKeys = true
            prettyPrint = true
        }.decodeFromString<Test>(jsonString)
        println(testData.shape is Rectangle)

will prints true

Here it is the log;

2021-01-12 00:42:14.193 7283-9169/com.yekta.example I/CustomController: Test(name=Lorem Ipsum, shape=com.yekta.example.data.BaseShape@f18051d)
2021-01-12 00:42:14.193 7283-9169/com.yekta.example I/CustomController: false

com.yekta.example.data.BaseShape@f18051d

In your example BaseShape is abstract, it can't be instantiated.

Can you show the actual code for classes and deserialization?

Sorry my bad. Now, it works. Thank you @shanshin.

Was this page helpful?
0 / 5 - 0 ratings