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 <es...@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); > } > } > } > > ```