question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.

See original GitHub issue

These codes works on 1.0.1, but on 1.1.0 it throws kotlinx.serialization.SerializationException: Serializer for class ‘Any’ is not found.

fun main() {
    val result = json.encodeToString(Encode(ClassA()))
    println(result)
}

val json = Json {
    serializersModule = SerializersModule {
        contextual(ClassA::class, ClassASerializer)
    }
}

@Serializable
data class Encode(val data: @Contextual Any)

abstract class NotSerializableClass

@Serializable(with = ClassASerializer::class)
class ClassA : NotSerializableClass() {
    fun convertTo() = ClassB()
}

@Serializable
class ClassB {
    fun convertTo() = ClassA()
}

@Serializer(forClass = ClassA::class)
object ClassASerializer : KSerializer<ClassA> {
    override val descriptor = PrimitiveSerialDescriptor("WithCustomDefault", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: ClassA) {
        encoder.encodeSerializableValue(ClassB.serializer(), value.convertTo())
    }

    override fun deserialize(decoder: Decoder): ClassA {
        return decoder.decodeSerializableValue(ClassB.serializer()).convertTo()
    }
}

Environment

  • Kotlin version: [ 1.4.30 ]
  • Library version: [ 1.1.0 ]
  • Kotlin platforms: [ Android / JVM]

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

7reactions
sandwwraithcommented, Mar 2, 2021

Hi, thanks for the report!

Unfortunately, contextual serialization was never meant to work this way. It worked due to a mistake in implementation, that was fixed in 1.1.0 (see https://github.com/Kotlin/kotlinx.serialization/pull/1277 for details). As documentation for ContextualSerializer says, 'Serializers are being looked for in a [SerializersModule] from the target [Encoder] or [Decoder], using statically known [KClass]". Here statically known KClass is Any, so it is being looked up in module instead of ClassA.

If you need to determine serializer dynamically for subtypes of Any, I suggest you to use polymorphic serialization.

If you want only serialization (because deserialization never worked in your example even in 1.0.0), I can suggest a workaround serializer for Any:

@ExperimentalSerializationApi
class DynamicLookupSerializer: 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")
    }
}
2reactions
OnwukaDanielcommented, May 30, 2022

Hi, thanks for the report! Unfortunately, contextual serialization was never meant to work this way. It worked due to a mistake in implementation, that was fixed in 1.1.0 (see #1277 for details). As documentation for ContextualSerializer says, 'Serializers are being looked for in a [SerializersModule] from the target [Encoder] or [Decoder], using statically known [KClass]". Here statically known KClass is Any, so it is being looked up in module instead of ClassA. If you need to determine serializer dynamically for subtypes of Any, I suggest you to use polymorphic serialization. If you want only serialization (because deserialization never worked in your example even in 1.0.0), I can suggest a workaround serializer for Any:

@ExperimentalSerializationApi
class DynamicLookupSerializer: 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")
    }
}

it works ~

Everyone is accepting the solution. Please tell how to use it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

"SerializationException: Serializer for class 'Any' is not found ...
Serialization : "SerializationException: Serializer for class 'Any' is not found" with map with Any parameter. Using Kotlin 1.7.10 and kotlinx.serialization ...
Read more >
kotlin - Serializer for class '...' is not found. Mark the class as ...
Mark the class as @Serializable or provide the serializer explicitly. doing call.respond(User(...)) will not throw any error. so if I remove ...
Read more >
Serializer for class is not found : r/Kotlin - Reddit
MainActivity}: kotlinx.serialization.SerializationException: Serializer for class 'Project' is not found. Any idea on what I am missing ?
Read more >
serializer - GitHub Pages
Retrieves a KSerializer for the given KClass. The given class must be annotated with Serializable or be one of the built-in types.
Read more >
Serialization | Kotlin
First, make a class serializable by annotating it with @Serializable . import kotlinx.serialization.Serializable @Serializable data class Data( ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found