java - jdk - Problemas con Rhino en Android
java se 11.0 1 lts (3)
Estoy tratando de usar Mozilla Rhino en mi aplicación Java para Android para evaluar algunos JavaScript. Estoy usando el complemento Eclipse + ADT.
Primero intenté simplemente descargar el archivo .jar de Rhino desde el sitio web de Mozilla y agregarlo al proyecto como una biblioteca en Eclipse. Eclipse lo reconoció bien y compiló la aplicación. Sin embargo, al ejecutarlo, obtengo una excepción al llamar a Context.evaluateReader()
(ver más abajo para el seguimiento de la pila).
Luego intenté agregar el código fuente de Rhino como un proyecto de Android separado en Eclipse, marcarlo como una biblioteca y hacer referencia a él en mi proyecto, que fue suficiente para que Eclipse lo compilara, pero dio lugar al mismo error.
Este es el stacktrace que obtengo ( java.lang.UnsupportedOperationException: can''t load this type of class file
)
Thread [<7> Thread-8] (Suspended (exception UnsupportedOperationException))
DefiningClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 338
DefiningClassLoader.defineClass(String, byte[]) line: 62
Codegen.defineClass(Object, Object) line: 159
Codegen.createScriptObject(Object, Object) line: 114
Context.compileImpl(Scriptable, Reader, String, String, int, Object, boolean, Evaluator, ErrorReporter) line: 2440
Context.compileReader(Reader, String, int, Object) line: 1326
Context.compileReader(Scriptable, Reader, String, int, Object) line: 1298
Context.evaluateReader(Scriptable, Reader, String, int, Object) line: 1137
TimetableProcessor.evaluate(InputStream, String, String[]) line: 31
TimetableProcessor.processBasicData(InputStream, String) line: 58
TimetableProcessor.process(InputStream, String) line: 52
TimetableUpdater.update() line: 53
Main$1$1.run() line: 22
El bit de mi código que golpea la excepción se ve así:
Context cx = Context.enter();
cx.setLanguageVersion(Context.VERSION_1_7);
Scriptable scope = cx.initStandardObjects();
try {
Object result = cx.evaluateReader(scope, new InputStreamReader(data), /* <<< exception here */
filename, 0, null);
} catch (IOException e) {
// ...
}
También encontré esta publicación de blog que contiene un código similar y dice que funciona. El autor dice que usó un archivo jar del sitio de secuencias de comandos de Android . El único archivo jar que encontré allí estaba en rhino_extras_r3.zip
. Sin embargo, no contiene archivos .class
sino más bien un archivo classes.dex
. Cuando agregué esto como una biblioteca en Eclipse, no reconoció las clases que contiene y por lo tanto no compilé mi proyecto debido a las referencias faltantes a las clases de Rhino.
Cualquier ayuda en absoluto sobre cómo hacer que esto funcione es apreciada!
Finalmente lo puse a trabajar. Debería haber prestado más atención a la entrada de blog que vinculé.
Si agrego la linea
cx.setOptimizationLevel(-1);
Para desactivar las optimizaciones, todo funciona perfectamente.
He escrito una biblioteca que permite ejecutar Rhino en Android.
Las ventajas incluyen:
- Rhino solo puede ejecutarse en el nivel de optimización -1. La biblioteca soporta todos los niveles.
- La biblioteca admite el uso de JavaAdapter, que no es posible con Rhino base.
- Aunque no comparé esto, debería dar un aumento de rendimiento. (El código compilado es más rápido que el código interpretado)
Una edición compatible con Android de rhino1_7R2.jar
está disponible en el sitio de SL4A , en el sistema de control de versiones. Aquí hay un proyecto de muestra que envuelve Rhino y BeanShell en un servicio de intérprete de Android.