【问题标题】:Java 8 ScriptEngine across ClassLoaders跨类加载器的 Java 8 ScriptEngine
【发布时间】:2015-05-15 13:12:58
【问题描述】:

我需要在不同的类加载器“内部”执行一些 javascript 代码。如果是 java,每个任务将在单独的类加载器中运行。现在我需要它是 javascript。

我需要在每个类加载器中创建ScriptEngine 的新实例,还是可以跨类加载器共享一个?

【问题讨论】:

    标签: java java-8 classloader nashorn


    【解决方案1】:

    从您的问题来看,尚不清楚您为什么要寻找这种类加载器隔离。所以,我在这里总结了 nashorn 的类加载器——也许,你会得到你想要的。

    Nashorn 和类加载器:

    1. Nashorn 类 (jdk.nashorn.*) 由 Java 扩展类加载器加载
    2. 生成的脚本类、适配器(子类、脚本的接口实现)由 nashorn 的内部类加载器加载。
    3. 从脚本引用的 Java 类由 Nashorn“应用程序类加载器”加载。

    (1) 和 (2) 不能自定义。在 nashorn 代码中有假设它是特权代码。还有关于生成脚本类加载器和适配器加载器的假设。

    (3) 默认情况下是创建 nashorn 引擎时的线程上下文类加载器。如果线程上下文类加载器为空,则使用 Nashorn 自己的加载器——扩展加载器。

    所以如果你通过 Thread.setContextClassLoader API 设置合适的线程上下文加载器后创建 Nashorn 引擎,你可以控制脚本引擎的“应用类加载器”。

    如果您可以使用 NashornScriptEngineFactory(nashorn 特定 API https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html)创建脚本引擎,您也可以以编程方式将任何类加载器作为“应用程序类加载器”传递。您可能需要查看接受 ClassLoader 参数的 NashornScriptEngineFactory 方法。

    除了“应用程序类加载器”之外,您还可以选择使用在“应用程序类加载器”之前搜索的另一个附加类加载器。这由“-cp”或“-classpath”nashorn 命令行选项指定。请注意,您可以通过“nashorn.args”系统属性为脚本引擎指定 nashorn 命令行选项,或者使用 NashornScriptEngineFactory 类的 getScriptEngine 方法以编程方式传递。另见:https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes

    希望这会有所帮助。

    【讨论】:

    • “如果你创建 Nashorn 引擎” - 你的意思是 new ScriptEngineManager().getEngineByName("Nashorn")?换句话说,这总是会创建新的 ScriptEngine ;我应该在调用这个方法之前设置我的 threadctx 类加载器?
    • 是的,这就是我的意思——在创建新的 nashorn 引擎之前设置线程上下文类加载器。
    • 谢谢,你说的一切都很完美。
    • 嗨,我也有同样的问题,并将自定义类加载器应用为线程的 contextClassLoader,但它似乎不起作用,请有任何想法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多