2010-10-04 9 views
17

Estoy tratando de usar Mozilla Rhino en mi aplicación Java para Android para evaluar algunos JavaScript. Estoy usando el complemento Eclipse + ADT.Problemas al usar Rhino en Android

Primero intenté simplemente descargar el archivo Rhino .jar del sitio web de Mozilla y agregarlo al proyecto como una biblioteca en Eclipse. Eclipse lo reconoció bien y compiló la aplicación. Sin embargo, cuando lo ejecuto recibo una excepción cuando llamo al Context.evaluateReader() (ver a continuación el rastreo de la pila).

Luego traté de agregar el código fuente de Rhino como un proyecto independiente de Android en Eclipse, marcándolo como una biblioteca y haciendo referencia a él en mi proyecto, que fue suficiente para hacer que Eclipse compilara, pero condujo al mismo error .

Ésta es la StackTrace consigo (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 

La parte de mi código que golpea la excepción es el siguiente:

 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é this blog post que contiene código similar y dice funciona. El autor dice que usó un archivo jar del sitio Android Scripting. El único archivo jar que encontré 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 pude compilar mi proyecto debido a las referencias faltantes a las clases de Rhino.

¡Se agradece cualquier ayuda sobre cómo hacer que esto funcione!

Respuesta

32

Finalmente lo tengo a trabajar. Debería haber prestado más atención a la publicación de blog que he vinculado.

Si añado la línea

cx.setOptimizationLevel(-1); 

para deshabilitar optimizaciones, todo funciona perfectamente.

+12

De forma predeterminada, Rhino intenta generar código de byte JVM sobre la marcha, como una especie de Javascript JIT. Eso es genial y todo, pero Android no ejecuta el bytecode de JVM, sino que ejecuta el bytecode de Dalvik. Por lo tanto, debe deshabilitar la optimización, a través del fragmento de código que mostró, para permitir que Rhino se ejecute. – CommonsWare

+0

Confirmo que esto ayuda :-) – agibalov

+1

@Listill m enfrentan el mismo problema después de agregar esta línea ... –

11

Una edición compatible con Android de rhino1_7R2.jar está disponible en el sitio SL4A, en el sistema de control de versiones. Here is a sample project que envuelve Rhino y BeanShell en un servicio de intérprete de Android.

+0

Gracias, no me di cuenta que el archivo jar, ya que no fue incluido en la sección de descargas. Todavía no resolvió mi problema (publiqué mi solución real), pero definitivamente se merece un voto positivo para mostrarme dónde está el archivo jar y el proyecto de ejemplo que puedo usar como ejemplo. –

+1

Aquí está el enlace directo: http://code.google.com/p/android-scripting/source/browse/rhino/rhino1_7R2.jar –

1

He escrito una biblioteca que permite ejecutar Rhino en Android.

Las ventajas incluyen:

  • Rhino sólo puede ejecutarse en el nivel de optimización -1. La biblioteca es compatible con 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 en el rendimiento. (El código compilado es más rápido que el código interpretado)

https://github.com/F43nd1r/rhino-android

Cuestiones relacionadas