2014-06-10 40 views
3

我正在測試一些與Rhino一起使用的JSR 223(腳本)代碼,以瞭解它如何與Nashorn配合使用。一個區別是處理通過Bindings參數傳入的變量的更新爲engine.eval()。在Rhino中,我可以使用此方法在評估腳本時傳遞動態變量綁定,然後在執行腳本之後讀出這些變量的任何更新值。但是,在Nashorn中,這不起作用 - 執行腳本後,Bindings對象中所有變量的值仍然以其初始值顯示。評估腳本後讀取更新的變量

要與TestNG的測試用例說明:

@Test 
public void shouldSupportReadingVariablesFromBindings() throws Exception { 
    // Given 
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); 
    Bindings vars = new SimpleBindings(); 
    vars.put("state", 1); 

    // When 
    engine.eval("state = 2", vars); 
    Number result = (Number) vars.get("state"); 

    // Then 
    assertEquals(result.intValue(), 2); 

} 

隨着犀牛(蘋果JDK 1.6.0_65在Mac OS X 10.9.3)測試通過。使用Nashorn(Oracle JDK 1.8.0_b132)失敗。我嘗試了各種不同的方法來讀取變量 - 呼籲engine.get(),engine.getBindings(ScriptContext.ENGINE_SCOPE).get(),engine.getContext().getBindings(...).get()等。結果總是null

可以得到它,如果我打電話engine.put("state", 1)工作,然後用engine.get("state")後來讀它,但相比只是在綁定作爲參數傳遞,這似乎有點凌亂。

閱讀JSR-223規範,我找不到任何支持此用法的措辭,那麼它是否與引擎相關?有沒有其他方法可以完成我在納沙恩想要的?

編輯:有效的一種方法是將每個變量包裝在AtomicReference中,然後在Javascript中調用顯式的.set(..)方法。醜陋,但可能可行。

回答

2

如果您通過使用ScriptEngine.createBindings創建的綁定,Nashorn會將更新的值存儲在綁定中。 (我測試過)。

根據the OpenJDK wikithis OpenJDK bug,Rhino和Nashorn之間的這種行爲差異是預期的。 Nashorn不打算與Rhino完全兼容。

+0

謝謝,這是有用的信息。在我們的測試中,我們發現Nashorn比Rhino需要更多的內存,所以我們捆綁了我們自己的Rhino以在JDK版本/供應商中獲得一致的行爲。無論如何,從Nashorn加速我們特定的用例(小腳本,大部分是REST調用和處理結果)是微不足道的。 –