kotlinktorkotlinx.serialization

Serializer for class '...' is not found. Mark the class as @Serializable or provide the serializer explicitly


I have a problem with the serialization of a class in Kotlin.

build.gradle.kt

...
plugins {
    application
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.serialization").version("1.6.21")
}
...
dependencies{
...
    implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
} 

Response.kt

import kotlinx.serialization.*
...
interface BaseResponse<T>

@Serializable
data class PaginatedResponse<T>(
    val prev: Int?,
    val next: Int?,
    val totalCount: Int = 0,
    val totalPages: Int = 0,
    val data: T? = null,
    val message: String? = null
) : BaseResponse<T>

usage

...
  return PaginatedResponse<List<User>>(
                prev,
                next,
                totalCount,
                totalPages,
                users
            )

The data I am passing looks quite healthy enter image description here and the error that is thrown when the return is reached is:

kotlinx.serialization.SerializationException: Serializer for class 'PaginatedResponse' is not found. Mark the class as @Serializable or provide the serializer explicitly.

Doing call.respond(User(...)) will not throw any error

so if I remove generic and make the PaginatedResponse non generic it will work but is not reusable anymore

@Serializable
data class PaginatedResponse(
    val prev: Int?,
    val next: Int?,
    val totalCount: Long = 0,
    val totalPages: Long = 0,
    val data: List<User>? = null,
    val message: String? = null
) : BaseResponse<User>

Solution

  • after reading some documentation I found that the error in my case was mainly due to two misconfigurations that I had:

    first: I needed to add the plugin in the gradle at the app and project level, I solved this as follows: adding in gradle.project the next line: id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.21'

    As is seen in the following image: gradle.module

    and after that, adding in the gradle.app the next line in the plugins block : id 'kotlinx-serialization'

    As is seen in the following image: gradle.app

    secondly, the problem was that when the classes were serialized at runtime, the proguard generated conflicts, for this I had to add a few lines to the file proguard-rules.pro project tree

    And add the following lines into the file:

    ### your config ....
    
    # Keep `Companion` object fields of serializable classes.
    # This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
    -if @kotlinx.serialization.Serializable class **
    -keepclassmembers class <1> {
       static <1>$Companion Companion;
    }
    
    # Keep `serializer()` on companion objects (both default and named) of serializable classes.
    -if @kotlinx.serialization.Serializable class ** {
       static **$* *;
    }
    -keepclassmembers class <2>$<3> {
       kotlinx.serialization.KSerializer serializer(...);
    }
    
    # Keep `INSTANCE.serializer()` of serializable objects.
    -if @kotlinx.serialization.Serializable class ** {
       public static ** INSTANCE;
    }
    -keepclassmembers class <1> {
       public static <1> INSTANCE;
       kotlinx.serialization.KSerializer serializer(...);
    }
    
    # @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
    -keepattributes RuntimeVisibleAnnotations,AnnotationDefault
    

    As is seen in the following image:  file proguard-rules.pro

    I finally synced the gradle, compiled again and everything worked fine.

    Reference documentation: https://github.com/Kotlin/kotlinx.serialization#gradle-with-plugins-block