2016-03-08 48 views
0

犀牛让我在一个新的范围评估的JavaScript,像这样:我可以在Nashorn的新引擎范围中调用函数吗?

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...)的类似功能。

有谁知道我该怎么做我想做的?这种不对称是否有充分的理由?

+0

是不是'ENGINE_SCOPE'的默认值?这就是示例8中提到的内容https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/api.html:*默认脚本上下文至少有一个作用域,由静态字段ENGINE_SCOPE。* – Tunaki

+0

也许我不清楚:我想改变引擎作用域的绑定来调用函数,类似于我可以用eval()做的事情。 – Sebastian

回答

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例外。

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

相关问题