IndexOutOfBoundsException on Generics Subclass Serialization
Describe the bug
I'm trying to create a generic class called Event that takes in a generic serializable payload and can be converted into Json. I'd prefer this so I can eventually pass the code into a function that takes in an object of type Event and serializes it for a call. Something like this:
object EventPublisher {
private val client = HttpClient(CIO)
suspend fun <reified T> publish(event: Event<T>) {
client.post("http://127.0.0.1:8080/events") {
setBody(event)
}
}
}
so I can publish events of all types from my app.
To Reproduce The following is what gives the error:
@Serializable
sealed class Event<T>(
val message: String,
val payload: T
) {
@Serializable
data class UserCreated(
val user: User,
) : Event<User>(
"User created",
user
)
}
@Serializable
data class User(
val id: String,
val name: String
)
fun main() {
val user = User("id", "Alice")
println(Json.encodeToString(Event.UserCreated(user)))
}
The two following code snippets seem identical to the one above, but seem to not cause any error:
@Serializable
sealed class Event<T>(
val message: String,
val payload: T
) {
@Serializable
class UserCreated<T>(
private val user: T
) : Event<T>("StringEvent", user) where T : User
}
@Serializable
data class User(
val id: String,
val name: String
)
fun main() {
val user = User("id", "Alice")
println(Json.encodeToString(Event.UserCreated(user)))
}
@Serializable
sealed class Event<T>(
val message: String,
) {
abstract val payload: T
@Serializable
data class UserCreated(
val user: User,
) : Event<User>(
"User created"
) {
override val payload = user
}
}
@Serializable
data class User(
val id: String,
val name: String
)
fun main() {
val user = User("id", "Alice")
println(Json.encodeToString(Event.UserCreated(user)))
}
Expected behavior Compile and work just like the working examples I provided.
Environment
- Kotlin version: 1.6.10
- Kotlin platforms: JVM
- Gradle version: 7.2
- Plugin:
id("org.jetbrains.kotlin.plugin.serialization") version "1.6.20-M1" - Dependencies:
implementation(platform("io.ktor:ktor-bom:2.0.0-beta-1"))
implementation("io.ktor:ktor-client-core")
implementation("io.ktor:ktor-client-content-negotiation")
implementation("io.ktor:ktor-client-serialization")
implementation("io.ktor:ktor-client-cio")
Is the issue still actual? Can you attach stacktrace?
Here is the full code with imports:
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@Serializable
sealed class Event<T>(
val message: String,
val payload: T
) {
@Serializable
data class UserCreated(
val user: User,
) : Event<User>(
"User created",
user
)
}
@Serializable
data class User(
val id: String,
val name: String
)
fun main() {
val user = User("id", "Alice")
println(Json.encodeToString(Event.UserCreated(user)))
}
and here is the stacktrace:
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:459)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$formEncodeDecodePropertyCall$1.invoke(SerializerIrGenerator.kt:295)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$formEncodeDecodePropertyCall$1.invoke(SerializerIrGenerator.kt:288)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.serializerInstance(GeneratorHelpers.kt:919)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.serializerInstance(SerializerIrGenerator.kt:47)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.formEncodeDecodePropertyCall(GeneratorHelpers.kt:1315)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.formEncodeDecodePropertyCall(SerializerIrGenerator.kt:47)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.formEncodeDecodePropertyCall(SerializerIrGenerator.kt:288)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$generateLoad$1.invoke(SerializerIrGenerator.kt:383)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$generateLoad$1.invoke(SerializerIrGenerator.kt:324)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.contributeFunction(GeneratorHelpers.kt:69)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.contributeFunction(SerializerIrGenerator.kt:47)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.IrBuilderExtension$DefaultImpls.contributeFunction$default(GeneratorHelpers.kt:63)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator.generateLoad(SerializerIrGenerator.kt:324)
at org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen.generateLoadIfNeeded(SerializerCodegen.kt:116)
at org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen.generate(SerializerCodegen.kt:38)
at org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator$Companion.generate(SerializerIrGenerator.kt:573)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializerClassLowering.lower(SerializationLoweringExtension.kt:59)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:36)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid$DefaultImpls.visitClass(IrElementVisitorVoid.kt:44)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:55)
at org.jetbrains.kotlin.ir.declarations.IrClass.acceptChildren(IrClass.kt:60)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoidKt.acceptChildrenVoid(IrElementVisitorVoid.kt:275)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:37)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid$DefaultImpls.visitClass(IrElementVisitorVoid.kt:44)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:55)
at org.jetbrains.kotlin.ir.declarations.IrClass.acceptChildren(IrClass.kt:60)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoidKt.acceptChildrenVoid(IrElementVisitorVoid.kt:275)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:37)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid$DefaultImpls.visitClass(IrElementVisitorVoid.kt:44)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitClass(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:55)
at org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl.acceptChildren(IrFileImpl.kt:84)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoidKt.acceptChildrenVoid(IrElementVisitorVoid.kt:275)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitElement(SerializationLoweringExtension.kt:32)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid$DefaultImpls.visitPackageFragment(IrElementVisitorVoid.kt:30)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitPackageFragment(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid$DefaultImpls.visitFile(IrElementVisitorVoid.kt:37)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitFile(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid$DefaultImpls.visitFile(IrElementVisitorVoid.kt:38)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitFile(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt$runOnFileInOrder$1.visitFile(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl.accept(IrFileImpl.kt:81)
at org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoidKt.acceptVoid(IrElementVisitorVoid.kt:271)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtensionKt.runOnFileInOrder(SerializationLoweringExtension.kt:30)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationLoweringExtension.generate(SerializationLoweringExtension.kt:77)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.convertToIr$lambda-1(JvmIrCodegenFactory.kt:121)
at org.jetbrains.kotlin.psi2ir.Psi2IrTranslator.generateModuleFragment(Psi2IrTranslator.kt:88)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.convertToIr(JvmIrCodegenFactory.kt:146)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.convertToIr$default(JvmIrCodegenFactory.kt:64)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.generateModule(JvmIrCodegenFactory.kt:59)
at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.compileCorrectFiles(KotlinCodegenFacade.java:35)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.generate(KotlinToJVMBytecodeCompiler.kt:331)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:123)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:58)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:52)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:92)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:434)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:120)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:357)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally$default(IncrementalCompilerRunner.kt:299)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:159)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:80)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:622)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:100)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1713)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
I'm having the same Problem
Are there any work arounds currently?
No, nothing in particular
Duplicate of #1264