Surprising difference between /usr/bin/jjs and .getEngineByName("JavaScript")

Hannes Wallnöfer hannes.wallnoefer at oracle.com
Wed Dec 21 10:40:20 UTC 2016


Hi Esben,

The reason you get null instead of undefined with the embedded script engine is that undefined is a language specific artefact that can’t be represented in Java. The script API translates undefined to null when it is returned by a script.

Hannes


> Am 21.12.2016 um 11:09 schrieb Esben Andreasen <esben at esbena.dk>:
> 
> Hi
> 
> I am not sure if this is a bug or a problem with my setup.
> I observe a surprising difference between the "external" (jjs) and the
> "internal" (new ScriptEngineManager().getEngineByName("JavaScript"))
> Nashorn when evaluating a regular expression method. The two Nashorns seems
> to be the same, but I am not sure how to check.
> 
> Consider the following two interactions with Nashorn (output manually
> transformed to have the same form):
> 
> ```
> Evaluating in internal Nashorn (new
> ScriptEngineManager().getEngineByName("JavaScript")):
>> java.lang.System.getProperty('java.version')
> 1.8.0_111
>> /(x)(y)?/.exec('x')[2]
> null
> 
> Evaluating in external Nashorn (/usr/bin/jjs):
>> java.lang.System.getProperty('java.version')
> 1.8.0_111
>> /(x)(y)?/.exec('x')[2]
> undefined
> ```
> 
> Observations:
> 1. the Java version for both interactions is the same. I *think* this means
> that the version of Nashorn is the same as well, but I am not sure.
> 2. the two interactions disagree on `null/undefined` as the second entry of
> the result array. The `undefined` value is the correct one according to
> other JavaScript engines.
> 
> Questions:
> 1. Are the two Nashorns of the same version?
> 2. Is the null/undefined discrepancy a bug?
> 
> ---------------------------------------
> 
> Additional content:
> 
> The interactions with the Nashorns where performed with the following Java
> class:
> 
> ```
> import javax.script.ScriptEngine;
> import javax.script.ScriptEngineManager;
> import javax.script.ScriptException;
> import java.io.BufferedReader;
> import java.io.IOException;
> import java.io.InputStreamReader;
> import java.nio.file.Files;
> import java.nio.file.Path;
> import java.util.ArrayList;
> import java.util.Arrays;
> import java.util.List;
> import java.util.function.Function;
> 
> public class NashornTest {
> 
> public static void main(String[] args) throws ScriptException, IOException,
> InterruptedException {
> String javaVersionScript = "java.lang.System.getProperty('java.version')";
> String execScript = "/(x)(y)?/.exec('x')[2]";
> 
> showEvaluation("Evaluating in internal Nashorn (new
> ScriptEngineManager().getEngineByName(\"JavaScript\")):",
> NashornTest::evaluateInternally, javaVersionScript, execScript);
> System.out.println();
> showEvaluation("Evaluating in external Nashorn (/usr/bin/jjs):",
> NashornTest::evaluateExternally, javaVersionScript, execScript);
> }
> 
> private static void showEvaluation(String title, Function<String, String>
> evaluator, String... scripts) {
> System.out.println(title);
> for (String script : scripts) {
> System.out.println("\t> " + script);
> System.out.println("\t" + evaluator.apply(script));
> }
> }
> 
> private static String evaluateInternally(String script) {
> ScriptEngine engine = new
> ScriptEngineManager().getEngineByName("JavaScript");
> try {
> return engine.eval(script) + "";
> } catch (ScriptException e) {
> throw new RuntimeException(e);
> }
> }
> 
> private static String evaluateExternally(String script) {
> Path scriptFile = null;
> try {
> scriptFile = Files.createTempFile("script", ".js");
> Files.write(scriptFile, Arrays.asList(String.format("print(%s);", script)));
> 
> Process process = Runtime.getRuntime().exec(new String[]{"/usr/bin/jjs",
> scriptFile.toAbsolutePath().toString()});
> BufferedReader stdInput = new BufferedReader(new
> InputStreamReader(process.getInputStream()));
> List<String> lines = new ArrayList<>();
> String line;
> while ((line = stdInput.readLine()) != null) {
> lines.add(line);
> }
> return String.join("\n", lines);
> } catch (IOException e) {
> throw new RuntimeException(e);
> }
> }
> }
> 
> ```



More information about the nashorn-dev mailing list