JavaScript ScriptEngine isn't working within Google App Engine for Java (GAE/J)

喜夏-厌秋 提交于 2019-12-25 02:53:52

问题


I am having an issue where I always get a 0 value returned when I try to use the ScriptEngine eval. By using Logger, I was able to determine that there are NullPointerExceptions being generated. After further inspection, it appears that GAE doesn't always return a valid script engine (if ever), because it throws an exception when you try to use it.

My code looks like:

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;
    }     
}

Everything works fine if I run it locally as a WebApp (Both in Eclipse & Netbeans. And within Tomcat & Glassfish 4.0).

Some of the strings which I tried to eval:

  • 62.0 / 100
  • 0.0 * 352.0
  • (0 - 428) * 1000
  • (0 - 597) * 1000
  • 73.0 / 100

NOTE: The 0's or 0.0's are from other evaluations which have failed in previous calls. Since this function returns 0 on error.

According to Google's JRE Class Whitelist, the ScriptEngineManager and ScriptEngine classes are allowed. So I don't understand why it isn't working as expected.

Any suggestions?

Thanks in advance,

Randy


回答1:


I've hit the same problem. Although the classes are whitelisted, it seems like their functionality is limited on App Engine. The code works fine on your local machine but fails when deployed to App Engine as there aren't any script engines available (hence the NullPointerException).

Luckily, you can do the same thing using the Rhino engine.

Note: this example builds on that given by Harsha R in https://stackoverflow.com/a/19828128/578821

Download the Rhino Jar and add js.jar to your classpath (you only need js-14.jar if you're using 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();
    }


来源:https://stackoverflow.com/questions/23188807/javascript-scriptengine-isnt-working-within-google-app-engine-for-java-gae-j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!