Kotlin / kotlinx.serialization

Kotlin multiplatform / multi-format serialization
Apache License 2.0
5.25k stars 616 forks source link

“Serializer for class is not found” error in Kotlin script even though @Serializable annotation is added #2617

Open unclechu opened 3 months ago

unclechu commented 3 months ago

Describe the bug

I have a simple Kotlin script (foo.kts):

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString

@Serializable
data class Foo(val a: Int, val b: String)

val str: String = Json.encodeToString(Foo(42, "test"))
println(str)

val foo: Foo = Json.decodeFromString<Foo>("{\"a\":42,\"b\":\"test\"}")
println(foo)

I start it like this:

kotlin -classpath "$(./gradlew -q printDependenciesClasspath)" ./test-kotlin-script-json.kts

Where in Gradle I have this task:

tasks.register("printDependenciesClasspath") {
  println(
    configurations.runtimeClasspath.get()
    .filter { it.name.endsWith("jar") }
    .map { file(it) }
    .joinToString(":")
  )
}

This is a bit fancy, just wanted to set the CLASSPATH and avoid constantly invoking Gradle but still have dependencies included for the script. The problem is that I keep getting this error:

kotlinx.serialization.SerializationException: Serializer for class 'Foo' is not found.
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
        at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
        at kotlinx.serialization.internal.PlatformKt.platformSpecificSerializerNotRegistered(Platform.kt:28)
        at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:134)
        at kotlinx.serialization.SerializersKt.serializer(Unknown Source)
        ...

Even though @Serializable annotation is added for the class.

Environment

sandwwraith commented 3 months ago

The answer to your question is in the second part of the exception message:

and that the serialization compiler plugin is applied.

Given that you're invoking the compiler manually, passing -Xplugin argument to it is required. Serialization compiler plugin is a separate jar that is not a part of runtime. You can find it using these coordinates: https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-serialization-compiler-plugin or in ${KOTLIN_HOME}/lib/kotlin-serialization-compiler-plugin.jar

sandwwraith commented 3 months ago

This ticket contains more information: https://youtrack.jetbrains.com/issue/KT-47384