当带有绑定的eval时,Nashorn找不到函数

时间:2015-10-03 14:27:18

标签: javascript java nashorn scriptengine

当我使用或不使用绑定来评估nashorn脚本时,有一个奇怪的区别:没有绑定,调用函数没有问题,但是使用绑定时找不到该函数。这是一个例子:

public class SimpleNashornTester {

    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn");
        Compilable jsCompilable = (Compilable) jsEngine;
        Invocable jsInvocable = (Invocable) jsEngine;

        ScriptContext scriptCtxt = new SimpleScriptContext();
        Bindings engineScope = scriptCtxt.getBindings(ScriptContext.ENGINE_SCOPE);
        CompiledScript jsScript = jsCompilable.compile("function definition() {print(\"Hello\")}");
        jsScript.eval(engineScope); // no error with jsScript.eval() !
        jsInvocable.invokeFunction("definition", new Object[] {});
    }
}

这会产生错误:

Exception in thread "main" java.lang.NoSuchMethodException: No such function definition
    at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:204)

在评估脚本时没有参数engineScope,可以找到并调用该函数。任何人都能解释这种差异吗?如何在不出错的情况下使用绑定?

1 个答案:

答案 0 :(得分:3)

您正在使用新的ScriptContext,并且它与ENGINE_SCOPE绑定相关联以编译脚本。 invokeFunction / invokeMethod使用默认的ScriptContext(及其关联的ENGINE_SCOPE Bindings)来搜索函数。每个不同的ENGINE_SCOPE绑定都与其自己的ECMAScript全局对象(以及它自己的ECMAScript全局对象)相关联。

所以,您可以通过

修复您的程序
  1. 在调用之前将默认上下文更改为新上下文:

    // change the default ScriptContext
    jsEngine.setContext(scriptCtxt);
    jsInvocable.invokeFunction("definition", new Object[] {});
    
  2. 也可以使用默认的ScriptContext编译脚本。如:

    ScriptContext scriptCtxt = jsEngine.getContext(); // new SimpleScriptContext();