kotlinx.serialization
kotlinx.serialization copied to clipboard
Error in deserialize function for parameterized abstract and sealed classes
Describe the bug Errors occurred when trying to deserialize instances for parameterized abstract and sealed classes.
To Reproduce
@Serializable
sealed class TypedSealedClass<T>(val a: T) {
@Serializable
data class Child(val y: Int) : TypedSealedClass<Int>(10)
}
and try to deserialize it
val child = Json.encodeToString(TypedSealedClass.serializer(Int.serializer()), TypedSealedClass.Child(10))
Json.decodeFromString(TypedSealedClass.serializer(Int.serializer()), child)
For JVM backend error occurred
java.lang.NoSuchFieldError: typeSerial0
at com.jetbrains.example.serialization.MainTest$TypedSealedClass$Child$$serializer.deserialize(Project.kt)
at com.jetbrains.example.serialization.MainTest$TypedSealedClass$Child$$serializer.deserialize(Project.kt:23)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:63)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:51)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:32)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:73)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:33)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:85)
...
for JVM IR
e: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$serializerInstance$1.invoke(GeneratorHelpers.kt:623)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$serializerInstance$1.invoke(GeneratorHelpers.kt:622)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.serializerInstance(GeneratorHelpers.kt:639)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.serializerInstance(SerializerIrGenerator.kt:45)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.serializerInstance(GeneratorHelpers.kt:616)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.serializerInstance(SerializerIrGenerator.kt:45)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$generateSave$1.invoke(SerializerIrGenerator.kt:540)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$generateSave$1.invoke(SerializerIrGenerator.kt:236)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.contributeFunction(GeneratorHelpers.kt:55)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.contributeFunction(SerializerIrGenerator.kt:45)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.generateSave(SerializerIrGenerator.kt:236)
at org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen.generateSaveIfNeeded(SerializerCodegen.kt:109)
at org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen.generate(SerializerCodegen.kt:37)
...
same for abstract classes
Expected behavior deserialize finished successfully
Environment
- Kotlin version: 1.4.30-M1
- Library version: 1.0.1
- Kotlin platforms: JVM, JVM IR
Got the same exception both on JVM-IR and JS-IR during compillation.
Also https://youtrack.jetbrains.com/issue/KT-43910
https://youtrack.jetbrains.com/issue/KT-49660
This is still an issue in "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0" in combination with Kotlin 1.7.10 and Java 17.
This is still an issue in "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0" in combination with Kotlin 1.7.10 and Java 17.
What if working with other versions of kotlin? Are there any workarounds at currently?
There's an easy workaround, the goal is to get rid of concrete property in parent class:
Change
@Serializable
sealed class TypedSealedClass<T>(val a: T) {
@Serializable
data class Child(val y: Int) : TypedSealedClass<Int>(10)
}
Into
@Serializable
sealed class TypedSealedClass<T>() {
abstract val a: T
@Serializable
data class Child(val y: Int) : TypedSealedClass<Int>() {
@EncodeDefault override val a: Int = 10
}
}
There's an easy workaround, the goal is to get rid of concrete property in parent class:
Change
@Serializable sealed class TypedSealedClass<T>(val a: T) { @Serializable data class Child(val y: Int) : TypedSealedClass<Int>(10) }
Into
@Serializable sealed class TypedSealedClass<T>() { abstract val a: T @Serializable data class Child(val y: Int) : TypedSealedClass<Int>() { @EncodeDefault override val a: Int = 10 } }
It works. Thanks a lot.