замещатьв Java Rhino (JSR223) с реальным именем файла - PullRequest
7 голосов
/ 21 мая 2010

В моем коде все сценарии содержатся в файлах .js. Всякий раз, когда один из сценариев содержит ошибку, я получаю это:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: «несуществующий» не определен. (<Неизвестный источник> # 5) в <Неизвестный источник> в строке № 5

Что меня беспокоит, так это <Неизвестный источник>. Несколько файлов находятся в одном ScriptContext, и может быть трудно отследить ошибку. Это также выглядит ужасно.

Есть ли способ заменить <Неизвестный источник> реальным именем файла? Ни один из методов, которые я вижу, не поддерживает передачу объекта File, поэтому я действительно запутался здесь.

Ответы [ 4 ]

9 голосов
/ 27 мая 2010

Используйте константу ScriptEngine.FILENAME:

scriptEngine.put (ScriptEngine.FILENAME, scriptFile.toString ());

6 голосов
/ 12 февраля 2014

Вопрос еще специально не задавался, но я подумал, что предложу это всем, кто наткнется на эту тему в будущем: это изменится, когда выйдет Java 8, и мы переместимся из Rhino в Nashorn в качестве основногоДвижок JavaScript.В Nashorn имя файла применяется к ScriptContext, а не к самому ScriptEngine:

ScriptContext context = new SimpleScriptContext();
context.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
try
{
    engine.eval(script, context);
}
catch (ScriptException e)
{
    /* e.getFileName() will return "test.js" */
}

Если вы попытаетесь применить имя файла с помощью ScriptEngine.put (), как это делается в Rhino, ничегопроизойдет, и ваши исключения вернут "" в качестве имени файла.

Я бы предположил, что несколько человек столкнутся с этой проблемой в ближайшие месяцы, поэтому подумал, что предложу его.Это, кажется, нигде не задокументировано.Мне пришлось копаться в исходном коде Nashorn, чтобы понять это.

3 голосов
/ 03 июля 2014

Java 8 (Nashorn) способ задания имени файла для обработчика сценариев через ScriptContext, рассчитанный с помощью mattj65816, также работает для механизма Rhino.Поэтому я бы рекомендовал использовать только

context.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);

, поскольку этот фрагмент кода работает для обоих распространенных механизмов JavaScript.Вам не нужно создавать собственный контекст, а только установить атрибут в контекст двигателя по умолчанию:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
if (engine != null) {
    ScriptContext ctx = engine.getContext();
    ctx.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
    ...
}
0 голосов
/ 06 декабря 2013

идеально!

    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
    // javax.script.filename
    engine.put(ScriptEngine.FILENAME, "test1.js");
    try {
        engine.eval("function throwError1(){throw new Error('test, haha')}");
    } catch (ScriptException e) {
    }       

    engine.put(ScriptEngine.FILENAME, "test2.js");
    try {
        engine.eval("function throwError2(){throw new Error('test2, haha')}");
    } catch (ScriptException e) {
    }
    try {
        engine.eval("throwError1()");
    } catch (ScriptException e) {
        System.out.println(e.getMessage());
    }
    try {
        engine.eval("throwError2()");
    } catch (ScriptException e) {
        System.out.println(e.getMessage());
    }

вывод:

Error: test, haha in test1.js at line number 1
Error: test2, haha in test2.js at line number 1
...