kotlinx.serialization
kotlinx.serialization copied to clipboard
Reading deserialized generic array crashes at runtime
Describe the bug
The following code crashes at runtime with the error:
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap')
at MainKt.main(Main.kt:18)
at MainKt.main(Main.kt)
To Reproduce
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@Serializable
class Blah<T>(val array: Array<T>)
@Serializable
class Foo(val blah: Blah<String>)
fun main() {
val foo1 = Foo(blah = Blah(array = arrayOf("")))
val foo2 = Json.decodeFromString<Foo>(Json.encodeToString(foo1))
val array1 = foo1.blah.array
val array2 = foo2.blah.array // <= error is here
}
Expected behavior
prints nothing (main() finishes without error)
I understand the challenge of deserializing this correctly. When Blah is deserialized, it has a KSerializer<T> but doesn't have a java.lang.Class<T> so cannot produce an accurately typed Array<T>, so produces an Array<Any?> instead which fails at runtime to cast to Array<String> (the inferred type of array2) because generic arrays on the JVM are not type-erased.
There was no IDE or compiler warning about this, nor could I find any documentation for this limitation.
Environment
- Kotlin version: 1.6.10
- Library version: 1.3.2
- Kotlin platforms: JVM
- Gradle version: 7.1
- IDE version (if bug is related to the IDE) IntellijIDEA 2021.2.4
- JRE 11.0.12