Hi Hannes Thank you for that explanation.
A follow-up, if allowed: I understand the motivation for eliminating `undefined`, but I would really like a way that I could avoid that elimination. Is that a discouraged use of the API? Implementation-wise: I see that `ScriptObjectMirror.translateUndefined` does the conversion from JavaScript `undefined` to Java `null`. I assume I could make a lightly edited copy of NashornScriptEngine.java that omits the call to `translateUndefined` to get the effect I want. Or is there a more elegant solution somewhere? On Wed, Dec 21, 2016 at 11:40 AM Hannes Wallnöfer < hannes.wallnoe...@oracle.com> wrote: > 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 <21%2012%2020%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); > > } > > } > > } > > > > ``` > >