2010-05-21 16 views
7

Trong mã của tôi, tất cả các tập lệnh được chứa trong tệp .js. Bất cứ khi nào một trong các tập lệnh có lỗi, tôi nhận được thông báo này:Thay thế <Nguồn không xác định> trong Java Rhino (JSR223) bằng tên tệp thực tế

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: Tham chiếuGỗi: "không tồn tại" không được xác định. (< nguồn Unknown > # 5) trong < nguồn Unknown > tại dòng số 5

gì làm tôi phát cáu là < Unknown Source >. Nhiều tệp nằm trong một ScriptContext và có thể khó theo dõi lỗi. Nó cũng có vẻ khủng khiếp.

Có cách nào thay thế < Nguồn không xác định > bằng tên tệp thực tế không? Không có phương pháp nào tôi thấy hỗ trợ truyền qua đối tượng Tệp, vì vậy tôi thực sự bối rối ở đây.

Trả lời

9

Sử dụng hằng số ScriptEngine.FILENAME:

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

+0

Cảm ơn, nó hoạt động! – TheLQ

0

hoàn hảo!

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

đầu ra:

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

Câu hỏi đặt ra đã không được yêu cầu đặc biệt nào, nhưng tôi nghĩ rằng tôi muốn cung cấp này cho bất cứ ai tình cờ gặp chủ đề này trong tương lai: điều này sẽ thay đổi khi Java 8 được phát hành và chúng tôi chuyển từ Rhino sang Nashorn như một công cụ JavaScript cơ bản. Dưới Nashorn, tên tệp được áp dụng cho các ScriptContext, chứ không phải cho bản thân 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" */ 
} 

Nếu bạn cố gắng áp dụng các tên file sử dụng ScriptEngine.put(), như bạn làm theo Rhino, không có gì sẽ xảy ra và ngoại lệ của bạn sẽ trả lại "<eval>" làm tên tệp.

Tôi sẽ tưởng tượng rằng một vài người sẽ gặp sự cố này trong những tháng tới, vì vậy tôi nghĩ tôi sẽ cung cấp. Điều này dường như không được ghi lại ở bất cứ đâu. Tôi phải đào sâu vào mã nguồn Nashorn để tìm ra.

+0

Điểm thưởng cho điểm này! Java 8 dài và Java 9 sắp ra mắt. :) –

3

Cách Java 8 (Nashorn) để đặt tên tệp cho công cụ tập lệnh thông qua ScriptContext được Mattj65816 tìm ra, cũng hoạt động với công cụ Rhino. Vì vậy, tôi khuyên bạn chỉ nên sử dụng

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

vì đoạn mã này hoạt động cho cả hai công cụ JavaScript phổ biến. Bạn không cần phải tạo bối cảnh riêng cho mình, nhưng chỉ đặt thuộc tính thành ngữ cảnh mặc định của công cụ:

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); 
    ... 
} 
Các vấn đề liên quan