Полностью не определено с 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, когда вы включаете скрипты в своем приложении. Есть два способа сделать это:-
- проходить
-Dnashorn.args=-scripting
когда вы запускаете свое приложение, чтобы включить сценарии nashorn - Включите его программно, создав движок Nashorn с аргументами сценария
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new String[] { "-scripting" });