0

I am trying to deserialise a simple json string using jackson json4s. I have been able to get this to work in scala 2.11, but on the upgrade to 2.12, I am seeing this error:

  import org.json4s._
  import org.json4s.jackson.Serialization.read
    
  implicit val formats: DefaultFormats.type = DefaultFormats

  case class Person(val name: String, val address: Option[String])

In Scala 2.11, when I run the code set, I get the following:

  println(jackson.parseJson(f"""{ "name": "foo" }""").extract[Person])

  Result: Person(foo,None)

In Scala 2.12, I am getting the following:

  println(jackson.parseJson(f"""{ "name": "foo" }""").extract[Person])

  org.json4s.package$MappingException: unknown error
  at org.json4s.Extraction$.extract(Extraction.scala:43)
  at org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)
  ... 52 elided
Caused by: java.lang.IndexOutOfBoundsException: 2
  at scala.collection.immutable.Vector.checkRangeConvert(Vector.scala:127)
  at scala.collection.immutable.Vector.apply(Vector.scala:118)
  at org.json4s.reflect.Reflector$ClassDescriptorBuilder.$anonfun$createConstructorDescriptors$6(Reflector.scala:156)
  at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238)
  at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
  at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
  at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
  at scala.collection.TraversableLike.map(TraversableLike.scala:238)
  at scala.collection.TraversableLike.map$(TraversableLike.scala:231)
  at scala.collection.AbstractTraversable.map(Traversable.scala:108)
  at org.json4s.reflect.Reflector$ClassDescriptorBuilder.$anonfun$createConstructorDescriptors$3(Reflector.scala:142)
  at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238)
  at scala.collection.mutable.ArraySeq.foreach(ArraySeq.scala:75)
  at scala.collection.TraversableLike.map(TraversableLike.scala:238)
  at scala.collection.TraversableLike.map$(TraversableLike.scala:231)
  at scala.collection.AbstractTraversable.map(Traversable.scala:108)
  at org.json4s.reflect.Reflector$ClassDescriptorBuilder.createConstructorDescriptors(Reflector.scala:136)
  at org.json4s.reflect.Reflector$ClassDescriptorBuilder.constructorsAndCompanion(Reflector.scala:121)
  at org.json4s.reflect.Reflector$ClassDescriptorBuilder.result(Reflector.scala:183)
  at org.json4s.reflect.Reflector$.createDescriptor(Reflector.scala:53)
  at org.json4s.reflect.Reflector$.$anonfun$describe$1(Reflector.scala:48)
  at org.json4s.reflect.package$Memo.apply(package.scala:36)
  at org.json4s.reflect.Reflector$.describe(Reflector.scala:48)
  at org.json4s.Extraction$.$anonfun$extract$9(Extraction.scala:393)
  at org.json4s.Extraction$.customOrElse(Extraction.scala:606)
  at org.json4s.Extraction$.extract(Extraction.scala:392)
  at org.json4s.Extraction$.extract(Extraction.scala:39)
  ... 53 more

I am using the following versions of the json4s libraries:

Scala 2.11

  • json4s-ast_2.11-3.5.3.jar
  • json4s-core_2.11-3.5.3.jar
  • json4s-jackson_2.11-3.5.3.jar
  • json4s-scalap_2.11-3.5.3.jar

Scala 2.12

  • json4s-ast_2.12-3.5.3.jar
  • json4s-core_2.12-3.5.3.jar
  • json4s-jackson_2.12-3.5.3.jar
  • json4s-scalap_2.12-3.5.3.jar

Please could you let me know what I am doing wrong here?

Nirmie
  • 65
  • 1
  • 4
  • BEWARE: Json4s is [vulnerable under DoS/DoW attacks](https://github.com/json4s/json4s/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+denial)! – Andriy Plokhotnyuk Aug 22 '20 at 07:48
  • BEWARE: @AndriyPlokhotnyuk is often promoting his own JSON library on stackoverflow – Tim Aug 22 '20 at 12:08

2 Answers2

3

In my experience (json4s 3.5.3 and 3.6.4):

class Test {
   case class Foo(foo: String, bar: Map[String, Int])
   implicit val formats = org.json4s.DefaultFormat
   val foo = Foo("foo", bar = Map("bar" -> 1, "baz" -> 2))

   org.json4s.Extraction.decompose(foo)
}

Works with scala-2.11 but fails with OutOfBoundException in scala-2.12.

Fix: define your case class in the companion object:

class Test {
   implicit val formats = org.json4s.DefaultFormat
   val foo = Test.Foo("foo", bar = Map("bar" -> 1, "baz" -> 2))

   org.json4s.Extraction.decompose(foo)
}
object Test {
   case class Foo(foo: String, bar: Map[String, Int])
}

This works for both scala-2.11 and scala-2.12

imc
  • 31
  • 3
0

I am not able to reproduce the issue. I use json4s-core_2.12-3.5.3 and json4s-jackson_2.12-3.5.3 with Scala 2.12.10, but it parses correctly. See https://scastie.scala-lang.org/IMs6t86PTlyfS9F00V32vw.

yiksanchan
  • 1,890
  • 1
  • 13
  • 37