java - 使用 MixIn 时 Jackson android NPE

标签 java android kotlin jackson

我的服务器 api 使用不同类型的多态对象。比如我有一个json:

{
  "eventType": "FirstType",
  "eventData": "some-useful-object"
}

和它的 kotlin 类:

sealed class NotificationEvent {

  data class SomeUsefulEvent(val eventData: String): NotificationEvent()

}

和混合类:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "eventType"
)
@JsonSubTypes(
    JsonSubTypes.Type(
        value = NotificationEvent.SomeUsefulEvent::class,
        name = "FirstType"
    )
)
abstract class NotificationEventMixIn

当我从客户端调用时

jsonMapper.readValue<NotificationEvent>(event.data)

应用程序因 NPE 而崩溃:

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.Map.get(java.lang.Object)' on a null object reference at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector._addFieldMixIns(AnnotatedFieldCollector.java:110) at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector._findFields(AnnotatedFieldCollector.java:87) at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector.collect(AnnotatedFieldCollector.java:41) at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector.collectFields(AnnotatedFieldCollector.java:36) at com.fasterxml.jackson.databind.introspect.AnnotatedClass._fields(AnnotatedClass.java:349) at com.fasterxml.jackson.databind.introspect.AnnotatedClass.fields(AnnotatedClass.java:321) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields(POJOPropertiesCollector.java:379) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:308) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:287) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:170) at com.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties(BasicBeanDescription.java:164) at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findProperties(BasicBeanDescription.java:239) at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._findCreatorsFromProperties(BasicDeserializerFactory.java:346) at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:330) at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:255) at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:214) at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:137) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244) at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477) at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4178) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3997) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3011)

我怎样才能避免这种崩溃?

最佳答案

在研究上浪费了一些时间后,我发现在 AnnotatedFieldCollector#_findFields 中有 for block 调用 JavaType.getRawClass().getDeclaredFields() 如果它返回一个空数组,则跳过所有 for block , map _fields 未初始化并保持 null_addFieldMixIns 被调用。

发生这种情况是因为属性不是 kotlin 中的字段并且父类没有。

可以通过向 NotificationEvent 类添加 @JvmField 注释属性来解决此问题,如下所示:

sealed class NotificationEvent {

  @Suppress("unused")
  @JvmField val stub: Int = 0

  data class SomeUsefulEvent(val eventData: String): NotificationEvent()

}

一切正常!

我希望这个问题对某人有所帮助,我鼓励 Jackson 团队修复这个错误

关于java - 使用 MixIn 时 Jackson android NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55238235/

相关文章:

android - 在没有应用程序的情况下测试 firebase 云消息传递

classloader - Kotlin 类重新加载伴随对象/函数

kotlin - 如何在 Kotlin 中创建一个用空值填充的通用数组?

java - 用Java制作一个彩票程序

java - 扫描图像中是否存在某种颜色

java - 在 Java 中实现接口(interface)的 Class<> 类型的变量赋值

java - 比较命令行参数引用返回 false 而字符串数组返回 true

Android,neenbedankt A.P 和 Support Annotation 有什么区别?

java - 单击同一按钮时,如何在一项 Activity 中显示不同的内容

android - 当应用程序处于后台时,如何从 BroadcastReceiver 的 onReceive() 方法启动 Activity ?