【问题标题】:Json4s: Decomposing to JValue gives ArrayIndexOutOfBoundsExceptionJson4s:分解为 JValue 给出 ArrayIndexOutOfBoundsException
【发布时间】:2017-03-30 16:04:35
【问题描述】:

我正在使用Extraction.decompose 生成JValue,但它间歇性地失败。我要求它分解以下案例类的Seq

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

DateTimeorg.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

我搜索了ArrayIndexOutOfBoundsExceptionsun.util.calendar.BaseCalendar.getCalendarDateFromFixedDateSimpleDateFormat 相关的问题,并且有很多关于SimpleDateFormat 不是线程安全的帖子。这似乎可以解释错误,但我可以看到 Json4s wraps the dateFormatter in a ThreadLocal,我理解它应该使它成为线程安全的。

对这里可能发生的事情有什么想法吗?

我正在使用 Scala 2.11.8、Json4s 3.5.1、OpenJDK 1.8.0。

干杯, 保罗

【问题讨论】:

    标签: scala json4s


    【解决方案1】:

    通过将dateFormatter 设置为val 而不是def (如DefaultFormats 的链接源中的def),您正在击败ThreadLocal,因此所有线程最终都会引用同一个实例。当然,当你将其设为def 时,setTimeZone 需要在定义中完成。

    【讨论】:

    • 这很有意义!我已经做出了改变,到目前为止我还没有看到任何这些问题,所以我确信这已经解决了问题。非常感谢您的帮助 Alexey!
    • @PaulL。在这种情况下,您可能希望接受答案(通过单击其下方的复选标记)。
    • 对不起,第一次来电,长时间的听众。
    猜你喜欢
    • 2014-06-14
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多