kotlinx.serialization: Regression when serialize wrapped Any type property annotated with @Contextual
Describe the bug
Kotlin version: 1.4.0 + kotlinx-serialization-core:1.0.0-RC) + @Contextual val data: Any? reports:
Exception in thread “main” kotlinx.serialization.SerializationException: Serializer for class ‘Any’ is not found.
But when (Kotlin version: 1.3.70 + kotlinx-serialization-runtime:0.20.0), @ContextualSerialization val data: Any? works fine.
To Reproduce
@Serializable
abstract class Box(
var code: String,
var msg: String?
){
constructor(): this(OK, null)
companion object{
const val OK = "OK"
}
}
@Serializable
//data class DataBox(@ContextualSerialization val data: Any?) : Box(OK,null) //kotlin 1.3.70
data class DataBox(@Contextual val data: Any?) : Box(OK,null) //kotlin 1.4.0
{
constructor(): this(null)
}
fun test3(){
val json = Json{}
//val str = json.stringify(DataBox.serializer(),DataBox(data = Person("Tom"))) //kotlin 1.3.70, ouput: {"code":"OK","msg":null,"data":{"name":"Tom"}}
val str = json.encodeToString(DataBox.serializer(),DataBox(data = Person("Tom")))// kotlin 1.4.0: Execption!!!
println(str)
}
reports error:
Exception in thread “main” kotlinx.serialization.SerializationException: Serializer for class ‘Any’ is not found. Mark the class as @Serializable or provide the serializer explicitly. at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:127) at kotlinx.serialization.ContextualSerializer.serialize(ContextualSerializer.kt:52) at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:223) at kotlinx.serialization.encoding.Encoder$DefaultImpls.encodeNullableSerializableValue(Encoding.kt:296) at kotlinx.serialization.json.JsonEncoder$DefaultImpls.encodeNullableSerializableValue(JsonEncoder.kt) at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeNullableSerializableValue(StreamingJsonEncoder.kt:15) at kotlinx.serialization.encoding.AbstractEncoder.encodeNullableSerializableElement(AbstractEncoder.kt:94) at DataBox.write$Self(main.kt) at DataBox$$serializer.serialize(main.kt) at DataBox$$serializer.serialize(main.kt:32) at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:223) at kotlinx.serialization.json.Json.encodeToString(Json.kt:73) at MainKt.test3(main.kt:138)
Expected behavior Expect the behavior of 1.4.0 + 1.0.0-RC same as one of 1.3.70 + 0.20.0
Environment
- Kotlin version: 1.4.0
- Library version: 1.0.0-RC
- Kotlin platforms: JVM
- Gradle version: 6.3
- IDE version: IntellijIDEA 2020.2.1 Other relevant context : MacOS 10.12.6, JDK 1.8.0_261
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 24 (2 by maintainers)
Commits related to this issue
- Mention fallback serializer Fixes #1019 — committed to Kotlin/kotlinx.serialization by qwwdfsad 4 years ago
- Fix "docs needed" tagged issues (#1079) * Document exception safety of encoding * More cautious warning for KClass.serializer() * Mention that serializer() is not platform-agnostic * Document fall... — committed to Kotlin/kotlinx.serialization by qwwdfsad 4 years ago
I’m using Map<String, Any> for the feedback purposes where attributes could be any. But in the new version, I cannot use that anymore 👎
How do I use either Contextual or Polymorphic for Map<String, Any?>?
It would be much better for me to still use
Anyin data classes, but if there is no other way I will have to useJsonElement.Is it possible to write a custom serializer for
Anytype? I’ve tried, and it’s easy to implement a serialize method, but in deserialize method I don’t see any way to determine what’s the type of deserialized json element.I think using T is a good idea as following. What a pity call.respond in ktor doesn’t support generic for now. (https://github.com/ktorio/ktor/issues/2013)
@VincentJoshuaET
Map<String, @Contextual @RawValue Any>In my case,
Anycould beString,IntorDouble.I tried just now, it does not work, same error:
But it works with @Contextual: