【问题标题】:Including a JavaScript file during Rhino eval在 Rhino eval 期间包含一个 JavaScript 文件
【发布时间】:2012-09-11 06:26:50
【问题描述】:

如何将脚本“Bar”包含在另一个脚本“Foo”中,该脚本正在由 Rhino 引擎评估,以 Java 运行。

IE,用Java这样设置脚本引擎:

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

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

load(["Bar.js"])

根据Rhino shell documentation,就是这样做的。但是当从 Java 运行时,它显然没有实现:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "load" is not defined.

@菲利普:

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

首先创建一个引擎,暴露 Invocable 接口:

var engine = new Packages.javax.script.ScriptEngineManager().getEngineByName("javascript");
engine = Packages.javax.script.Invocable(engine);

然后“加载()”脚本

engine.eval(new java.io.FileReader('./function.js'));

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

engine.invokeFunction("printHello", null);

【问题讨论】:

  • 注意:这不是在 Rhino shell 中执行的,也不是在浏览器中执行的。

标签: javascript rhino


【解决方案1】:

我设法通过将引擎传递给自身,然后在 Javascript 代码中对其调用 eval() 来做到这一点:

Java 代码:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.put("engine", engine);
engine.eval(new FileReader("test.js"));

test.js:

engine.eval(new java.io.FileReader('function.js'));
printHello();

function.js:

function printHello() {
    print('Hello World!');
}

输出:

Hello World!

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

【讨论】:

  • “哟,dawg,听说你喜欢ScriptEngines,所以我在你的引擎里装了一个引擎,这样你就可以一边评估一边评估!”
  • 感谢 Philipp,这将在很大程度上起作用。 (见我上面的编辑)
  • 您所做的与我不同的是,您在 Javascript 部分创建了一个新的 ScriptEngine。在调用 eval 跳转到 Javascript 代码之前,我使用 engine.put() 传递了我在 Java 部分中的 ScriptEngine,因此我的引擎已经可用。我对其进行了测试-它完美无缺。当然,这假设您可以控制应用程序的 Java 部分。当您为别人的应用程序编写脚本时,在 Javascript 部分创建 ScriptEngine 是唯一的方法。
猜你喜欢
  • 2012-02-19
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2014-02-08
  • 2010-10-31
相关资源
最近更新 更多