在Rhino eval期间包含JavaScript文件

Rob*_*ian 3 javascript rhino

如何在由Java运行的Rhino Engine评估的另一个脚本"Foo"中包含一个脚本"Bar".

IE,在Java中设置这样的脚本引擎:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
BufferedReader br = new BufferedReader(new FileReader(new File("Foo.js")));
engine.eval(br);
Run Code Online (Sandbox Code Playgroud)

......并将以下内容放入Foo:

load(["Bar.js"])
Run Code Online (Sandbox Code Playgroud)

根据Rhino shell文档,这是实现它的方法.但是从Java运行时,它显然没有实现:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "load" is not defined.
Run Code Online (Sandbox Code Playgroud)

@Phillip:

感谢您的创意回应.您的解决方案不太有效,因为除非使用Invocable接口,否则eval不会使解析的函数可用.此外,它在Java代码不可访问的情况下不起作用.我详细阐述了你的解决方法并创建了一些适用于纯JS的东西:

首先创建一个引擎,公开Invocable接口:

var engine = new Packages.javax.script.ScriptEngineManager().getEngineByName("javascript");
engine = Packages.javax.script.Invocable(engine);
Run Code Online (Sandbox Code Playgroud)

然后"加载()"脚本

engine.eval(new java.io.FileReader('./function.js'));
Run Code Online (Sandbox Code Playgroud)

此时,可以使用以下方法评估函数:

engine.invokeFunction("printHello", null);
Run Code Online (Sandbox Code Playgroud)

Phi*_*ipp 5

我设法通过将引擎传递给自己然后在Javascript代码中调用它上面的eval()来实现:

Java代码:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.put("engine", engine);
engine.eval(new FileReader("test.js"));
Run Code Online (Sandbox Code Playgroud)

test.js:

engine.eval(new java.io.FileReader('function.js'));
printHello();
Run Code Online (Sandbox Code Playgroud)

function.js:

function printHello() {
    print('Hello World!');
}
Run Code Online (Sandbox Code Playgroud)

输出:

Hello World!
Run Code Online (Sandbox Code Playgroud)

我不知道这是否是最优雅的方式,但它确实有效.

  • "哟,dawg,我听说你喜欢ScriptEngines,所以我把引擎放在你的引擎中,所以你可以在你评估时评估!" (7认同)