No. We do not discourage javax.script API. javax.script is the main API. Nashorn specific extension API is in jdk.nashorn.api.* packages.

This undefined to null translation was already discussed -> http://mail.openjdk.java.net/pipermail/nashorn-dev/2016-December/006707.html

javax.script API - which is scripting language independent API - translates undefined to null. Nashorn specific API jdk.nashorn.api.scripting.* does not.

jjs, which is a nashorn specific shell, does not translate undefined.

-Sundar

On 21/12/16, 5:49 PM, Esben Andreasen wrote:
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);
}
}
}

```

Reply via email to