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