问题
I am trying to run a javascript script with the new Java 8 Nashorn javascript engine but it fails with the following error:
<eval>:1 ReferenceError: "readFully" is not defined
The script uses the readFully function that should be defined in the global scope nashorn is run with the scripting mode enabled (wich is default when running through a ScriptEngine as seen here http://mail.openjdk.java.net/pipermail/nashorn-dev/2013-December/002562.html).
Here is a sample to reproduce the error:
import java.io.FileNotFoundException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Test {
public static void main(String[] argv) throws FileNotFoundException, ScriptException {
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
scriptEngine.eval("print('Hey!');print(print);print(readFully);");
}
}
This sample prints Hey ! and then the source code of the print function (another nashorn built-in function) and finally it should print the source code of the readFully method. But I have this Exception instead:
Exception in thread "main" javax.script.ScriptException: ReferenceError: "readFully" is not defined in <eval> at line number 1
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:586)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:570)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:525)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:521)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:192)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at com.github.bringking.maven.requirejs.Test.main(Test.java:14)
Caused by: <eval>:1 ReferenceError: "readFully" is not defined
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:58)
at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:320)
at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:292)
at jdk.nashorn.api.scripting.NashornScriptEngine.__noSuchProperty__(NashornScriptEngine.java:272)
at jdk.nashorn.internal.scripts.Script$engine.L:35(nashorn:engine/resources/engine.js:37)
at jdk.nashorn.internal.scripts.Script$\^eval\_.runScript(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:535)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:209)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:568)
... 5 more
When the sample script is run with the nashorn command line with the -scripting parameter (with the jjs tool of the jdk), all is fine. Here is the result of the same script:
Hey!
function print() { [native code] }
function readFully() { [native code] }
I could rewrite a readFully method and bind it with the script context, but I prefer to understand why it does not work and use already built-in functions.
Regards
回答1:
Finally, I have implemented a readFully function that I use in my script (Only compatible with Nashorn):
function readFully(url) {
var result = "";
var imports = new JavaImporter(java.net, java.lang, java.io);
with (imports) {
var urlObj = null;
try {
urlObj = new URL(url);
} catch (e) {
// If the URL cannot be built, assume it is a file path.
urlObj = new URL(new File(url).toURI().toURL());
}
var reader = new BufferedReader(new InputStreamReader(urlObj.openStream()));
var line = reader.readLine();
while (line != null) {
result += line + "\n";
line = reader.readLine();
}
reader.close();
}
return result;
}
回答2:
readFully is not a standard JavaScript function and it is likely not standard in Nashorn either.
There were similar issues when Rhino was chosen for inclusion in the Sun implementation of Java 6. The scripting tool may provide enhancements that are not present in the embedded API. readFully is not a documented function in the Java 8 Nashorn API.
In previous versions of Java the specification stated that provided scripting engines were an implementation detail of the JRE vendor. I am not aware if Java 8 makes anything about the engines provided mandatory or whether it makes any future compatibility guarantees. I would check JSR-337 thoroughly if this was likely to be an issue.
回答3:
https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions
readFully (-scripting mode only)
This function reads the entire contents of a file passed in as a string argument and sends it to stdout, or you can assign the result to a variable.
readFully example:
jjs> readFully("text.txt")
This is the contents of the text.txt file located in the current working directory.
回答4:
readFully is enabled only in scripting mode. Nashorn docs
try this:
>>jjs -scripting
jjs> readFully("your_file")
回答5:
readFully() function is only available as built in function in nashorgn when you enable scripting in you application There are two ways you can do this:-
- pass
-Dnashorn.args=-scripting
when you run your application to enable nashorn scripting - Enable it programmatically by creating Nashorn engine with scripting args
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new String[] { "-scripting" });
来源:https://stackoverflow.com/questions/27788356/readfully-not-defined-with-java-nashorn-javascript-engine