Kotlinx.serialization: Qualifiers for a Lint Contextual

Created on 31 Aug 2020  Â·  4Comments  Â·  Source: Kotlin/kotlinx.serialization

Describe the bug (or maybe feature)
I am using a dependency injector for singleton initialization Json {}.
I am setting frequent contextual() for popular types in my project.
I am getting an important warning about unknown types.

Serializer has not been found for type 'ZonedDateTime'. To use context serializer as fallback, explicitly annotate type or property with @Contextual

Although my type is declared at a higher level.

To Reproduce

        Json {
            serializersModule = SerializersModule {
                contextual(ZonedDateTime::class, DateSerializer())
            }
        }
@Serializable
data class Entity(
    @SerialName("date") val date: ZonedDateTime? = null
) {

Expected behavior
I understand perfectly well that magic does not exist, and it is necessary to solve this problem with additional code.
I am thinking of some kind of dependency compileOnly. Possibly embedded additional code that will be automatically removed via R8.
My idea is Qualifiers. Setting up qualifiers at a high level. Like IntDef in Android annotations. The programmer creates his own annotation qualifiers and annotates the classes.

Environment

  • Kotlin version: [e.g. 1.4.0]
  • Library version: [e.g. 1.0.0-RC]
  • Kotlin platforms: [e.g. Android]
  • Gradle version: [e.g. 6.2]
  • IDE version (maybe bug is related to the IDE) [Android Studio 4.0.1]
question

Most helpful comment

Yeah, because it's a new one :)

Hm, it seems that I slightly misunderstood you. If you do not need to determine serializer in runtime dynamically, then you don't need module at all. It is indeed better to use @Serializable(DateSerializer::class) or @file:UseSerializers(...) because they wire serializers directly in compile time, without additional runtime lookup in serializersModule.

All 4 comments

Hi,
This is not an important warning, this is a compiler error.
By default, the context is not used at all, so compiler complains that no serializer is defined, and therefore such class is not serializable.
The actual 'additional code' you mentioned is already there — when you're using @Contextual, compiler inserts code that instructs framework to search for the serializer in your serializersModule.

If you're unhappy that there's a lot of @Contextual annotations, I'd suggest you to take a look at the @file:UseContextualSerialization annotation (https://kotlin.github.io/kotlinx.serialization/kotlinx-serialization-core/kotlinx-serialization-core/kotlinx.serialization/-use-contextual-serialization/index.html)

Hi,
This is not an important warning, this is a compiler error.
By default, the context is not used at all, so compiler complains that no serializer is defined, and therefore such class is not serializable.
The actual 'additional code' you mentioned is already there — when you're using @Contextual, compiler inserts code that instructs framework to search for the serializer in your serializersModule.

If you're unhappy that there's a lot of @Contextual annotations, I'd suggest you to take a look at the @file:UseContextualSerialization annotation (https://kotlin.github.io/kotlinx.serialization/kotlinx-serialization-core/kotlinx-serialization-core/kotlinx.serialization/-use-contextual-serialization/index.html)

Oh. material very very little.

@Contextual looks good. But won't this affect performance? Perhaps someone measured it? Are there official guidelines Contextual vs @Serializable(DateSerializer::class)?

Yeah, because it's a new one :)

Hm, it seems that I slightly misunderstood you. If you do not need to determine serializer in runtime dynamically, then you don't need module at all. It is indeed better to use @Serializable(DateSerializer::class) or @file:UseSerializers(...) because they wire serializers directly in compile time, without additional runtime lookup in serializersModule.

I think you got it right. These were 2 different questions. Many thanks.

Was this page helpful?
0 / 5 - 0 ratings