Java 8 个跨类加载器的 ScriptEngine

Java 8 ScriptEngine across ClassLoaders

我需要执行一些 java 脚本代码 'inside' 不同的 class 加载器。如果是 java,每个任务将 运行 在单独的 class 加载器中。现在我需要它是 javascript.

我是否需要在每个 class 加载器中创建 ScriptEngine 的新实例,或者是否可以在 class 个加载器之间共享一个实例?

从你的问题来看,你为什么要寻找这样的 classloader 隔离还不清楚。所以,我在这里总结了 nashorn 的 classloader - 也许,你会得到你想要的东西。

Nashorn 和 class加载程序:

  1. Nashorn classes (jdk.nashorn.*) 由 Java extension class loader
  2. 加载
  3. 生成的脚本 classes,适配器(subclasses,脚本中的接口实现)由 nashorn 的内部 class 加载器加载。
  4. Java class从脚本引用的 es 由 Nashorn "app class loader".
  5. 加载

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

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

因此,如果您通过Thread.setContextClassLoader API设置合适的线程上下文加载器后创建Nashorn引擎,您可以控制脚本引擎的"app class loader"。

如果您可以使用 NashornScriptEngineFactory(特定于 nashorn API https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html)来创建脚本引擎,您可以以编程方式将任何 classloader 作为 "app class loader" 作为出色地。您可能想查看接受 ClassLoader 参数的 NashornScriptEngineFactory 方法。

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

希望对您有所帮助。