2016-05-05 10 views
0

Ich mache eine Anwendung für Android mit Scala (Macroid-Framework, wenn es darauf ankommt). Ich bekomme Probleme beim Deserialisieren von JSON mit Genson Library.Genson Problem mit Android - scala.Array nicht gefunden

ist der minimale Fehlercode

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"}""") 
     .... 
    } 

} 

ich die nächsten Fehler bekam diesen Code auf 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 [email protected] 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 [email protected] 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 

Deserialisierung funktioniert gut, wenn auf dem PC (als Standalone-scala app) läuft

Ich habe hinzugefügt -keep class com.owlike.genson.*{ *; } Optionen Build.SBT, wie empfohlen here, aber es hilft nicht. Hier ist ein Teil meiner 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.** { *; }" 
) 

Ich habe versucht -keep class scala.Array, hinzufügen Optionen ProGuard, es nicht auch helfen.

Was kann ich noch tun?


EDITED: Ich did't Erfolg mit GENSON bekommen, und verwenden Sie Gson jetzt. Gson funktioniert gut für mich.

+0

Dann hätte es mit der Java-Version von Genson funktioniert, wenn konfiguriert, Felder anstelle von Eigenschaften zu verwenden (es ist, was Gson im Grunde tut). – eugen

+0

Ich würde Circe oder Argonaut verwenden, beide sind Hochleistungs-JSON-Parser, die überhaupt keine Reflexion verwenden, sie sind auch idiomatische Scala im Gegensatz zu Genson oder Gson – pfn

Antwort

0

Können Sie versuchen, Scala.Array in Ihrem Code ohne Genson zu verwenden. Nur um sicher zu gehen, dass es da ist.

Dann versuchen Sie, scala.Array zu verwenden und gleichzeitig Genson zu verwenden. Wenn es funktioniert, bedeutet dies, dass scala.Array wahrscheinlich von proguard ausgeschlossen wird.

Wenn das nicht funktioniert, vermute ich, dass der von Genson verwendete Klassenlader die Array-Klasse nicht sieht. In diesem Fall versuchen Sie dies:

val builder = new GensonBuilder().withClassLoader(Array.getClassLoader) 
val genson = new ScalaGenson(builder.withBundle(ScalaBundle()).create()) 
genson.fromJson... 
+0

Eugen, danke für Hilfe. Ich habe Array-Objekte in meinem Code, so dass es im Klassenpfad vorhanden ist. Mit Builder-Ausnahme ist das gleiche. Ich verstehe nicht, warum StackTrace nur scala.reflect. * Klassen enthält. – Alexander

+0

Haben Sie einen detaillierteren Stacktrace? Etwas, das zeigen würde, welcher Teil des Genson-Codes es produziert? – eugen

+0

Nein. Ich habe den StackTrace der Ausnahme von PrintWriter gedruckt. Ich sehe keinen Genson-Code oder meinen Aktivitätscode. Eigentlich ist die Frage jetzt nicht relevant, vielleicht werde ich später das Problem lösen – Alexander

Verwandte Themen