Java 8 ScriptEngine 跨 ClassLoaders

5

我需要在不同的类加载器中执行一些JavaScript代码。如果是Java,则每个任务将在单独的类加载器中运行。现在我需要这个功能在JavaScript中实现。

我是否需要在每个类加载器中创建一个新的ScriptEngine实例,或者共享一个跨类加载器使用也可以?

1个回答

12

根据您的问题,不清楚为什么要寻找这种类加载器隔离。所以,我在此简述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”系统属性或使用NashornScriptEngineFactory类的getScriptEngine方法以编程方式传递来指定脚本引擎的nashorn命令行选项。另请参阅:https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes 希望这可以帮助到您。

如果你创建Nashorn引擎,你是指new ScriptEngineManager().getEngineByName("Nashorn")吗?换句话说,这总是会创建一个新的ScriptEngine;在调用这个方法之前,我应该设置我的线程上下文类加载器吗? - igr
3
是的,这就是我的意思——在创建新的nashorn引擎之前设置线程上下文类加载器。 - A. Sundararajan
谢谢,你说的一切都很完美。 - igr
嗨,我也有同样的问题,并将自定义类加载器应用为线程的上下文类加载器,但似乎并没有起作用,请问有什么想法! - jatanp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接