【问题标题】:Which JS Script Engine will be chosen by Java?Java 将选择哪个 JS 脚本引擎?
【发布时间】:2014-10-27 03:48:21
【问题描述】:

ScriptEngineManager.getEngineByName 查找并为给定名称创建一个 ScriptEngine。

Rhino 将自己注册为“js”、“rhino”、“JavaScript”、“javascript”、“ECMAScript”和“ecmascript”

Nashorn 将自己注册为“nashorn”、“Nashorn”、“js”、“JS”、“JavaScript”、“javascript”、“ECMAScript”和“ecmascript”

如果我使用 Nashorn 和 Rhino 都注册的名称,如“js”,将使用哪个脚本引擎?它会在 Java 8 和 Rhino 上使用 Nashorn 吗?

【问题讨论】:

    标签: java rhino nashorn scriptengine


    【解决方案1】:

    查看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。如果您要通过系统类路径添加额外的引擎,它将在引导/扩展类加载器加载的引擎之后加载,因此具有优先权。

    【讨论】:

    • 这不太对,因为发现机制根本不使用registerEngineName。如果没有显式注册名称,您实际上会得到第一个从HashSet 中弹出的匹配引擎。它比类加载器顺序更随机,因为它归结为java.lang.Object.hashCode,并且从一个运行到下一个运行变化。
    【解决方案2】:

    阅读代码,registerEngineName 确实是确定性的,但是发现机制是一个单独的东西(正如 JavaDoc 所暗示的那样),它是非确定性的,因为它在发现期间将所有引擎添加到 HashSet ,当按名称询问引擎时,它只使用找到的第一个匹配项。

    如果您在 Java 7 中安装 an updated Rhino ScriptEngine 并使用任何常用名称(jsrhino 等)请求它,您可能会遇到此问题。

    但除非你这样做,否则 Java 7 和 Java 8 都只有一个实现,它回答 jsjavascriptecmascript 等。只要你不要求 rhinonashorn,它应该适用于这两种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 1970-01-01
      • 2012-04-23
      • 2017-04-25
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      相关资源
      最近更新 更多