Nashorn将compiledscript放入引擎范围



我有两个js文件,

  • 一个是js库
  • 第二个是一个简单的脚本,通常大约50行,需要访问库中的函数

在我的项目中,我试图在应用程序启动期间预编译所有java脚本,然后在运行时只使用所需的参数调用CompiledScripts。

我最终得到了以下代码


static String LIBRARY = "function hello(arg) {return 'Hello ' + arg;};";
static String SCRIPT = "hello(arg)";
public static void main(String... args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
Compilable compilable = ((Compilable) engine);
CompiledScript compiledLib = compilable.compile(LIBRARY);
compiledLib.eval();
CompiledScript actualScript = compilable.compile(SCRIPT);
Bindings helloParams = new SimpleBindings();
helloParams.put("arg","world");
ScriptObjectMirror result = (ScriptObjectMirror) actualScript.eval(helloParams);
System.out.println(result);
}

但是这个代码抛出一个错误

> compiledScript.eval(helloParams);
<eval>:1 ReferenceError: "hello" is not defined

如何从"actualScript"中访问"compiledLib"(即方法和变量(的上下文?

编译不注册hello()函数,它只是解析JavaScript代码。

您需要执行要注册的函数的代码。

请记住,在JavaScript中,这两个语句之间几乎没有什么区别,除了function声明是挂起的,因此可以在声明语句之前使用:

function hello(arg) {return 'Hello ' + arg;};
var hello = function(arg) {return 'Hello ' + arg;};

因此,没有什么理由单独编译LIBRARY代码,只需运行它并保存所有创建的全局变量,即库方法。例如,在执行LIBRARY代码后,您将拥有一个名为hello的全局变量。


ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
Compilable compilable = ((Compilable) engine);
// Process LIBRARY code
Bindings bindings = new SimpleBindings();
engine.eval(LIBRARY, bindings);
// Compile SCRIPT code
CompiledScript actualScript = compilable.compile(SCRIPT);
// Run SCRIPT code
bindings.put("foo", "world");
Object result = actualScript.eval(bindings);
System.out.println(result);

输出

Hello world

最新更新