I make an application for android using scala (macroid framework, if it matters). I get issues while deserializing JSON using Genson Library.
Here is the minimal error code
case class Model(a: Int, b: String)
class MainActivity extends FragmentActivity with Contexts[FragmentActivity] with IdGeneration with AkkaActivity {
....
override def onCreate(savedInstanceState: Bundle) = {
super.onCreate(savedInstanceState);
val m = com.owlike.genson.defaultGenson.fromJson[Model]("""{"a":1, "b":"hello"}""")
....
}
}
I got the next error running this code on emulator
05-05 10:55:29.996 5439-5439/? I/art: Not late-enabling -Xcheck:jni (already on)
05-05 10:55:30.033 5439-5439/com.myapp.dfp W/System: ClassLoader referenced unknown path: /data/app/com.myapp.dfp-2/lib/x86
05-05 10:55:30.316 5439-5439/com.myapp.dfp D/AndroidRuntime: Shutting down VM
05-05 10:55:30.316 5439-5439/com.myapp.dfp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.dfp, PID: 5439
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.dfp/com.myapp.dfp.MainActivity}: scala.reflect.internal.MissingRequirementError: class scala.Array in JavaMirror with dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.myapp.dfp-2/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.dfp-2/lib/x86, /vendor/lib, /system/lib]]] of type class dalvik.system.PathClassLoader with classpath [<unknown>] and parent being java.lang.BootClassLoader@a7ede1c of type class java.lang.BootClassLoader with classpath [<unknown>] and parent being primordial classloader with boot classpath [/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/apache-xml.jar:/system/framework/org.apache.http.legacy.boot.jar] not found.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: scala.reflect.internal.MissingRequirementError: class scala.Array in JavaMirror with dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.myapp.dfp-2/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.dfp-2/lib/x86, /vendor/lib, /system/lib]]] of type class dalvik.system.PathClassLoader with classpath [<unknown>] and parent being java.lang.BootClassLoader@a7ede1c of type class java.lang.BootClassLoader with classpath [<unknown>] and parent being primordial classloader with boot classpath [/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/apache-xml.jar:/system/framework/org.apache.http.legacy.boot.jar] not found.
at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:17)
at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:18)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:53)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:66)
at scala.reflect.internal.Mirrors$RootsBase.getClassByName(Mirrors.scala:102)
at scala.reflect.internal.Mirrors$RootsBase.getRequiredClass(Mirrors.scala:105)
at scala.reflect.internal.Definitions$DefinitionsClass.ArrayClass$lzycompute(Definitions.scala:440)
at scala.reflect.internal.Definitions$DefinitionsClass.ArrayClass(Definitions.scala:440)
at scala.reflect.internal.Definitions$DefinitionsClass.arrayType(Definitions.scala:827)
at scala.reflect.internal.Definitions$DefinitionsClass$$anonfun$JavaRepeatedParamClass$1.apply(Definitions.scala:374)
at scala.reflect.internal.Definitions$DefinitionsClass$$anonfun$JavaRepeatedParamClass$1.apply(Definitions.scala:374)
at scala.reflect.internal.Definitions$DefinitionsClass.specialPolyClass(Definitions.scala:1268)
at scala.reflect.internal.Definitions$DefinitionsClass.JavaRepeatedPa
05-05 11:00:30.355 5439-5439/com.myapp.dfp I/Process: Sending signal. PID: 5439 SIG: 9
Deserialization works fine when running on PC (as a standalone scala app)
I've added -keep class com.owlike.genson.*{ *; }
options to build.sbt,
as was recommended here, however it does not help.
Here is part of my build.sbt:
proguardOptions in Android ++= Seq(
"-ignorewarnings",
"-keepattributes Signature",
"-keep class scala.Dynamic",
"-keep class scala.collection.SeqLike {public protected *;}",
"-keep public class scala.PartialFunction",
"-keep class com.owlike.genson.*{ *; }",
"-keep class com.myapp.** { *; }"
)
I've tried to add -keep class scala.Array
, to proguard options, it does not help also.
What else can I do?
EDITED: I did't get success with genson, and use gson now. Gson works fine for me.
Can you try to use scala.Array in your code without Genson. Just to make sure it is present.
Then try to use scala.Array and at the same time use Genson. If it works then this means that scala.Array is probably excluded by proguard.
If this doesn't work I suspect that the classloader used by Genson doesn't see the Array class. In that case try this: