Thread
#serialization
    d

    Daniele B

    1 year ago
    I would like to serialize this class:
    @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:
    val req = RpcRequest("2.0",2342,"getData",listOf("erwrwee",{"encoding":"base64"}))
    How can it be properly serialized?
    itnoles

    itnoles

    1 year ago
    What is @Contextual?
    d

    Daniele B

    1 year ago
    I just put it there, thinking it would work, but it doesn’t
    Robert Jaros

    Robert Jaros

    1 year ago
    Is it compile or runtime error? It does compile for me without error.
    d

    Daniele B

    1 year ago
    @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.
    Robert Jaros

    Robert Jaros

    1 year ago
    And do you provide a
    Serializer
    for
    Any
    within your
    Json
    instance?
    This is working for me:
    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

    Daniele B

    1 year ago
    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:
    @SerialName("params") val params : JsonArray?,
    Moritz Post

    Moritz Post

    1 year ago
    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

    CLOVIS

    1 year ago
    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.