【问题标题】:Genson issue with android - scala.Array not foundandroid的Genson问题-找不到scala.Array
【发布时间】:2016-05-05 20:57:36
【问题描述】:

我使用 scala(macroid 框架,如果重要的话)为 android 制作了一个应用程序。 我在使用 Genson 库反序列化 JSON 时遇到问题。

这是最小的错误代码

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

}

我在模拟器上运行此代码时遇到了下一个错误

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

在 PC 上运行时反序列化工作正常(作为独立的 scala 应用程序)

我在 build.sbt 中添加了 -keep class com.owlike.genson.*{ *; } 选项, 正如推荐的here,但它没有帮助。 这是我的 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.** { *; }"
)

我已尝试将-keep class scala.Array 添加到 proguard 选项中,但也无济于事。

我还能做什么?


已编辑:我没有使用 genson 获得成功,现在使用 gson。 Gson 对我来说很好用。

【问题讨论】:

  • 如果配置为使用字段而不是属性(这是 Gson 基本上所做的),它将可以与 Genson 的 java 版本一起使用。
  • 我会使用 circe 或 Argonaut,它们都是高性能 json 解析器,根本不使用反射,它们也是惯用的 scala,不像 genson 或 gson

标签: android json scala proguard genson


【解决方案1】:

您可以尝试在没有 Genson 的情况下在您的代码中使用 scala.Array。只是为了确保它存在。

然后尝试使用scala.Array,同时使用Genson。如果它有效,那么这意味着 scala.Array 可能被 proguard 排除在外。

如果这不起作用,我怀疑 Genson 使用的类加载器看不到 Array 类。在这种情况下,试试这个:

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

【讨论】:

  • 欧根,感谢您的帮助。我的代码中有 Array 对象,因此它存在于类路径中。与builder例外是一样的。我不明白,为什么 stacktrace 只包含 scala.reflect.* 类。
  • 你有更详细的堆栈跟踪吗?可以显示 Genson 代码的哪一部分产生它的东西?
  • 没有。我已将异常堆栈跟踪打印到 PrintWriter,我没有看到任何 genson 代码或我的活动代码。其实,这个问题现在不相关,可能稍后我会抓住这个问题
猜你喜欢
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 2020-11-02
  • 1970-01-01
相关资源
最近更新 更多