Closed as not planned
Closed as not planned
Description
Describe the bug
I'm running into an issue where I need to use a JsonContentPolymorphicSerializer
on a nested sealed class. The children of the nested sealed class share the same top level discriminator, and are differentiated by their content.
To Reproduce
@Serializable
sealed class Base {
@Serializable
@SerialName("a")
data class A(val value: Int) : Base()
@Serializable(with = InnerBase.Companion::class)
@SerialName("b")
sealed class InnerBase : Base() {
@Serializable
data class D(val value: Int) : InnerBase()
@Serializable
data class E(val value: Int) : InnerBase()
companion object : JsonContentPolymorphicSerializer<InnerBase>(InnerBase::class) {
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<InnerBase> {
return if ("foo" in element.jsonObject) {
D.serializer()
} else {
E.serializer()
}
}
}
}
}
class NestedCustomSerializerTest {
val json = Json { }
@Test
fun `test deserialize D`() {
val actual = json.decodeFromString<Base>(
"""{
"type": "b",
"foo": 1,
"value": 2
}""".trimMargin()
)
assertEquals(Base.InnerBase.D(2), actual)
}
@Test
fun `test deserialize A`() {
val actual = json.decodeFromString<Base>(
"""{
"type": "a",
"value": 7
}""".trimMargin()
)
assertEquals(Base.A(7), actual)
}
}
When running test deserialize D
I get the following error:
kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 0: Serializer for subclass 'b' is not found in the polymorphic scope of 'Base' at path: $
Check if class with serial name 'b' exists and serializer is registered in a corresponding SerializersModule.
To be registered automatically, class 'b' has to be '@Serializable', and the base class 'Base' has to be sealed and '@Serializable'.
JSON input: {
"type": "b",
"foo": 1,
"value": 2
}
at app//kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
at app//kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:32)
at app//kotlinx.serialization.json.internal.AbstractJsonLexer.fail(AbstractJsonLexer.kt:598)
at app//kotlinx.serialization.json.internal.AbstractJsonLexer.fail$default(AbstractJsonLexer.kt:596)
at app//kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:85)
at app//kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
Expected behavior
The JSON is deserialized to Base.InnerBase.D(2)
.
Environment
- Kotlin version: 1.9.23
- Library version: 1.6.3
- Kotlin platforms: JVM (Android)
- Gradle version: 8.6
Metadata
Metadata
Assignees
Labels
No labels