当用空列表和 minifyEnabled true 序列化模型时抛出 KotlinReflectionInternalError 导致 Jackson 序列化失败
Jackson serialisation fails by throwing KotlinReflectionInternalError when serializing model with empty list and minifyEnabled true
我的 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)
我的杰克逊 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
文件中添加了 class
-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.invoke(KPropertyImpl.kt:156)
at kotlin.reflect.jvm.internal.KPropertyImpl$Getter$caller.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.invoke(KotlinAnnotationIntrospector.kt:40)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector$hasRequiredMarker$hasRequired.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.onClick(HomeScreenActivity.kt:92)
at android.view.View.performClick(View.java:7509)
at android.view.View.performClickInternal(View.java:7486)
at android.view.View.access00(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)
错误提示No accessors or field is found for property val kotlin.collections.EmptyList.serialVersionUID: kotlin.Long
所以 kotlin.reflect
知道 EmptyList.serialVersionUID
但它找不到 Jackson 序列化空列表。它知道 EmptyList.serialVersionUID
而实际上无法访问可能意味着它在 kotlin.collections.EmptyList
的 kotlin.Metadata
中,但不在 class 本身中。
因为这只发生在 minifyEnabled = true
上,看来 r8
剥离了 kotlin.collections.EmptyList.serialVersionUID
但实际上并没有更新 kotlin.collections.EmptyList
的 kotlin.Metadata
以避免错误地指示该字段仍然存在。
这可能是 r8
的错误,并且 r8
与 android gradle 插件打包在一起,因此更新 android gradle 最新稳定版本的插件应该可以解决这个问题。如果没有,我建议在 Google 问题跟踪器中提交一个 r8 错误。
我的 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)
我的杰克逊 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
文件中添加了 class
-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.invoke(KPropertyImpl.kt:156)
at kotlin.reflect.jvm.internal.KPropertyImpl$Getter$caller.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.invoke(KotlinAnnotationIntrospector.kt:40)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector$hasRequiredMarker$hasRequired.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.onClick(HomeScreenActivity.kt:92)
at android.view.View.performClick(View.java:7509)
at android.view.View.performClickInternal(View.java:7486)
at android.view.View.access00(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)
错误提示No accessors or field is found for property val kotlin.collections.EmptyList.serialVersionUID: kotlin.Long
所以 kotlin.reflect
知道 EmptyList.serialVersionUID
但它找不到 Jackson 序列化空列表。它知道 EmptyList.serialVersionUID
而实际上无法访问可能意味着它在 kotlin.collections.EmptyList
的 kotlin.Metadata
中,但不在 class 本身中。
因为这只发生在 minifyEnabled = true
上,看来 r8
剥离了 kotlin.collections.EmptyList.serialVersionUID
但实际上并没有更新 kotlin.collections.EmptyList
的 kotlin.Metadata
以避免错误地指示该字段仍然存在。
这可能是 r8
的错误,并且 r8
与 android gradle 插件打包在一起,因此更新 android gradle 最新稳定版本的插件应该可以解决这个问题。如果没有,我建议在 Google 问题跟踪器中提交一个 r8 错误。