2

I'm trying to replace the default Javalin JSON serializer Jackson by Kotlinx.serialization.

The documentation show how to do it with GSON serializer.
Unfortunately kotlinx serializer has a different function signature and I can't figure out how to pass arguments through.

Serialization is OK but deserialization with decodeFromString function require to be passed a type given by the mapping function as targetClass.

I'm stuck here:

val kotlinx = Json { coerceInputValues = true }
    
JavalinJson.toJsonMapper = object : ToJsonMapper {
    override fun map(obj: Any): String = kotlinx.encodeToString(obj)
}
    
JavalinJson.fromJsonMapper = object : FromJsonMapper {
    override fun <T> map(json: String, targetClass: Class<T>): T = kotlinx.decodeFromString(json)
}

But I get: Cannot use 'T' as reified type parameter. Use a class instead.

I also tried:

JavalinJson.fromJsonMapper = object : FromJsonMapper {
    override inline fun <reified T> map(json: String, targetClass: Class<T>): T = kotlinx.decodeFromString(json)
}

But I get a warning: Override by an inline function and an error: Override by a function with reified type parameter.

I'm new to kotlin and I'm struggling understanding what's wrong with this override.

Freezystem
  • 4,494
  • 1
  • 32
  • 35

1 Answers1

2

Try this one:

JavalinJson.toJsonMapper = object : ToJsonMapper {
    override fun map(obj: Any): String {
        val serializer = serializer(obj.javaClass)
        return kotlinx.encodeToString(serializer, obj)
    }
}

JavalinJson.fromJsonMapper = object : FromJsonMapper {
    override fun <T> map(json: String, targetClass: Class<T>): T {
        @Suppress("UNCHECKED_CAST")
        val deserializer = serializer(targetClass) as KSerializer<T>
        return kotlinx.decodeFromString(deserializer, json)
    }
}
  • Thanks a lot, it looks better than before. I'm always getting some errors though. `Serializer for class 'Any' is not found`. The problem is that `serializer(targetClass)` returns a `KSerializer` and not a `KSerializer`. – Freezystem Oct 09 '20 at 20:18
  • I tried `val deserializer: KSerializer = serializer()` that seems more appropriate but I'm having the `reified` issue again.. – Freezystem Oct 09 '20 at 20:28
  • Seems, this error is related to `toJsonMapper`. Edited answer, added this one too. – Михаил Нафталь Oct 09 '20 at 20:42
  • Now I get this error: `Serializer for class 'GenericResponse' is not found. Mark the class as @Serializable or provide the serializer explicitly` which is better because `GenericResponse` is my serialized data class. The strange thing is that this class is already tagged as `Serializable`. – Freezystem Oct 09 '20 at 21:17
  • Are you sure you added Kotlin Serialization compiler plugin to your project? – Михаил Нафталь Oct 10 '20 at 07:31
  • yes I followed the setup procedure of kotlinx README.md and add `kotlin("plugin.serialization") version "1.4.10"` to plugins and `implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0")` to dependencies – Freezystem Oct 10 '20 at 07:45
  • Are you sure you are using `kotlinx.serialization.Serializable`, not `java.io.Serializable`? – Михаил Нафталь Oct 10 '20 at 08:12
  • Can't reproduce in JVM... What platform are you targeting? – Михаил Нафталь Oct 10 '20 at 09:21
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222814/discussion-between-freezystem-and--). – Freezystem Oct 10 '20 at 09:38