Джексон андроид ИМЯ при использовании MixIn

1

Мой сервер API использует полиморфные объекты разных типов. Например, у меня есть JSON:

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

и класс котлин для него:

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: попытка вызвать метод интерфейса 'java.lang.Object java.util.Map.get(java.lang.Object)' для пустой ссылки на объект в com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector. _addFieldMixIns (AnnotatedFieldCollector.java:110) по адресу com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector._findFields (AnnotatedFieldCollector.java:87) по адресу com.fasterxml.jackson.dield.ollectOntFoltaTointA в com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector.collectFields(AnnotatedFieldCollector.java:36) в com.fasterxml.jackson.databind.introspect.AnnotatedClass._fields (AnnotatedClass.java.f.data. at at..introspect.AnnotatedClass.fields(AnnotatedClass.java:321) при com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields (POJOPropertiesCollector.java:379) в com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertie sCollector.java:308) в com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:287) в com.fasterxml.jackson.databind.introspect.POJOPropertiesOperties.Polties.Color.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties (BasicBeanDescription.java:164) в com.fasterxml.jackson.databind.introspect..BasicDeserializerFactory.: 255) на com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:214) на com.fasterxml.j ackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:137) в com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2 (DeserializerCache.java.f. _createDeserializer (DeserializerCache.java:349) по адресу com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2 (DeserializerCache.java:264) по адресу com.fasterxml.jackson.databind.deser.DeserializerCache.acheueCal_Case по адресу com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) по адресу com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.jack:4xjecta.jack.fb).._findRootDeserializer (ObjectMapper.java:4178) в com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose (ObjectMapper.java:3997) в com.fasterxml.jackson.databind.ObjectMapper.readValue( ObjectMapper.java:3011)

как я могу избежать этого сбоя?

Теги:
kotlin
jackson

1 ответ

0

после того, как некоторое количество времени тратится на исследования я обнаружил, что в AnnotatedFieldCollector#_findFields есть for блока, который вызывает JavaType.getRawClass().getDeclaredFields(), и если он возвращает пустой массив, все for блока пропускается, карта _fields не инициализируется и остается null когда _addFieldMixIns.

Это происходит потому, что свойства не являются полями в kotlin и родительский класс не имеет их.

Эту проблему можно обойти, добавив аннотированное свойство @JvmField в класс NotificationEvent следующим образом:

sealed class NotificationEvent {

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

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

}

и все работает отлично!

Я надеюсь, что этот вопрос кому-нибудь поможет, и я призываю команду Джексона исправить эту ошибку

Ещё вопросы

Сообщество Overcoder
Наверх
Меню