2010-05-21 37 views
7

在我的代碼中,所有腳本都包含在.js文件中。只要其中一個腳本包含錯誤,我就會得到:用實際文件名替換Java Rhino(JSR223)中的<Unknown Source>

javax.script.ScriptException:sun.org.mozilla.javascript.internal.EcmaError:ReferenceError:「nonexistant」未定義。 (<未知源>#5)行號5

在<未知源>我有什麼錯誤的<來源不明>。多個文件位於一個ScriptContext中,並且可能很難找出錯誤。它也看起來很可怕。

有沒有辦法用實際文件名替換<未知源>?我沒有看到支持傳遞File對象的方法,所以我在這裏很困惑。

回答

9

使用ScriptEngine.FILENAME常數:

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

+0

謝謝,它的工作原理! – TheLQ 2010-06-08 00:49:12

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 
6

的問題沒有具體還沒有問過,但我想我會提供給任何人誰在這個話題在未來絆倒:這將改變Java的時候8發佈後,我們將從Rhino轉移到Nashorn作爲基礎JavaScript引擎。在犀牛,文件名被應用到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()的文件名,你犀牛下做的,什麼都不會發生而您的例外將返回「<eval>」作爲文件名。

我想象幾個人會在未來幾個月遇到這個問題,所以我想我會提供它。這似乎沒有記錄在任何地方。我不得不深入研究Nashorn源代碼來弄清楚。

+0

這個獎金積分! Java 8很久了,Java 9即將問世。 :) – 2017-04-28 05:11:08

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); 
    ... 
} 
相關問題