I am trying to make a simple server which gives serialized List in JSON. The List to be serialized is the example in the official blog post's Polymorphic serialization section.
But with the ktor's serialization feature, I get the following exception.
21:53:25.536 [nioEventLoopGroup-4-1] ERROR ktor.application - Unhandled: GET - /
java.lang.IllegalStateException: Serializing collections of different element types is not yet supported. Selected serializers: [DirectMessage, BroadcastMessage]
at io.ktor.serialization.SerializerLookupKt.elementSerializer(SerializerLookup.kt:71)
Since sealed class is a key feature to choose Kotlin, I really wonder why this is not supported.
Are there any good reasons for ktor-serialization not supporting this? Or should I post an issue for removing this check from SerializerLookup.kt?
I made this code by choosing New Project > Kotlin > Application in IntelliJ. The modified code is shown below.
My server.kt:
import io.ktor.application.*
import io.ktor.features.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.serialization.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.serialization.Serializable
@Serializable
sealed class Message {
abstract val content: String
}
@Serializable
data class BroadcastMessage(override val content: String) : Message()
@Serializable
data class DirectMessage(override val content: String, val recipient: String) : Message()
val data: List<Message> = listOf(
DirectMessage("Hey, Joe!", "Joe"),
BroadcastMessage("Hey, all!")
)
fun main() {
embeddedServer(Netty, port = 8080, host = "127.0.0.1") {
install(ContentNegotiation) {
json()
}
routing {
get("/") {
call.respond(data)
}
}
}.start(wait = true)
}
My build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.4.10"
application
kotlin("plugin.serialization") version "1.4.10"
}
group = "com.example.ktor.serialization"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
jcenter()
maven {
url = uri("https://dl.bintray.com/kotlin/ktor")
}
maven {
url = uri("https://dl.bintray.com/kotlin/kotlinx")
}
}
dependencies {
testImplementation(kotlin("test-junit5"))
implementation("io.ktor:ktor-server-netty:1.4.1")
implementation("io.ktor:ktor-html-builder:1.4.1")
implementation("io.ktor:ktor-serialization:1.4.1")
implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0")
implementation("ch.qos.logback:logback-classic:1.2.3")
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "11"
}
application {
mainClassName = "ServerKt"
}
As said in the stacktrace
this is not supported yet.
, so it might come someday.However, a workaround is still possible for such a case. The issue is from Ktor, not Kotlinx Serialization. So, you can serialize your data as JSON, and then send them as a response, like here: