Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I run ECMAScript 6 from Java 9 Nashorn engine

Java 9 now includes ECMAScript 6 support, as claimed by this article. However, it doesn't explain how to run it from Java with ScriptEngine. The linked Java magazine also doesn't explain it. The article says the following:

To activate ES6 support, use --language=es6 on the command line.

This does work with jjs, but I can't find a way how to enable this from Java code. To test it, I used the following code:

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();
}

It fails with the following exception:

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]

I've tried to list all available ScriptEngineFactories with this code:

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());
}

This outputs just the following:

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

Does this mean I can't run ECMAScript 6 from Java and only using jjs? Or is there something I have missed?

Thanks beforehand.

like image 291
TheZeus121 Avatar asked Feb 21 '18 17:02

TheZeus121


1 Answers

While browsing through Nashorn questions here, I stumbled upon this question. Its answers describe two ways how to pass Nashorn engine commandline arguments. This answer suggests to use NashornScriptEngineFactory directly, code following:

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();
}

Even though this works, it's not a nice solution because it makes you use jdk package which is not an officially supported package. Another answer says you can set the arguments with system property nashorn.args. Code:

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();
}

This also isn't a nice way of doing it, because it relies on:

  • Nashorn engine existing which may not be the case on other Java distributions, and
  • Nashorn engine being up-to-date to support the language command line parameter.

I, personally, prefer the first version, because it will throw a ClassNotFoundException on Java 1.8 since NashornScriptEngineFactory doesn't exist there, while the second version will just silently ignore the setting of property.

like image 154
TheZeus121 Avatar answered Oct 01 '22 05:10

TheZeus121