I would like to serialize this class: ```@Serializ...
# serialization
d
I would like to serialize this class:
Copy code
@Serializable
data class RpcRequest(
  @SerialName("jsonrpc") val jsonrpc : String,
  @SerialName("id") val id : Int,
  @SerialName("method") val method : String,
  @SerialName("params") val params : List<@Contextual Any>?,
)
where
params
could be a list of any kind of object I currently get this error:
Serializer for class 'Any' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
An example of RpcRequest object:
Copy code
val req = RpcRequest("2.0",2342,"getData",listOf("erwrwee",{"encoding":"base64"}))
How can it be properly serialized?
i
What is @Contextual?
d
I just put it there, thinking it would work, but it doesn’t
r
Is it compile or runtime error? It does compile for me without error.
d
@Robert Jaros it is a runtime error
@Robert Jaros to be precise: In case I don’t annonate with
@Contextual
, I get a compile error:
Serializer has not been found for type 'Any'. To use context serializer as fallback, explicitly annotate type or property with @Contextual
If I annotate with
@Contextual
, I get a runtime error:
Serializer for class 'Any' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
r
And do you provide a
Serializer
for
Any
within your
Json
instance?
This is working for me:
Copy code
object JsonAnySerializer : KSerializer<Any> {
    override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.Any")

    override fun deserialize(decoder: Decoder): Any {
        return decoder.decodeString()
    }

    override fun serialize(encoder: Encoder, value: Any) {
        encoder.encodeString(value.toString())
    }
}

val json = Json {
            serializersModule = serializersModuleOf(Any::class, JsonAnySerializer)
}

json.encodeToString(RpcRequest("a", 2, "b", listOf("ABC", 5)))
Of course the serializer would need to be way more advanced to deserialize anything successfully 😉
d
thanks @Robert Jaros for illustrating this! I also found another way to encode a list, using `JsonArray`: https://kotlin.github.io/kotlinx.serialization/kotlinx-serialization-json/kotlinx-ser[…]ation-json/kotlinx.serialization.json/-json-array/index.html
so the params field would become:
Copy code
@SerialName("params") val params : JsonArray?,
m
There is an issue hoovering around the same problem but with no concrete solution as of yet https://github.com/Kotlin/kotlinx.serialization/issues/746
The
Any
type should be supported by for basic types imo
c
It is by design that you can't deserialize Any: https://github.com/Kotlin/kotlinx.serialization/issues/8 You must always explicitly tell the deserializer which class you expect. This is also why interfaces are not supported, but sealed classes are.