4

I want to deserialize a JSON-String using the lift-json library. In my Android application I'm using Scala 2.9.0 and lift-json_2.9.0_2.4-M1.

I took a simple example from lift-json readme, but everytime I try to extract values from the JSON-String I get a net.liftweb.json.MappingException when calling the Activity. It seems there are no args delivered to "extract".

Here is my Activity:

import _root_.android.app.Activity
import _root_.android.os.Bundle
import net.liftweb.json._

class JsonTest extends Activity {

  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.mainactivity)

    implicit val formats = DefaultFormats
    case class NumList(numbers: List[Int])
    val json = parse(""" { "numbers" : [1, 2, 3, 4] } """)
    json.extract[NumList]
  }
}

and here the exception I get:

06-29 12:09:31.548: ERROR/AndroidRuntime(405): FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{de.fhs.spirit/de.fhs.spirit.JsonTest}: net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
    args=
    arg types=
    constructor=public de.fhs.spirit.JsonTest$NumList$2(de.fhs.spirit.JsonTest,scala.collection.immutable.List)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
    args=
    arg types=
    constructor=public de.fhs.spirit.JsonTest$NumList$2(de.fhs.spirit.JsonTest,scala.collection.immutable.List)
    at net.liftweb.json.Meta$.fail(Meta.scala:185)
    at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:257)
    at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:280)
    at net.liftweb.json.Extraction$.build$1(Extraction.scala:298)
    at net.liftweb.json.Extraction$.extract0(Extraction.scala:345)
    at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:194)
    at net.liftweb.json.Extraction$.extract(Extraction.scala:42)
    at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:290)
    at de.fhs.spirit.JsonTest.onCreate(JsonTest.scala:16)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    ... 11 more

Would be great if you have an idea how to solve my problem. Thank you!

Greetings, Illaz

Illaz
  • 43
  • 2

1 Answers1

2

I suspect Lift uses reflection in this mode. It might not work at all in Android, or it may require that some stuff that got removed not be removed. I suggest you just try to use some of other alternatives instead.

See also this question -- my suspicion comes from the remark that it doesn't work on REPL. Not that REPL doesn't have reflection, but its package structure might be confusing to the Lift library.

Community
  • 1
  • 1
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Thanks for your answer. I'm now using Google Gson. Unfortunately it's no Scala, but it works. – Illaz Jun 30 '11 at 09:32
  • Are you able to deserialize Scala objects with GSon, or are you not using Scala at all? – Chopmo Jun 30 '11 at 10:13
  • 1
    If you're using Gson and for example you have a List in your Json-String, Gson returns a java.util.List. If you want to use a scala.List instead, you have to convert this list using "import scala.collection.JavaConversions._" and "javaList.toList". Is that what you meant, Chopmo? – Illaz Jul 07 '11 at 12:29