2014-10-27 26 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等,它应该工作在这两种情况。