SerializationException {message: "Serializer for c...
# serialization
k
SerializationException {message: "Serializer for class 'ArrayList' is not found.\nPle…at the serialization compiler plugin is applied.\n", cause: undefined, name: 'SerializationException' Any idea ?
Copy code
val experienceWidgetList:MutableList<Any> = mutableListOf()
val jsonString = Json.encodeToString(Utils.AnySerializer(),experienceWidgetList)
Copy code
@OptIn(InternalSerializationApi::class)
@ExperimentalSerializationApi
class AnySerializer: KSerializer<Any> {
    override val descriptor: SerialDescriptor = ContextualSerializer(Any::class, null, emptyArray()).descriptor

    override fun serialize(encoder: Encoder, value: Any) {
        val actualSerializer = encoder.serializersModule.getContextual(value::class) ?: value::class.serializer()
        encoder.encodeSerializableValue(actualSerializer as KSerializer<Any>, value)
    }

    override fun deserialize(decoder: Decoder): Any {
        error("Unsupported")
    }
}
g
MutableList<T> (it's an ArrayList on JVM) is not supported, you generally want to serialize List<T> instead. I presume your AnySerializer is an attempt to generally solve the serialization descriptor, so just a couple of things to share: • there's an extension that allow you to write
Json.encodeToString(value)
(no need to specify the serializer) • getting the serializer automatically is not a good generalisation of the problem : you can have 1 class that extends a sealed class (polymorphism), if you encode the class with the class serializer, you will get a different result that if you encode the class with the sealed class serializer (polymorphism requires a class discriminator field).
k
@glureau so what to do then I want to serialize list of any here ?
want to convert it to string
g
Have you defined a polymorphism on Any? What's your goal exactly?
k
Okay so Im making List<Any> right and Any is generallyt widgets which has some properties like padding:Int or if any object/ class than its also serilizable then I want to convert this list to string. how can I do that
Have you defined a polymorphism on Any? by this you mean ? Serilizer for Any here is that
Copy code
@OptIn(InternalSerializationApi::class)
@ExperimentalSerializationApi
class AnySerializer: KSerializer<Any> {
    override val descriptor: SerialDescriptor = ContextualSerializer(Any::class, null, emptyArray()).descriptor

    override fun serialize(encoder: Encoder, value: Any) {
        val actualSerializer = encoder.serializersModule.getContextual(value::class) ?: value::class.serializer()
        encoder.encodeSerializableValue(actualSerializer as KSerializer<Any>, value)
    }

    override fun deserialize(decoder: Decoder): Any {
        error("Unsupported")
    }
}
g
Serializer does the job to do the transformation. Defining a polymorphism means you define how the all kotlinxserialization is setup when dealing with polymorphic objects. Usually you can define an interface Vehicle (for example) and some implementations of it, then you describe the serializerModule with this kind of config:
Copy code
val json = Json {
    serializersModule = SerializersModule {
        polymorphic(Vehicle::class) {
            subclass(Truck::class)
            subclass(Tesla::class)
        }
    }
}
So that later, if you do json.decode<Vehicle>(jsonString), Kotlinx will search for a class denominator then take the subclass that matches, then parse the rest of the data to create the right Vehicle.
Have you tested the output of your AnySerializer with a List<> ?
k
yes same it throws same error
g
Serializer for class 'ArrayList'
was in your initial error, I believe with List<> you should have another error
k
oky let me check. thanks for your help man
Serializer for class 'EmptyList' is not found.\nPle…at the serialization compiler plugin is applied.\n When I use List<Any> this is the error
g
Yep makes sense if your list is empty and you still use your AnySerializer. This is exactly why using a serializer from the class is not recommended. Here the List is implemented by some class (if empty -> EmptyList), then the serializer tries to find how to serialize this class, but there's no default serialization for this class. There's one default for List<> but you're not using it.
k
Can you share some snippet wrt. So I'm new in this
g
I'd advise to first define your interface Widget, then: • if you define all subclasses of this interface in the same module use
sealed interface Widget
, the polymorphism will be enabled by default • if you use multiple modules, then define your polymorphism with all the classes you want to use like in my previous snippet. Then use
json.encodeToString<Widget>(myWidgetInstance)
and this should work fine.
If you want to serialize a List, I presume you can do that json.encodeToString<List<Widget>>(...) but I'm not really sure (as you'll mix different instances in the list)
But in all cases, remove your AnySerializer
k
See here it takes actual class and actual serializable but in your case it doesn't, do I'm importing something different
g
You're missing those imports:
Copy code
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
k
finally thanks my man
working now : )
👍 1