8

在我的代码中,所有脚本都包含在 .js 文件中。每当其中一个脚本包含错误时,我都会得到以下信息:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "nonexistant" 未定义。(<Unknown source>#5) 在 <Unknown source> 的第 5 行

让我烦恼的是<未知来源>。多个文件在一个 ScriptContext 中,很难找到错误。它看起来也很可怕。

有没有办法用实际文件名替换 <Unknown Source> ?我看到的方法都不支持传递 File 对象,所以我在这里真的很困惑。

4

4 回答 4

12

使用 ScriptEngine.FILENAME 常量:

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

于 2010-05-26T23:47:37.010 回答
6

这个问题还没有被特别提出,但我想我会向将来偶然发现这个主题的任何人提供这个问题:当 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 下所做的那样,什么都不会发生,并且您的异常将返回“<eval>”作为文件名。

我想在接下来的几个月里会有一些人遇到这个问题,所以我想我会提供它。这似乎没有记录在任何地方。我不得不深入研究 Nashorn 源代码才能弄清楚。

于 2014-02-11T20:29:00.613 回答
3

通过 mattj65816 发现的 ScriptContext 为脚本引擎设置文件名的 Java 8 (Nashorn) 方法也适用于 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);
    ...
}
于 2014-07-03T17:01:12.600 回答
0

完美的!

    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
于 2013-12-06T02:54:30.037 回答