Можно ли передавать вещи от Rhino до Java через исключение? - PullRequest
3 голосов
/ 05 июля 2010

Используя механизм JDK 6 ScriptEngine, все, что идет не так во время "eval" или "invokeMethod" или что-либо еще, приводит к тому, что ScriptException возвращается в вызывающую среду Java.Насколько я могу судить по экспериментам и чтению исходного кода, лучшее, что я могу сделать, чтобы получить информацию из Javascript, когда мой код Javascript хочет выдать исключение, - это выбросить строку.Эта строка отображается в возвращаемом значении getMessage из объекта ScriptException.Не очень.

Кажется, было бы неплохо иметь возможность:

 if (somethingWrong) {
   throw { error: Errors.INVALID_SOMETHING, context: whatever() };
 }

из Javascript, и тогда код Java мог бы каким-то образом добраться до этого объекта.Однако я боюсь, что, учитывая текущую реализацию оболочки Rhino ScriptEngine, это просто невозможно.Если кто-нибудь знает трюк, который работает, однако, я хотел бы увидеть его.

Ответы [ 3 ]

2 голосов
/ 14 августа 2010

Rhino плохо поддерживает Исключения, они не так полезны и полезны, как в других скриптовых движках, таких как Groovy или JRuby.

Чтобы помочь вам отладить проблемы, я думаю, вы можете использовать этот трюк.Rhino добавляет нестандартное свойство к объекту Error, к которому вы можете получить доступ, чтобы распечатать некоторую информацию об ошибке.

try {
   someCode()
}
catch(e) { 
     if(e.rhinoException != null) 
     { 
         e.rhinoException.printStackTrace();
     } 
}

Вы также можете использовать привязки, чтобы указать, что что-то пошло не так?

Я понимаю, что вы ищете сейчас.Это не красиво, на самом деле это ужасно, но вы можете получить доступ к лежащему в основе JavaScriptException, а затем получить значение, в которое вы добавили исключение.

package test;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import sun.org.mozilla.javascript.*;

public class Main {
    private static ScriptEngineManager mgr = new ScriptEngineManager();
    private static ScriptEngine engine = mgr.getEngineByName("JavaScript");

    public static void main(String... args) {
        System.out.println("START");
        try {
            engine.eval("throw { error: \"cheese\", context: \"payload\" };");
        } catch (ScriptException e) {
            JavaScriptException jse = (JavaScriptException)e.getCause();
            Object obj = jse.getValue();
            ScriptableObject so = (ScriptableObject)obj;
            System.out.println(so.get("error", so));
            System.out.println(so.get("context", so));
        }
        System.out.println("END");
    }
}
0 голосов
/ 23 декабря 2010

FWIW, я думаю, было бы очень полезно, если бы вы могли выбросить объект исключения Java и получить его, который распространяется по стеку.Например, чтобы адаптировать код сверху:

try {
    engine.eval("throw new java.lang.IllegalArgumentException( 'no cookie!' )" );
} 
catch (ScriptException e) {
    Throwable cause = e.getCause();
    if ( cause != null && cause instanceof IllegalArgumentException ) {
        // ...react explicitly 
    }
    else {
        // ...react generically
    }
0 голосов
/ 14 августа 2010

Вы можете сериализовать свой объект ошибки в виде строки JSON, а затем десериализовать в Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...