【问题标题】:Can I invoke a function in a new engine scope with Nashorn?我可以使用 Nashorn 在新引擎范围内调用函数吗?
【发布时间】:2016-03-08 22:41:52
【问题描述】:

Nashorn 允许我在新范围内评估 JavaScript,如下所示:

public Object evalInNewScope(String code, Bindings bindings) throws Exception  {
    ScriptContext context = new SimpleScriptContext();
    context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
    return engine.eval(code, context);
}

这对线程安全很有好处:引擎实例可以跨线程重复使用,每个线程都可以使用特定于线程的绑定进行自己的调用。

但是,我还没有为Invocable#invokeFunction(String, Object...) 找到类似的功能。

有谁知道我怎样才能做我想做的事?这种不对称有充分的理由吗?

【问题讨论】:

  • ENGINE_SCOPE 不是默认的吗?这就是 docs.oracle.com/javase/8/docs/technotes/guides/scripting/… 的示例 8 中提到的内容:默认脚本上下文至少有一个由静态字段 ENGINE_SCOPE 表示的范围。
  • 也许我不清楚:我想更改函数调用的引擎范围绑定,类似于我可以使用 eval() 执行的操作。

标签: javascript multithreading java-8 nashorn


【解决方案1】:

invokeFunction 仅从当前上下文调用函数,不能直接提供上下文。

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

ScriptContext ctx = new SimpleScriptContext();
ctx.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
engine.eval("function hello() { return 'Hello!'; }", ctx);
engine.setContext(ctx);

((Invocable) engine).invokeFunction("hello");

删除engine.setContext(ctx) 行将导致java.lang.NoSuchMethodException: No such function hello 异常。

根据您的情况,您可能需要重新设置原始上下文!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多