android - 当使用空列表和 minifyEnabled true 序列化模型时,Jackson 序列化失败,并抛出 KotlinReflectionInternalError

标签 android kotlin jackson proguard

我的 build.gradle 文件中有 minifyEnabled true ,假设我有一个模型

data class SomeModel(
    val numberList: List<Int>
)

numberList 变量具有某个值时,它会被正确序列化

SomeModel(listOf(1, 2, 3))

但是如果numberList的内容为空,则序列化失败

SomeModel(listOf()) // or SomeModel(emptyList())

如果我将代码更改为 minifyEnabled false,以上两种情况都可以正常工作

我是这样序列化的

jsonMapper.writeValueAsString(someModel)

我的 Jackson 的 JsonMapper 看起来像这样

JsonMapper().apply {
    enable(MapperFeature.INFER_PROPERTY_MUTATORS)
    enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
    configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    registerModule(KotlinModule())
}

我什至在 proguard-rules.pro 文件中添加了该类

-keep  class org.package.SomeModel {
    <fields>;
}

# tried this also
-keep  class org.package.SomeModel {
    *;
}

错误日志如下

kotlin.reflect.jvm.internal.KotlinReflectionInternalError: No accessors or field is found for property val kotlin.collections.EmptyList.serialVersionUID: kotlin.Long
    at kotlin.reflect.jvm.internal.KPropertyImplKt.computeCallerForAccessor(KPropertyImpl.kt:240)
    at kotlin.reflect.jvm.internal.KPropertyImplKt.access$computeCallerForAccessor(KPropertyImpl.kt:1)
    at kotlin.reflect.jvm.internal.KPropertyImpl$Getter$caller$2.invoke(KPropertyImpl.kt:156)
    at kotlin.reflect.jvm.internal.KPropertyImpl$Getter$caller$2.invoke(KPropertyImpl.kt:147)
    at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:62)
    at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
    at kotlin.reflect.jvm.internal.KPropertyImpl$Getter.getCaller(Unknown Source:7)
    at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:63)
    at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.getCorrespondingGetter(KotlinAnnotationIntrospector.kt:145)
    at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.hasRequiredMarker(KotlinAnnotationIntrospector.kt:110)
    at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.access$hasRequiredMarker(KotlinAnnotationIntrospector.kt:23)
    at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector$hasRequiredMarker$hasRequired$1.invoke(KotlinAnnotationIntrospector.kt:40)
    at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector$hasRequiredMarker$hasRequired$1.invoke(KotlinAnnotationIntrospector.kt:23)
    at com.fasterxml.jackson.module.kotlin.ReflectionCache.javaMemberIsRequired(ReflectionCache.kt:56)
    at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.hasRequiredMarker(KotlinAnnotationIntrospector.kt:33)
    at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.hasRequiredMarker(AnnotationIntrospectorPair.java:318)
    at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.hasRequiredMarker(AnnotationIntrospectorPair.java:318)
    at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getMetadata(POJOPropertyBuilder.java:229)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._anyIndexed(POJOPropertiesCollector.java:1197)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._sortProperties(POJOPropertiesCollector.java:1099)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:425)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getJsonValueAccessor(POJOPropertiesCollector.java:227)
    at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findJsonValueAccessor(BasicBeanDescription.java:258)
    at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(BasicSerializerFactory.java:391)
    at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.buildCollectionSerializer(BasicSerializerFactory.java:705)
    at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.buildContainerSerializer(BasicSerializerFactory.java:647)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:200)
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:169)
    at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1473)
    at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1441)
    at com.fasterxml.jackson.databind.SerializerProvider.findPrimaryPropertySerializer(SerializerProvider.java:651)
    at com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.findAndAddPrimarySerializer(PropertySerializerMap.java:72)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter._findAndAddDynamic(BeanPropertyWriter.java:895)
E/AndroidRuntime:     at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:706)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
    at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4485)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3740)
    at org.nvest.BiTool.test1(BiTool.kt:173)
    at org.bharti.axa.ui.HomeScreenActivity$onCreate$4.onClick(HomeScreenActivity.kt:92)
    at android.view.View.performClick(View.java:7509)
    at android.view.View.performClickInternal(View.java:7486)
    at android.view.View.access$3600(View.java:841)
    at android.view.View$PerformClick.run(View.java:28709)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:236)
    at android.app.ActivityThread.main(ActivityThread.java:8060)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)

最佳答案

该错误表明找不到属性 val kotlin.collections.EmptyList.serialVersionUID: kotlin.Long 的访问器或字段

所以 kotlin.reflect 知道 EmptyList.serialVersionUID 但它找不到 Jackson 来序列化空列表。要让它知道 EmptyList.serialVersionUID 而实际上无法访问,则可能意味着它位于 kotlin.collections.EmptyListkotlin.Metadata 中但不在类(class)本身。

由于这种情况仅在 minifyEnabled = true 时发生,因此 r8 似乎剥离了 kotlin.collections.EmptyList.serialVersionUID 但实际上并没有更新 kotlin.collections.EmptyListkotlin.Metadata 以避免错误地指示该字段仍然存在。

这可能是 r8 的错误,并且 r8 与 android gradle 插件打包在一起,因此将 android gradle 插件更新到最新的稳定版本应该可以解决该问题。如果没有,我建议在 Google 问题跟踪器中提交 r8 错误。

关于android - 当使用空列表和 minifyEnabled true 序列化模型时,Jackson 序列化失败,并抛出 KotlinReflectionInternalError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68511430/

相关文章:

java - 折线未显示在 Api v2 android 上

Android TalkBack 宣布 "List"为 "Fifty first"

android - 找不到 android.arch.navigation :navigation-safe-args-gradle-plugin:2. 3.5.?

Java REST API 引发错误 "org.glassfish.jersey.server.ContainerException: java.lang.NoSuchFieldError: ACCEPT_CASE_INSENSITIVE_PROPERTIES"

android - 在这个特定场景中,我们可以使用 android 数据绑定(bind)来替换 findViewById() 吗?

kotlin - 在 Kotlin 中,HashSet 包含通过哈希重复的元素

java - 如何用不同的泛型类型实例化基类?

java - jackson 注释JsonFormat $ Value json java.lang.NoSuchMethodError

java - 在名称与其 getter 不同的字段上使用 jackson 注释 JsonUnwrapped

java - 在 Java/Android 中处理多个不同异步结果的惯用方法