readFully not defined with Java Nashorn Javascript Engine

我们两清 提交于 2019-12-04 21:08:15

问题


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:-

  1. pass -Dnashorn.args=-scripting when you run your application to enable nashorn scripting
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!