类的序列化器' ...'找不到。将类标记为@serializable或明确提供序列化器

发布于 2025-01-24 01:33:58 字数 1647 浏览 4 评论 0原文

我在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")
} 

响应.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>

使用

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

我所传递的数据看起来很健康 以及达到返回时丢弃的错误是:

kotlinx.Serialization.SerializationException:“ PaginedResponse”类的序列化器。 将类标记为@serializable或明确提供序列化器。

call.respond(user(...))不会丢任何错误,

因此,如果我删除通用并使paginedresponse non generic non generic可以使用,但不再可重复使用

@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>

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

北城半夏 2025-01-31 01:33:58

阅读了一些文档后,我发现我案件中的错误主要是由于我有两个错误的配置:

first :我需要在应用程序中的gradle中添加插件和项目级别,我解决了以下内容:
添加 gradle.project 下一行:
id'org.jetbrains.kotlin.plugin.serialization'版本'1.6.21'

如下图:

之后,添加 gradle.app 插件中的下一行 block block:id'kotlinx-serialization'

如下图所示:

其次 ,问题是,当课程在运行时序列化时,Proguard会产生冲突,为此,我必须在文件proguard-rules.pro

并将以下行添加到文件中:

### 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>
lt;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

如下图所示:

我终于同步了Gradle,再次编译,一切都很好。

参考文档: https://github.com/kotlin/kotlin/kotlin/kotlinx.serialization#serialization#serialization#ulialization# gradle-with-plugins-block

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>
lt;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

拒绝两难 2025-01-31 01:33:58

只有实现库是不够的,您仍然需要插件。因此,我们需要以下所有以下内容:

app/build.gradle:

1 实现(“ org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0”)

2 2 plugins {id {id“ org” org。 jetbrains.kotlin.plugin.serialization“}

build.gradle:

3 plugins {id“ org.jetbrains.kotlin.kotlin.plugin.serialization.serialization”版本“ 1.8.20” 1.8.20“ apply false false}

Only implementation library is not enough, you still need the plugin. Therefore we need all belowings:

app/build.gradle:

1 implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")

2 plugins { id "org.jetbrains.kotlin.plugin.serialization" }

build.gradle:

3 plugins { id "org.jetbrains.kotlin.plugin.serialization" version "1.8.20" apply false}

世界和平 2025-01-31 01:33:58

对我个人而言,在使用类型安全性的撰写过程中,我会遇到此错误。我有一个带有参数的数据类,例如:

@Serializable
data class Task(
   val id: Int = 0
): Screen()

显然在呼叫站点中,我忘了在称为此类'()'()'的括号中包括

NavHost(
   ...
   startDestination = Screen.Task
) { ... }

括号>'()'如果您不使用kotlin 数据对象

NavHost(
   ...
   startDestination = Screen.Task()
) { ... }

我希望它有帮助。 :)

For me personally, I've got this error when using a type-safety in compose-navigation. I've had a data class with parameters, like:

@Serializable
data class Task(
   val id: Int = 0
): Screen()

And apparently in the call site, I've forgot to include brackets when called this class '()'

NavHost(
   ...
   startDestination = Screen.Task
) { ... }

Don't forget to include brackets '()' if you're not using kotlin data object.

NavHost(
   ...
   startDestination = Screen.Task()
) { ... }

I hope it helps. :)

静谧 2025-01-31 01:33:58

我曾经有一个类似的问题。我假设您使用的是KTOR,并且返回paginedreponse的函数以某种方式通过以call.respond()的参数()传递,对吗?

applicationCall.Respond()是一个重新的内联函数。在我的情况下,我传递给call.respond()的变量已通过具有多种返回类型的何时表达方式丢失了它的静态类型信息。编译器推断出“任何”时表达式的公共回报类型。

就我而言,这导致与您到达那里的错误消息相同。令人困惑的是,它说,尽管没有任何类型的类型,但没有发现特定类型的序列化器。

也许您与我相同的问题。希望我能够提供帮助。

响应的定义

I once had a similar issue. I assume that you're using Ktor and the function returning the PaginatedReponse somehow gets passed as a parameter to call.respond(), right?

ApplicationCall.respond() is a reified inline function. In my case the variable I passed to call.respond() had lost it's static type information through a when-expression with multiple return types. The compiler inferred a common return type of the when expression of "Any".

In my case, this resulted in the same error message as you got there. Confusingly it said there was no serializer found for the specific type although the reified type was Any.

Perhaps you have the same issue as I did. Hope that I was able to help.

Definition of respond

清风夜微凉 2025-01-31 01:33:58

中添加下面的插件来解决该问题

”)

我通过在gradle.app插件块id(“ kotlinx- serialization 。
build.gradle.kts(模块:应用程序)插件块

id("org.jetbrains.kotlin.plugin.serialization") version "1.8.10"

I solved the issue by adding the plugin below in the gradle.app plugins block

id ("kotlinx-serialization")

This works if you have the kotlinx serialization plugin in the
build.gradle.kts (Module :app) plugin block

id("org.jetbrains.kotlin.plugin.serialization") version "1.8.10"
望她远 2025-01-31 01:33:58

对我来说没什么帮助,只能在proguard-rules.pro中添加这些规则。 链接

-keep class * {
 @kotlinx.serialization.SerialName <fields>;
}

之所以强制性,是因为默认情况下启用了R8 FullMode,Gradle 8中。

For me nothing helped, but adding these rules in proguard-rules.pro according to this link

-keep class * {
 @kotlinx.serialization.SerialName <fields>;
}

This became mandatory because of enabled R8 fullMode by default in gradle 8.

指尖凝香 2025-01-31 01:33:58

对于那些在组成 type-safety 的人:
在一致性数据类/数据对象上检查

目的地,不是对象

@Serializable
data class EnterPin(val verificationGoal: VerificationGoal)
  • 检查 startDestination
  • 检查 popupto()函数
  • 检查 navigate()函数,

以防万一您尝试以对象的身份传递目标 - 您将会崩溃:

popUpTo(EnterPin) {
   inclusive = true
}

正确的方法是:

popUpTo<EnterPin> {
   inclusive = true
}

For those who are using type-safety in compose-navigation:
check your destinations on consistency data class/data object

For example, you have a destination which is class, not the object

@Serializable
data class EnterPin(val verificationGoal: VerificationGoal)
  • check startDestination
  • check popUpTo() functions
  • check navigate() functions

In case you try to pass the destination as an object - you will get such crash:

popUpTo(EnterPin) {
   inclusive = true
}

The right way is:

popUpTo<EnterPin> {
   inclusive = true
}
栖迟 2025-01-31 01:33:58

像上面的答案一样,他可能缺少

我通过添加&lt; reified t&gt;的类型解决了这一问题。在子方法上。

Like the above answer, he may be missing the type

I solved this by adding <reified T> on the sub method.

绝對不後悔。 2025-01-31 01:33:58

就我而言,当在撰写奖励中使用类型安全时,我也会遇到此错误,但是与我的数据类中使用自定义枚举类型有关。

按照 https:// https://developer.android.com/guide/导航/use-graph/pass-data#proguard_consinations 我需要添加@keep,以防止Proguard对我的枚举产生混淆。

In my case I also got this error when using type-safety in compose-navigation however it was related to using a custom enum type in my data class.

As per https://developer.android.com/guide/navigation/use-graph/pass-data#proguard_considerations I needed to add @Keep to prevent Proguard from obfuscating my enum.

十雾 2025-01-31 01:33:58

我也有一个例外:

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

在我的情况下,这些前进的规则对我有帮助!

这些前进规则专门用于防止使用Kotlinx.Serialization的混淆或收缩代码时的问题。

将这些规则放在Proguard配置文件中(例如Proguard-rules.pro)。

# Keep all @Serializable classes
-keep @kotlinx.serialization.Serializable class ** { *; }

# Keep the generated serializers
-keep class kotlinx.serialization.internal.** { *; }
-keep class kotlinx.serialization.json.** { *; }
-keepnames class kotlinx.serialization.** { *; }

# Prevent obfuscation of enum values
-keepclassmembers enum * { *; }

# Retain classes with reflective annotations
-keepclassmembers class ** {
    @kotlinx.serialization.* <fields>;
    @kotlinx.serialization.* <methods>;
}

# Keep all kotlinx serialization-related classes and methods
-keep class kotlinx.serialization.** { *; }

I also had such an exception:

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

In my case these rules for the proguard helped me!

These ProGuard rules are specifically used to prevent issues when obfuscating or shrinking code that utilizes kotlinx.serialization.

Place these rules in a ProGuard configuration file (e.g., proguard-rules.pro).

# Keep all @Serializable classes
-keep @kotlinx.serialization.Serializable class ** { *; }

# Keep the generated serializers
-keep class kotlinx.serialization.internal.** { *; }
-keep class kotlinx.serialization.json.** { *; }
-keepnames class kotlinx.serialization.** { *; }

# Prevent obfuscation of enum values
-keepclassmembers enum * { *; }

# Retain classes with reflective annotations
-keepclassmembers class ** {
    @kotlinx.serialization.* <fields>;
    @kotlinx.serialization.* <methods>;
}

# Keep all kotlinx serialization-related classes and methods
-keep class kotlinx.serialization.** { *; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文