Json4s: разложение на JValue дает ArrayIndexOutOfBoundsException

Я использую Extraction.decompose для создания JValue, и он периодически дает сбой. Я прошу его разложить Seq следующего класса case:

case class Item(locators: Seq[String], dateAdded: DateTime = new DateTime(0L), newVersionSinceCuration: Option[Boolean] = None)

DateTime это org.joda.time.DateTime.

Одна и та же строка кода будет работать в большинстве случаев, но каждые несколько минут будет происходить сбой со следующей трассировкой стека:

java.lang.ArrayIndexOutOfBoundsException: 14
    at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:453)
    at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2397)
    at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2312)
    at java.util.Calendar.complete(Calendar.java:2268)
    at java.util.Calendar.get(Calendar.java:1826)
    at java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1119)
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:966)
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:936)
    at java.text.DateFormat.format(DateFormat.java:345)
    at org.json4s.DefaultFormats$$anon$4.format(Formats.scala:358)
    at org.json4s.ext.DateTimeSerializer$$anonfun$$lessinit$greater$4$$anonfun$apply$8.applyOrElse(JodaTimeSerializers.scala:78)
    at scala.PartialFunction$OrElse.apply(PartialFunction.scala:167)
    at org.json4s.ext.InstantSerializer$$anonfun$$lessinit$greater$3$$anonfun$apply$6.applyOrElse(JodaTimeSerializers.scala:57)
    at scala.PartialFunction$OrElse.apply(PartialFunction.scala:167)
    at org.json4s.ext.DurationSerializer$$anonfun$$lessinit$greater$2$$anonfun$apply$4.applyOrElse(JodaTimeSerializers.scala:47)
    at scala.PartialFunction$OrElse.apply(PartialFunction.scala:167)
    at scala.PartialFunction$class.applyOrElse(PartialFunction.scala:123)
    at scala.collection.AbstractMap.applyOrElse(Map.scala:59)
    at scala.PartialFunction$OrElse.apply(PartialFunction.scala:167)
    at org.json4s.Extraction$.internalDecomposeWithBuilder(Extraction.scala:146)
    at org.json4s.Extraction$.addField$1(Extraction.scala:110)
    at org.json4s.Extraction$.decomposeObject$1(Extraction.scala:140)
    at org.json4s.Extraction$.internalDecomposeWithBuilder(Extraction.scala:228)
    at org.json4s.Extraction$.internalDecomposeWithBuilder(Extraction.scala:189)
    at org.json4s.Extraction$.decomposeWithBuilder(Extraction.scala:64)
    at org.json4s.Extraction$.decompose(Extraction.scala:242)

    ...

Так что, похоже, не удается разобрать файл DateTime. Я переопределяю формат даты в соответствии с документацией Json4s следующим образом:

implicit def json4sFormats = new DefaultFormats {
    override val dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")
    dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"))
} ++ JodaTimeSerializers.all

Я прогуглил около ArrayIndexOutOfBoundsException проблем с sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate и SimpleDateFormat, и есть много сообщений о том, что SimpleDateFormat не является потокобезопасным. Кажется, это может объяснить ошибку, но я вижу, что Json4s оборачивает dateFormatter в ThreadLocal, что, как я понимаю, должно сделать его потокобезопасным.

Любые мысли о том, что может происходить здесь?

Я использую Scala 2.11.8, Json4s 3.5.1, OpenJDK 1.8.0.

Привет, Пол


person Paul L.    schedule 30.03.2017    source источник


Ответы (1)


Вы побеждаете ThreadLocal, превращая dateFormatter в val вместо def, как в связанном источнике для DefaultFormats, поэтому все потоки в конечном итоге ссылаются на один и тот же экземпляр. Конечно, когда вы делаете это def, setTimeZone нужно делать внутри определения.

person Alexey Romanov    schedule 31.03.2017
comment
В этом столько смысла! Я внес это изменение и до сих пор не видел ни одной из этих проблем, поэтому я уверен, что проблема решена. Большое спасибо за помощь Алексею! - person Paul L.; 31.03.2017
comment
@ПолЛ. В этом случае вы можете принять ответ (щелкнув галочку под ним). - person Alexey Romanov; 31.03.2017
comment
Извините, долго слушаю, звоню впервые. - person Paul L.; 03.04.2017