替换<未知来源>在 Java Rhino (JSR223) 中使用实际文件名

发布于 2024-09-03 00:58:45 字数 363 浏览 7 评论 0原文

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

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "nonexistant" is not Defined。 (<未知来源>#5)在<未知来源>中第 5 行

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

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

In my code, all of the scripts are contained in .js files. Whenever one of the scripts contains an error, I get this:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "nonexistant" is not defined. (<Unknown source>#5) in <Unknown source> at line number 5

What bugs me is the <Unknown Source>. Multiple files are in one ScriptContext, and it can be hard to track down an error. It also looks horrible.

Is there a way to replace <Unknown Source> with the actual file name? None of the methods I see support passing a File object, so I'm really confused here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

看轻我的陪伴 2024-09-10 00:58:45

使用 ScriptEngine.FILENAME 常量:

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

Use the ScriptEngine.FILENAME constant:

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

中性美 2024-09-10 00:58:45

这个问题还没有被专门提出,但我想我会向将来偶然发现这个主题的任何人提供这个:当 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 源代码才能弄清楚。

The question hasn't been specifically asked yet, but I thought I'd offer this to anyone who stumbles upon this topic in the future: this will change when Java 8 is released and we move from Rhino to Nashorn as the underlying JavaScript engine. Under Nashorn, the file name is applied to the ScriptContext, rather than to the ScriptEngine itself:

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" */
}

If you attempt to apply the file name using ScriptEngine.put(), as you do under Rhino, nothing will happen and your exceptions will return "<eval>" as the file name.

I would imagine that a few people will run into this issue in the coming months, so thought I'd offer it. This does not appear to be documented anywhere. I had to dig into the Nashorn source code to figure it out.

╭⌒浅淡时光〆 2024-09-10 00:58:45

通过 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);
    ...
}

The Java 8 (Nashorn) way of setting the filename for the script engine through the ScriptContext figured out by mattj65816, works for the Rhino engine as well. So, I'd recommend using only

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

since this piece of code works for both common JavaScript engines. You don't event need to create you own context, but only set the attribute to the engine's default context:

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);
    ...
}
清音悠歌 2024-09-10 00:58:45

完美的!

    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

perfect!

    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());
    }

output :

Error: test, haha in test1.js at line number 1
Error: test2, haha in test2.js at line number 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文