我遇到的问题是,当我尝试使用ScriptEngine eval时,我总是会返回0值。通过使用Logger,我能够确定是否正在生成NullPointerExceptions。经过进一步检查后,看来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中),一切正常。
我试图评估的一些字符串:
注意:0或0是来自其他评估,这些评估在之前的呼叫中失败。由于此函数在出错时返回0。
根据Google's JRE Class Whitelist,允许使用ScriptEngineManager和ScriptEngine类。所以我不明白为什么它没有按预期工作。
有什么建议吗?
提前致谢,
兰迪
答案 0 :(得分:0)
我遇到了同样的问题。尽管这些类已列入白名单,但它们的功能似乎仅限于App Engine。代码在本地计算机上运行正常但在部署到App Engine时失败,因为没有可用的脚本引擎(因此NullPointerException)。
幸运的是,你可以使用Rhino引擎做同样的事情。
注意:此示例基于Harsha R在https://stackoverflow.com/a/19828128/578821
中提供的示例下载Rhino Jar并将js.jar添加到您的类路径中(如果您正在使用Java 1.4,则只需要js-14.jar)。
/* 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();
}