2010-05-21 5 views
7

In meinem Code sind alle Skripte in JS-Dateien enthalten. Immer wenn eines der Skripte einen Fehler enthält, bekomme ich folgendes:Ersetzen <Unbekannte Quelle> in Java Rhino (JSR223) mit dem tatsächlichen Dateinamen

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "Nonexistant" ist nicht definiert. (< Quelle unbekannt > # 5) in < Quelle unbekannt > bei Zeilennummer 5

Was nervt mich ist die < unbekannte Quelle >. Mehrere Dateien befinden sich in einem ScriptContext und es kann schwierig sein, einen Fehler zu finden. Es sieht auch schrecklich aus.

Gibt es eine Möglichkeit, < Unbekannte Quelle > mit dem tatsächlichen Dateinamen zu ersetzen? Keine der Methoden, die ich sehe, unterstützt die Übergabe eines Dateiobjekts, daher bin ich hier wirklich verwirrt.

Antwort

9

Über die ScriptEngine.FILENAME Konstante:

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

+0

Danke, es funktioniert! – TheLQ

0

perfekt!

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

Ausgang:

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

Die Frage speziell wurde noch nicht gefragt, aber ich dachte, dass ich dies jeden anbieten würde, die in Zukunft auf dieses Thema stolpern: dies wird als Java ändern 8 wird veröffentlicht und wir bewegen uns von Rhino nach Nashorn als die zugrunde liegende JavaScript-Engine. Unter Nashorn, wird der Dateiname auf die ScriptContext angewandt, anstatt auf die Scriptengine selbst:

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

Wenn Sie die Dateinamen ScriptEngine.put() anzuwenden versuchen, wie Sie unter Rhino tun, wird nichts passieren und Ihre Ausnahmen werden "<eval>" als Dateiname zurückgeben.

Ich könnte mir vorstellen, dass ein paar Leute in den kommenden Monaten auf dieses Problem stoßen werden, also dachte ich würde es anbieten. Dies scheint nirgendwo dokumentiert zu sein. Ich musste in den Nashorn-Quellcode eindringen, um es herauszufinden.

+0

Bonuspunkte für diesen! Java 8 ist lange draußen und Java 9 kommt in Kürze. :) –

3

Die Java 8 (Nashorn) Methode, den Dateinamen für die Skript-Engine über den ScriptContext festzulegen, der von mattj65816 ermittelt wurde, funktioniert auch für die Rhino-Engine. Also würde ich nur

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

empfehlen, da dieses Stück Code für beide gängigen JavaScript-Engines funktioniert. Sie müssen nicht einen eigenen Kontext erstellen, sondern nur das Attribut auf den Standardkontext der Engine setzen: