Surprising difference between /usr/bin/jjs and .getEngineByName("JavaScript")
Esben Andreasen
esben at esbena.dk
Wed Dec 21 10:09:22 UTC 2016
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