This code works:
import net.liftweb.json.{DefaultFormats, parse}
object JsonTest {
def main(args: Array[String]): Unit = {
implicit val formats = DefaultFormats // Brings in default date formats etc.
case class RawObject(filters: List[ChunkObject])
case class ChunkObject(name: String)
val json = parse("""{"filters": []}""").extract[RawObject]
println(json)
}
}
It prints :
RawObject(List())
This same code within a class does not:
import net.liftweb.json.{DefaultFormats, parse}
class JsonTest2 {
def fct(): Unit = {
implicit val formats = DefaultFormats // Brings in default date formats etc.
case class RawObject(filters: List[ChunkObject])
case class ChunkObject(name: String)
val json = parse("""{"filters": []}""").extract[RawObject]
println(json)
}
}
object JsonTest2 {
def main(args: Array[String]): Unit = {
val jt = new JsonTest2
jt.fct()
}
}
Error:
Exception in thread "main" net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
args=List()
arg types=scala.collection.immutable.Nil$
constructor=public JsonTest2$RawObject$1(JsonTest2,scala.collection.immutable.List)
at net.liftweb.json.Meta$.fail(Meta.scala:227)
at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:274)
at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:308)
at net.liftweb.json.Extraction$.build$1(Extraction.scala:379)
at net.liftweb.json.Extraction$.extract0(Extraction.scala:444)
at net.liftweb.json.Extraction$.extract0(Extraction.scala:206)
at net.liftweb.json.Extraction$.extract(Extraction.scala:43)
at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:703)
at JsonTest2.fct(JsonTest2.scala:9)
at JsonTest2$.main(JsonTest2.scala:17)
at JsonTest2.main(JsonTest2.scala)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:265)
... 9 more
What did I miss?
PS: with a simple json (only a field with a string value so without a List inside) it works in both Object and Class
EDIT: I think it is related to the case class definition inside the function but i do not understand why.
From the look of the error messages it seems that the constructor for
RawObjecttakes an additional argument that liftweb is not expecting:RawObjectis a nested type, and in Scala nested types are unique for each instance of the containing object. SoRawObjectinside one instance ofJsonTest2is not the same type asRawObjectinside a different instance ofJsonTest2.I am guessing that Scala places the instance of the containing type (
JsonTest2) in the nested type (RawObject) so that it can determine the type at runtime. Hence thatJsonTest2argument to the constructor forRawObject.So moving
RawObjectandChunkObjectout of theJsonTest2class will fix the problem. These can be placed in the companion object to keep things neat.