question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Polymorphic serialization: properties named "type" are not serialized with a unique key

See original GitHub issue

Describe the bug When using the polymorphic serializer, if a class has a property called type, it will be serialized with two keys called type – one with the class name, and one with the value of the class property.

To Reproduce

class SampleTests {
    @Serializable
    abstract class Base

    @Serializable
    data class Derived(val type: String) : Base()

    @Test
    fun test() {
        val j = Json {
            serialModule = SerializersModule {
                polymorphic(Base::class) {
                    addSubclass(Derived.serializer())
                }
            }
        }

        val derived = Derived("string")
        val stringified = j.stringify(Base.serializer(), derived)
        val parsed = j.parse(Base.serializer(), stringified) // throws

        assertEquals(
            derived,
            parsed
        )
    }
}

Expected behavior An error should be emitted that the key type is reserved, with instructions to use SerialName. It could also be useful to allow the discriminator property name to be configurable

Environment

  • Kotlin version: [1.3.30]
  • Library version: [0.11.0]
  • Kotlin platforms: [e.g. JVM, JS, and Native]
  • Gradle version: [e.g. 5.4]

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
sandwwraithcommented, May 17, 2019

Discriminator name is configurable, see in JsonConfiguration class

0reactions
SerVBcommented, Nov 27, 2019

Now sealed classes are supported automatically and there is the same problem:

package com

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration

@Serializable
sealed class Base

@Serializable
data class Child(val type: String) : Base()

object Tmp {

  @JvmStatic
  fun main(args: Array<String>) {
    val json = Json(JsonConfiguration.Stable)

    val child = Child("1")

    val string = json.stringify(Base.serializer(), child)
    println(string)

    val parsed = json.parse(Base.serializer(), string)

    println(parsed)
  }
}

The output:

{"type":"com.Child","type":"1"}
Exception in thread "main" kotlinx.serialization.SerializationException: 1 is not registered for polymorphic serialization in the scope of class com.Base
	at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:99)
	at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.access$throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:1)
	at kotlinx.serialization.internal.AbstractPolymorphicSerializer.findPolymorphicSerializer(AbstractPolymorphicSerializer.kt:83)
	at kotlinx.serialization.SealedClassSerializer.findPolymorphicSerializer(SealedSerializer.kt:92)
	at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:41)
	at kotlinx.serialization.json.internal.StreamingJsonInput.decodeSerializableValue(StreamingJsonInput.kt:33)
	at kotlinx.serialization.CoreKt.decode(Core.kt:80)
	at kotlinx.serialization.json.Json.parse(Json.kt:126)
	at com.Tmp.main(Tmp.kt:24)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Deserializing polymorphic types with Jackson based on the ...
You could write a custom deserializer that uses @JsonSubTypes ' "name" and "value" properties in a non-standard way to accomplish what you want....
Read more >
How to serialize properties of derived classes with System ...
In this article. Serialize properties of derived classes; Polymorphic type discriminators; Configure polymorphism with the contract model ...
Read more >
SerialDescriptor - Kotlin
The structure of the serializable type is not only the property of the type, ... Serial descriptor is identified by its name and...
Read more >
Serialization Tutorial - GitHub Pages
This section of the C# Driver Tutorial discusses serialization (and deserialization) of ... To not serialize default values using attributes write:
Read more >
User Guide Genson - Fast and easy to use Java and Scala to ...
During serialization if there is no type information available (meaning it is Object), Genson will use the runtime type of the object to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found