Open
Description
Describe the bug
When i try to encode generic data to the JSON element using ContextualSerializer
, the following crash occurs
Empty list doesn't contain element at index 0.
java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0.
at kotlin.collections.EmptyList.get(Collections.kt:37)
at kotlin.collections.EmptyList.get(Collections.kt:25)
at GenericContextualTest$createJson$1$1$1.invoke(GenericContextualTest.kt:55)
at GenericContextualTest$createJson$1$1$1.invoke(GenericContextualTest.kt:55)
at kotlinx.serialization.modules.ContextualProvider$WithTypeArguments.invoke(SerializersModule.kt:231)
at kotlinx.serialization.modules.SerialModuleImpl.getContextual(SerializersModule.kt:172)
at kotlinx.serialization.modules.SerializersModule.getContextual$default(SerializersModule.kt:48)
at kotlinx.serialization.descriptors.ContextAwareKt.getContextualDescriptor(ContextAware.kt:61)
at kotlinx.serialization.json.internal.WriteModeKt.carrierDescriptor(WriteMode.kt:49)
at kotlinx.serialization.json.internal.AbstractJsonTreeEncoder.encodeSerializableValue(TreeJsonEncoder.kt:79)
at kotlinx.serialization.json.internal.TreeJsonEncoderKt.writeJson(TreeJsonEncoder.kt:21)
at kotlinx.serialization.json.Json.encodeToJsonElement(Json.kt:117)
at GenericContextualTest.should serialize contextual to JsonElement(GenericContextualTest.kt:37)
To Reproduce
import kotlinx.serialization.ContextualSerializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.modules.SerializersModule
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
class GenericContextualTest {
@Test
fun `should serialize contextual to string`() {
val json = createJson()
val serializer = createContextualSerializer(
typeArgumentSerializer = String.serializer(),
)
val actualResult = json.encodeToString(
serializer,
Box("test")
)
assertThat(actualResult).isEqualTo("\"test\"")
}
@Test
fun `should deserialize contextual from string`() {
val json = createJson()
val serializer = createContextualSerializer(
typeArgumentSerializer = String.serializer(),
)
val actualResult = json.decodeFromString(
serializer,
"\"test\""
)
assertThat(actualResult).isEqualTo(Box("test"))
}
@Test
fun `should serialize contextual to JsonElement`() {
val json = createJson()
val serializer = createContextualSerializer(
typeArgumentSerializer = String.serializer(),
)
val actualResult = json.encodeToJsonElement(
serializer,
Box("test")
)
assertThat(actualResult).isEqualTo(JsonPrimitive("test"))
}
@Test
fun `should deserialize contextual from JsonElement`() {
val json = createJson()
val serializer = createContextualSerializer(
typeArgumentSerializer = String.serializer(),
)
val actualResult = json.decodeFromJsonElement(
serializer,
JsonPrimitive("test")
)
assertThat(actualResult).isEqualTo(Box("test"))
}
fun <T> createContextualSerializer(
typeArgumentSerializer: KSerializer<T>,
): KSerializer<Box<T>> = ContextualSerializer(
serializableClass = Box::class,
fallbackSerializer = null,
typeArgumentsSerializers = arrayOf(typeArgumentSerializer),
) as KSerializer<Box<T>>
private fun createJson() = Json {
serializersModule = SerializersModule {
contextual(Box::class) { args -> BoxSerializer(args[0]) }
}
}
data class Box<T>(val contents: T)
class BoxSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<Box<T>> {
override val descriptor: SerialDescriptor = dataSerializer.descriptor
override fun serialize(encoder: Encoder, value: Box<T>) =
dataSerializer.serialize(encoder, value.contents)
override fun deserialize(decoder: Decoder) = Box(dataSerializer.deserialize(decoder))
}
}
Expected behavior
Serialization should be performed properly without crash. Deserialization works as expected
Environment
- Kotlin version: 1.9.21
- Library version: 1.6.2
- Kotlin platforms: JVM
- Gradle version: 8.5
- IDE version: Android Studio Hedgehog | 2023.1.1
- Other relevant context: Windows 10, Java 17