Джерксон (Джексон) проблема с scala.runtime.BoxedUnit?
Джерксон начал выдавать действительно странную ошибку, которую я не видел раньше.
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class scala.runtime.BoxedUnit and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: scala.collection.MapWrapper["data"])
Я анализирую некоторые основные данные из API. Класс, который я определил:
case class Segmentation(
@(JsonProperty@field)("legend_size")
val legend_size: Int,
@(JsonProperty@field)("data")
val data: Data
)
а также Data
похоже:
case class Data(
@(JsonProperty@field)("series")
val series: List[String],
@(JsonProperty@field)("values")
val values: Map[String, Map[String, Any]]
)
Любая подсказка, почему это будет вызывать ошибки? Похоже на простой класс, с которым Джерксон может справиться.
Изменить: пример данных:
{"legend_size": 1, "data": {"series": ["2013-04-06", "2013-04-07", "2013-04-08", "2013-04-09", "2013-04-10", "2013-04-11", "2013-04-12", "2013-04-13", "2013-04-14", "2013-04-15"], "values": {"datapoint": {"2013-04-12": 0, "2013-04-15": 4, "2013-04-14": 0, "2013-04-08":
0, "2013-04-09": 0, "2013-04-11": 0, "2013-04-10": 0, "2013-04-13": 0, "2013-04-06": 0, "2013-04-07": 0}}}}
3 ответа
Прошло много времени с тех пор, как я впервые опубликовал этот вопрос. Решение при написании этого ответа, похоже, заключается в том, чтобы перейти от Джексона и использовать Jackson-module-scala или Json4s с бэкэндом Джексона. Многие типы Scala включены в сериализованные по умолчанию и обрабатываются изначально.
Кроме того, причина, по которой я вижу BoxedUnit
потому что явный тип, который видел Джерксон, был Any
(часть Map[String, Map[String, Any]]
). Any
является базовым типом и не дает Джерксону / Джексону информацию о том, что он десериализует. Поэтому жалуется на отсутствующий сериализатор.
Это не ответ на приведенный выше пример, но я собираюсь предложить его, потому что это был ответ на мой аналогичный сценарий "BoxedUnit":
No serializer found for class scala.runtime.BoxedUnit and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
В моем случае Джексон жаловался на десериализацию экземпляра объекта scala.runtime.BoxedUnit.
Q: Так что же такое scala.runtime.BoxedUnit?
A: Это Scala Java-представление для "Unit". Основная часть Джексона (который является Java-кодом) пытается десериализовать Java-представление не-сущности модуля Scala.
Q: Так почему это случилось?
A: В моем случае это был побочный эффект, вызванный ошибочным методом с необъявленным возвращаемым значением. Рассматриваемый метод обернул предложение match, которое (непреднамеренно) не возвращало значение для каждого случая. Из-за ошибочного кода, описанного выше, Scala динамически объявляет переменную, фиксирующую результат этого метода, как "Unit". Позже в коде, когда этот var сериализуется в json, возникает ошибка Джексона.
Поэтому, если у вас возникла такая проблема, я бы посоветовал изучить любые неявно типизированные переменные / методы с неопределенными возвращаемыми значениями и убедиться, что они делают то, что, по вашему мнению, они делают.
У меня было такое же исключение. в моем случае это вызвало то, что я определил метод apply в объекте-компаньоне без '=':
object Somthing {
def apply(s: SomthingElse) {
...
}
}
вместо
object Somthing {
def apply(s: SomthingElse) = {
...
}
}
Это привело к тому, что тип возвращаемого значения метода apply был Unit, что вызвало исключение, когда я передал объект Джексону. Не уверен, так ли это в вашем коде или этот вопрос все еще актуален, но это может помочь другим в решении этой проблемы.