Полностью не определено с Java Nashorn Javascript Engine

Я пытаюсь запустить сценарий javascript с новым механизмом javascript Java 8 Nashorn, но он завершается ошибкой со следующей ошибкой:

<eval>:1 ReferenceError: "readFully" is not defined

В сценарии используется функция readFully, которая должна быть определена в глобальной области действия. Nashorn запускается с включенным режимом сценариев (который используется по умолчанию при запуске через ScriptEngine, как показано здесь http://mail.openjdk.java.net/pipermail/nashorn-dev/2013-December/002562.html).

Вот пример для воспроизведения ошибки:

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);");


    }
}

Этот образец печатает Эй! а затем исходный код функции печати (еще одна встроенная функция nashorn) и, наконец, он должен напечатать исходный код метода readFully. Но у меня есть это исключение:

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

Когда образец сценария запускается с помощью командной строки nashorn с параметром -scripting (с помощью инструмента jjs jdk), все в порядке. Вот результат того же сценария:

Hey!
function print() { [native code] }
function readFully() { [native code] }

Я мог бы переписать метод readFully и связать его с контекстом скрипта, но я предпочитаю понять, почему он не работает, и использовать уже встроенные функции.

С уважением

4 ответа

Решение

Наконец, я реализовал функцию readFully, которую я использую в своем скрипте (совместимо только с 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;
}

readFully не является стандартной функцией JavaScript и, вероятно, не является стандартной в Nashorn.

Были аналогичные проблемы, когда Rhino был выбран для включения в реализацию Java 6. Sun. Инструмент сценариев может предоставлять улучшения, которых нет во встроенном API. readFully не является документированной функцией в Java 8 Nashorn API.

В предыдущих версиях Java в спецификации указывалось, что предоставляемые механизмы сценариев являются деталями реализации поставщика JRE. Я не знаю, делает ли Java 8 что-нибудь о предоставляемых движках в обязательном порядке или дает ли она какие-либо гарантии совместимости в будущем. Я бы тщательно проверил JSR-337, если это может быть проблемой.

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions

readFully (только в режиме -скрипт)

Эта функция читает все содержимое файла, переданного в качестве строкового аргумента, и отправляет его в стандартный вывод, или вы можете присвоить результат переменной.

прочитайте полностью пример:

jjs> readFully("text.txt") This is the contents of the text.txt file located in the current working directory.

readFully включен только в режиме сценариев. Нашорн документы

попробуй это:

>>jjs -scripting
jjs> readFully("your_file")

Функция readFully() доступна только как встроенная функция в nashorgn, когда вы включаете скрипты в своем приложении. Есть два способа сделать это:-

  1. проходить -Dnashorn.args=-scripting когда вы запускаете свое приложение, чтобы включить сценарии nashorn
  2. Включите его программно, создав движок Nashorn с аргументами сценария
    NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
    ScriptEngine engine = factory.getScriptEngine(new String[] { "-scripting" });
    
Другие вопросы по тегам