I have also found the exactly same issue.
I am using Scala 2.10.
Regards.
Hey all,
I'm currently using scala 2.9.1 with the salat 1.9.2 snapshot. I'm using salat to parse json strings into case classes and I have lots of optional fields. The problem arises when you have an Option[Double] field in your case class and the json happens to have a value that can be treated as an integer (eg. 0). Everything seems to parse fine, but then when you try to access the value it will throw this error:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
at scala.runtime.BoxesRunTime.unboxToDouble(Unknown Source)
at .<init>(<console>:18)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:914)
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:546)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:577)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:543)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:694)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:745)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:651)
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:542)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:550)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:851)
at xsbt.ConsoleInterface.run(ConsoleInterface.scala:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:57)
at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:48)
at sbt.Console.console0$1(Console.scala:23)
at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:24)
at sbt.TrapExit$.executeMain$1(TrapExit.scala:33)
at sbt.TrapExit$$anon$1.run(TrapExit.scala:42)
It's easy to reproduce the problem, just create a case class with an Option[Double] field:
case class Boxing(test: Option[Double])
val s: String = "{\"test\": 0}"
val b = grater[Boxing].fromJSON(s)
Everything up to this point will work fine, but you'll get an exception if you try:
b.test.get
Calling .toDouble also won't help you in situation, but what you can do is access it in a println statement or with a toString call. Both cases where the scala compiler will automatically insert type conversions.
println(b.test.get)
b.test.get.toString
If you check the type, the value stored in the field is actually an integer, not a double (getClass returns 'java.lang.Class[Double] = int'). For the time being I can avoid the issue by type checking and then if needed doing a toString conversion, but this is far from ideal.
if (!b.test.get.isInstanceOf[Double])
b.test.get.toString.toDouble
Is this an issue with Salat, with Scala, or with my own usage?
Thanks,
Eric