我可以从Java 9 Nashorn引擎运行ECMAScript 6吗?

时间:2018-02-21 17:23:44

标签: javascript java nashorn

Java 9现在包含了this article所声称的ECMAScript 6支持。但是,它没有解释如何使用ScriptEngine从Java运行它。链接的Java杂志也没有解释它。文章说:

  

要激活ES6支持,请在命令行中使用--language=es6

这适用于jjs,但我找不到如何从Java代码启用此功能的方法。为了测试它,我使用了以下代码:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
...
ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType("application/javascript");
try {
    engine.eval("const a = 20;");
} catch (ScriptException e) {
    e.printStackTrace();
}

失败,出现以下异常:

javax.script.ScriptException: <eval>:1:0 Expected an operand but found const
const a = 20;
^ in <eval> at line number 1 at column number 0
    [STACK TRACE OMITTED]

我尝试使用以下代码列出所有可用的ScriptEngineFactories

import java.util.List;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
...
List<ScriptEngineFactory> factories = new ScriptEngineManager().getEngineFactories();
for (ScriptEngineFactory factory : factories) {
    System.out.println("-----------------------");
    System.out.println(factory.getLanguageName());
    System.out.println(factory.getLanguageVersion());
}

这只输出以下内容:

-----------------------
ECMAScript
ECMA - 262 Edition 5.1

这是否意味着我无法从Java运行ECMAScript 6而只能使用jjs?或者有什么我错过了吗?

事先谢谢。

1 个答案:

答案 0 :(得分:9)

在浏览Nashorn问题时,我偶然发现了this question。它的答案描述了如何传递Nashorn引擎命令行参数的两种方法。 This answer建议直接使用NashornScriptEngineFactory,代码如下:

import javax.script.ScriptEngine;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
...
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine("--language=es6");
try {
    engine.eval("const a = 20;\n"
            + "print(a);");
} catch (ScriptException e) {
    e.printStackTrace();
}

尽管这有效,但它并不是一个很好的解决方案,因为它会让你使用jdk包而不是官方支持的包。 Another answer表示您可以使用系统属性nashorn.args设置参数。代码:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
...
System.setProperty("nashorn.args", "--language=es6");
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
try {
    engine.eval("const a = 20;\n"
            + "print(a);");
} catch (ScriptException e) {
    e.printStackTrace();
}

这也不是一个好方法,因为它依赖于:

  • 存在Nashorn引擎,其他Java发行版可能不是这种情况,
  • Nashorn引擎是最新的,以支持language命令行参数。

我个人更喜欢第一个版本,因为它会在Java 1.8上抛出ClassNotFoundException,因为NashornScriptEngineFactory不存在,而第二个版本只是默默地忽略属性的设置。