samedi 4 mars 2017

Scala reflection java.rmi dependency, can it work on Android?

I would like to use the Scala (2.11) reflection package's runtime mirror in a Scala application compiled for android which is being build using Scala on android.

I was able to fiddle with ProGuard options in order to make it include the required Scala classes. However when I try to get a mirror instance:

universe.runtimeMirror(this.getClass.getClassLoader)

(Indeed it fails during the lazy computation of universe)

The application crashes in run time:

03-04 17:23:32.923 E/AndroidRuntime(11876): java.lang.NoClassDefFoundError: Failed resolution of: Ljava/rmi/Remote; 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.internal.Definitions$DefinitionsClass.RemoteInterfaceClass$lzycompute(Definitions.scala:370) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.internal.Definitions$DefinitionsClass.RemoteInterfaceClass(Definitions.scala:370) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.runtime.JavaUniverseForce$class.force(JavaUniverseForce.scala:255) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.runtime.JavaUniverse.force(JavaUniverse.scala:16) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.runtime.JavaUniverse.init(JavaUniverse.scala:147) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.runtime.JavaUniverse.<init>(JavaUniverse.scala:78) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.runtime.package$.universe$lzycompute(package.scala:17) 03-04 17:23:32.923 E/AndroidRuntime(11876): at scala.reflect.runtime.package$.universe(package.scala:17)

This crash is for me as expected as it isn't. It is expected as java.rmi is not part of the Android API and I should expect any code trying to load it classes to crash. It is unexpected as I didn't know that Scala's reflect package used java.rmi

I have traced the code to were rmi is required, that is to JavaUniverse (a trait mixed in JavaUniverse class) force method:

... definitions.RemoteInterfaceClass ...

Which leads to DefinitionsClass:

lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote]

Am I wrong to think that this is a no-go for Scala reflection in Android? If I am, what could be a workaround to this problem?





Aucun commentaire:

Enregistrer un commentaire