JavaScript ScriptEngine не работает в Google App Engine для Java (GAE/J)

У меня возникла проблема, когда я всегда получаю значение 0 при попытке использовать ScriptEngine eval. Используя Logger, я смог определить, что генерируются исключения NullPointerException. После дальнейшей проверки выясняется, что GAE не всегда возвращает действительный механизм сценариев (если вообще когда-либо), потому что он выдает исключение при попытке его использовать.

Мой код выглядит так:

public double myEval(String JsFormulaStr ) {
    double solutionValue = 0;
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine eng = mgr.getEngineByName("JavaScript");
    if(eng == null) {  // Added this block of code to prevent java.lang.NullPointerException...
        log.severe("Unable to get Script Engine." );
        return 0;
    }
    try {
        Object jsResults = eng.eval(JsFormulaStr);
        solutionValue = Double.parseDouble(jsResults.toString());
        return solutionValue;
    } catch(Exception e) {
        log.severe("[ERROR] in getCalculatedSolution_FromJS_ToDouble()::\n\t" +
                "Formula String is: " + JsFormulaStr + "\n\t" + e);
        return 0;
    }     
}

Все работает нормально, если я запускаю его локально как WebApp (как в Eclipse & Netbeans, так и в Tomcat & Glassfish 4.0).

Некоторые из строк, которые я пытался оценить:

  • 62,0 / 100
  • 0.0 * 352.0
  • (0 - 428) * 1000
  • (0 - 597) * 1000
  • 73,0 / 100

ПРИМЕЧАНИЕ. 0 или 0,0 взяты из других оценок, которые не были выполнены при предыдущих вызовах. Так как эта функция возвращает 0 при ошибке.

Согласно белому списку классов Google JRE, классы ScriptEngineManager и ScriptEngine разрешены. Поэтому я не понимаю, почему это не работает, как ожидалось.

Какие-либо предложения?

Заранее спасибо,

похотливый

1 ответ

Я столкнулся с той же проблемой. Хотя классы занесены в белый список, похоже, что их функциональность ограничена в App Engine. Код прекрасно работает на вашем локальном компьютере, но завершается неудачно при развертывании в App Engine, поскольку нет доступных механизмов сценариев (отсюда и исключение NullPointerException).

К счастью, вы можете сделать то же самое, используя движок Rhino.

Примечание: этот пример основан на примере, заданном Harsha R в /questions/39450440/podderzhivaet-li-google-app-engine-java-script-engine/39450449#39450449

Скачайте Rhino Jar и добавьте js.jar в ваш путь к классам (вам нужен только js-14.jar, если вы используете Java 1.4).

    /* Example 1: Running a JavaScript function (taken from examples) */
    String script = "function abc(x,y) {return x+y;}";
    Context context = Context.enter();
    try {
        ScriptableObject scope = context.initStandardObjects();
        Scriptable that = context.newObject(scope);
        Function fct = context.compileFunction(scope, script, "script", 1, null);
        Object result = fct.call(context, scope, that, new Object[] { 2, 3 });
        System.out.println(Context.jsToJava(result, int.class));
    } 
    finally {
        Context.exit();
    }

    /* Example 2: execute a JavaScript statement */
    script = "3 + 2 * (4*5)";
    context = Context.enter();

    try{
        Scriptable scope = context.initStandardObjects();
        Object result = context.evaluateString(scope, script, "<cmd>", 1, null);
        System.out.println(result);
    }
    finally{
        Context.exit();
    }
Другие вопросы по тегам