2014-10-27 24 views
4

ScriptEngineManager.getEngineByName查找併爲給定名稱創建ScriptEngine。哪個JS腳本引擎將由Java選擇?

犀牛自身註冊爲 「JS」, 「犀牛」, 「JavaScript的」, 「JavaScript的」, 「ECMAScript的」 和 「ECMAScript的」

犀牛自身註冊爲 「犀牛」, 「犀牛」,「JS 「,」JS「,」JavaScript「,」javascript「,」ECMAScript「和」ecmascript「如果我使用Nashorn和Rhino註冊的名稱,如」js「,將使用哪個腳本引擎?否則它會在Java 8和Rhino上使用Nashorn?

回答

4

縱觀JavaDocregisterEngineName

註冊一個ScriptEngineFactory來處理語言名稱。覆蓋使用發現機制找到的任何此類關聯 。

而且也在registerEngineName源代碼(注意:nameAssociations是一個哈希表):

public void registerEngineName(String name, ScriptEngineFactory factory) { 
    if (name == null || factory == null) throw new NullPointerException(); 
     nameAssociations.put(name, factory); 
} 

所以,看來,對於一個給定的名稱,getEngineByName將返回腳本引擎工廠,這是最後被註冊爲該名稱。

由於腳本引擎工廠通過ServiceLoader機制加載,加載順序將取決於相關類加載器的getResources方法枚舉服務配置文件的順序。

對於默認安裝,所有這些都不重要,因爲Java 8只包含Nashorn,而Java 7和更早版本只包含Rhino。如果您要通過系統類路徑添加額外的引擎,它將在引導程序/擴展類加載器加載的引擎之後加載,因此優先。

+0

這是不正確的,因爲發現機制根本不使用'registerEngineName'。如果沒有明確註冊名稱,那麼實際上會得到第一個匹配的引擎,它會從「HashSet」中彈出。 它比classloader的順序更隨機,因爲它歸結爲java.lang.Object.hashCode,並且從一個運行到另一個運行。 – seanf 2015-03-06 16:32:00

0

讀取代碼registerEngineName確實是確定性的,但是發現機制是一個單獨的事物(如JavaDoc所暗示的),並且它是非確定性的,因爲它在發現過程中將所有引擎添加到HashSet,按名稱詢問引擎,它只是使用它找到的第一個匹配。

如果您在Java 7中安裝an updated Rhino ScriptEngine並通過任何常用名稱(js,rhino等)請求它,則可以運行此操作。

但是,除非你做到這一點,無論是隻要你不要求rhinonashorn的Java 7和Java 8都恰好與一個實現,它解答了jsjavascriptecmascript等,它應該工作在這兩種情況。