การแชร์วัตถุ Java ใน Rhino Javascript

ก่อนอื่นให้ฉันเริ่มต้นด้วยการยอมรับว่าฉันเป็น noob ใน JavaScript ดังนั้นคำถามอาจไม่ชัดเจนในระดับพื้นฐานและอาจขาดข้อมูลเพียงพอที่จะช่วยฉันได้

พื้นหลัง

องค์กรของฉันมี IDE ที่ใช้ Eclipse ภายในสำหรับ JavaScript สิ่งที่เราต้องทำคือเขียนสคริปต์ใน JavaScript และดำเนินการโดยตรง ฉันเดาว่ามันใช้ Rhino เนื่องจากฉันได้เห็นมันในการติดตามสแต็กของข้อยกเว้นบางประการ

รหัสของฉันทำงานในไฟล์ ".js" 3 ไฟล์

สคริปต์-1: ประกาศตัวแปรโกลบอลและสร้างอินสแตนซ์ให้เป็นอ็อบเจ็กต์ Java

importClass(java.util.HashMap);
var hmTCResult = new HashMap();

Script-2: ดำเนินการบางอย่างโดยใช้ตัวแปรร่วมจาก Script-1

Script-2.prototype.run = function() {
hmTCResult.put("Result", "Fail");
};

changeStatus = function(strStatus){
hmTCResult.put("Result", strStatus);
};

Script-3: ฟังก์ชันการโทรใน Script-2 ซึ่งใช้ตัวแปรส่วนกลาง

changeStatus("Pass") 

คำจำกัดความของปัญหา

เมื่อมาจาก Script-3 ฉันเรียกใช้ฟังก์ชันใน Script-2 ดูเหมือนจะไม่เลือกตัวแปรอินสแตนซ์และฟังก์ชันของฉันก็ล้มเหลว กล่าวคือ ฉันได้รับข้อยกเว้น "hmTCResult ไม่ได้ตั้งค่าเป็นอินสแตนซ์ของวัตถุ" โปรดทราบว่าตัวแปรเดียวกัน hmTCResult ทำงานได้ดีในสคริปต์ 1

ฉันได้อ่านขอบเขตและบริบทใน JavaScript แล้ว แต่ยังไม่สามารถเจาะลึกได้ เนื่องจากฉันไม่เห็นอย่างชัดเจนใน IDE

เรายินดีที่จะให้ข้อมูลเพิ่มเติมหากจำเป็น


person wanderlust    schedule 21.10.2012    source แหล่งที่มา
comment
ฉันไม่คิดว่ามีวัตถุ Java ใด ๆ ที่ใช้ร่วมกันซึ่งมีความสำคัญสำหรับคุณ โปรดแสดงส่วนที่เกี่ยวข้องของโค้ดของคุณให้เราทราบ เช่น การประกาศฟังก์ชันนั้นในสคริปต์ 2 การเรียกใช้ในสคริปต์ 3 และชี้ไปที่ตัวแปรที่คุณต้องการใช้แต่ไม่มี   -  person Bergi    schedule 21.10.2012
comment
คุณช่วยบอกรหัสเราหน่อยได้ไหม?   -  person Aadit M Shah    schedule 21.10.2012
comment
คำถามอัปเดตด้วยรหัส ฉันขอโทษที่ฉันไม่สามารถให้รหัสที่สมบูรณ์ได้ ขอบคุณล่วงหน้าสำหรับความช่วยเหลือ   -  person wanderlust    schedule 21.10.2012
comment
ฉันไม่มีประสบการณ์กับ Java/Rhino แต่ Script-2 ไม่ใช่ตัวระบุ JavaScript ที่ถูกต้อง ตั้งชื่อมันว่า Script2 หรือ Script_2   -  person J. K.    schedule 21.10.2012
comment
ขอบคุณเอียน แต่ชื่อสคริปต์ที่กล่าวถึงมีไว้เพื่อเป็นภาพประกอบเท่านั้น ชื่อสคริปต์จริงนั้นถูกต้องมาก   -  person wanderlust    schedule 21.10.2012
comment
ดูเหมือนว่า hmTCResult ไม่ใช่ตัวแปรร่วมจริงๆ เหมือนที่ changeStatus เป็น บางทีสภาพแวดล้อมการเขียนสคริปต์ของคุณ (ฉันไม่รู้ว่าไฟล์สคริปต์สามไฟล์ของคุณทำงานอย่างไร) ดำเนินการทุกอย่างในขอบเขตทั้งไฟล์ ลองลบคำหลัก var หรือกำหนด hmTCResult ให้กับวัตถุส่วนกลางของคุณอย่างชัดเจน   -  person Bergi    schedule 21.10.2012
comment
ขอบคุณ Bergi สำหรับคำตอบ ฉันพยายามลบคีย์เวิร์ด var ออก แต่ก็ไม่มีโชค ฉันทำ Google และพบว่าฉันสามารถใช้ window.hmTCResult เพื่อเพิ่มลงในวัตถุส่วนกลางได้อย่างชัดเจน อย่างไรก็ตาม เนื่องจากนี่ไม่ใช่ JavaScript ที่สามารถดำเนินการได้ในเบราว์เซอร์ ฉันไม่แน่ใจว่าจะใช้งานได้หรือไม่ มีวิธีอื่นใดที่ฉันสามารถมอบหมายให้กำหนดให้กับวัตถุส่วนกลางได้   -  person wanderlust    schedule 21.10.2012


คำตอบ (3)


ในการประเมินสคริปต์ js ใน Java การดำเนินการต่อไปนี้อาจดำเนินการได้

ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType( "text/javascript" );
Bindings bindings = engine.getBindings( ScriptContext.GLOBAL_SCOPE );
bindings.put( "varname", ... );
bindings.put( ... );
engine.put( ScriptEngine.FILENAME, script.toString());
engine.eval( new FileReader( script ));

หากโหลดสคริปต์ทั้ง 3 ตัวภายในกลไก/การเชื่อมโยงเดียวกัน ก็ไม่เป็นไร แต่หากกลไกได้รับการจัดสรรใหม่สำหรับเรียกใช้สคริปต์ 3 บริบทก็จะถูกล้างออกไป

โพสต์นี้ไม่ใช่คำตอบจริงๆ แต่ยาวเกินกว่าจะแสดงความคิดเห็น

person Aubin    schedule 22.10.2012
comment
ขอบคุณออบิน. ดังที่ฉันได้กล่าวถึงเครื่องมือของฉัน แม้ว่าจะใช้ Eclipse แต่ก็ทำงานเหมือนกับ JavaScript IDE มากกว่า ฉันไม่เห็นโค้ด Java ในเครื่องมือ - person wanderlust; 23.10.2012
comment
โอเค ฉันไม่เข้าใจเรื่องนั้น ฉันได้ติดแท็กคำถามของคุณใหม่โดยลบ Java เนื่องจากใช้ไม่ได้ - person Aubin; 23.10.2012
comment
ออบิน ฉันไม่เห็นด้วย หากคุณเห็นคำถามของฉัน ฉันกำลังใช้คลาส Java ภายใน JavaScript ดังนั้นแท็ก Java จึงมีความเกี่ยวข้อง - person wanderlust; 23.10.2012

ฉันเดาว่าหากไม่มีข้อมูลเพิ่มเติม และสมมติว่าการถอดเสียงที่แก้ไขของคุณถูกต้องอย่างแน่นอน ก็คือสคริปต์ของคุณทำงานในขอบเขตที่แยกจากกัน โดยทั้งหมดจะมีขอบเขตส่วนกลางเป็นพาเรนต์

ด้วยเหตุนี้ ฉันเดาว่าเหตุผลที่ changeStatus ทำงานในสคริปต์ที่สามเป็นเพราะไม่มีการประกาศ var ดังนั้น หากไม่มีการกำหนดค่าอื่น สิ่งนี้จะถูกกำหนดให้เป็นตัวแปรในขอบเขตระดับบนสุดหรือระดับโลก ที่ใช้ร่วมกันระหว่างสคริปต์ทั้งสาม

ฉันเดาว่าเหตุผลที่ hmTCResult ไม่ ทำงานก็เพราะว่ามีการประกาศด้วยคำหลัก var ซึ่งระบุตัวแปรท้องถิ่น หากสคริปต์ทั้งหมดทำงานในขอบเขตระดับบนสุด สิ่งนี้จะกำหนดตัวแปรบนออบเจ็กต์โกลบอล แต่ถ้าแต่ละสคริปต์ทำงานในขอบเขตของตัวเอง สิ่งนี้จะกำหนดตัวแปรเฉพาะในขอบเขตของสคริปต์ 1 คุณจะไม่เห็นปัญหาในขอบเขตของสคริปต์ 2 เนื่องจากไม่มีใครรันโค้ดในสคริปต์ 2 จนถึงสคริปต์ 3 ดำเนินการ

person David P. Caldwell    schedule 21.11.2012

วิธีนี้ใช้ได้ผลดี เพียงปรับขอบเขตและตั้งค่าการค้นหาต้นแบบ:

Context cx = Context.enter();
try {
    // Cache and reuse:
    ScriptableObject sealedSharedScope = cx.initStandardObjects(null,
            true);
    // Force the LiveConnect stuff to be loaded.
    String loadMe = "RegExp; getClass; java; Packages; JavaAdapter;";
    cx.evaluateString(sealedSharedScope, loadMe, "preLoadLazyLoad", 0,
            null);

    cx.evaluateString(sealedSharedScope, "varInRoot = 'blah';",
            "setVarInRoot", 0, null);

    // here you can put more cx.evaluateString calls to set up your
    // environment (eg. hmTCResult)

    // now connect a throw-away new scope into the hierarchy, with local
    // vars:
    Scriptable scope = cx.newObject(sealedSharedScope);
    // ensure that definitions in the root scope are found
    scope.setPrototype(sealedSharedScope);
    // ensure that new global variables are created in this scope (don't
    // use
    // var for them!)
    scope.setParentScope(null);

    cx.evaluateString(scope, "localVar = varInRoot;", "mySource", 0,
            null);
    assertEquals("blah", scope.get("localVar", scope).toString());
    // new var not in root:
    assertEquals(ScriptableObject.NOT_FOUND,
            sealedSharedScope.get("localVar", scope));
} finally {
    Context.exit();
}

ระวังว่า scope.get จะไม่ค้นหาเชนต้นแบบ - ต้องทำด้วยตัวเอง!

ขอบเขตไม่ขึ้นกับบริบทและคงอยู่ตาม Context.exit()

person Georg    schedule 27.11.2012