java - Nashorn JavaScript Invocable.getInterface 在 Web 应用程序中跨类加载器失败

标签 java classloader nashorn scriptengine javascript-engine

我需要从 Java 代码调用(使用 Nashorn)一个在 JavaScript 中定义的函数并向其传递一些参数。我没有使用 Invocable.invokeFunction("Foo", arg1, arg2),而是要定义一个接口(interface),然后请求 Invocable 生成它的实现,就像 Oracle 建议的那样 here , "嵌入 Oracle Nashorn":

package mypackage;
public final class MyClass {
  public interface Composer {
    void compose(final StringBuilder subject, final StringBuilder body);
  }

  public void composeEmail(...) {
      ...
      final ScriptEngineManager engineManager = new ScriptEngineManager();
      final ScriptEngine engine = engineManager.getEngineByName("nashorn");
      engine.eval(scriptText);
      final Invocable invocable = (Invocable) engine;
      final Composer composer = (Composer)invocable.getInterface(Composer);
      composer.compose(subject, body);
      ...
  }
}

问题是,因为我在 Tomcat 中运行的 Web 应用程序中执行此操作,所以我的 Composer 由应用程序级类加载器加载,而 nashorn 类由扩展类加载器加载。所以 getInterface 失败说 TypeError: Can not find a common class loader for ScriptObject and mypackage.Composer

有什么办法可以克服吗?当然,我可以尝试在父类加载器中加载 Composer,假设(hack-like)它实际上是一个 ext 加载器,但至少有一个问题:它找不到我的类。我想这是完全正确的:我的包驻留在我的 web 应用程序中,扩展加载器不在那里。还有其他好主意吗?

附言现在我注意到这个消息很奇怪:如果一个应用程序类加载器委托(delegate)给 ext 类加载器,那么后者当然是它们的通用类加载器。也许他们试图说目标接口(interface)的类加载器必须等于实际实现的类加载器,或者实现的类加载器必须委托(delegate)给目标的(但反之亦然)?

最佳答案

直接创建一个jdk.nashorn.api.scripting.NashornScriptEngineFactory实例而不是做engineManager.engineByName(),然后创建一个ScriptEngine 通过调用 NashornScriptEngineFactory.getScriptEngine(ClassLoader appLoader) 并将其传递给您的应用级加载器。

关于java - Nashorn JavaScript Invocable.getInterface 在 Web 应用程序中跨类加载器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31669566/

相关文章:

java - Java中的四叉 TreeMap 形显示

java - 有什么方法可以将一个条目添加到具有来自 int 变量的自定义位置的 Java 数组列表中吗?

java - 如何从 nashorn 访问 Java 对象函数

java - 使用多个脚本引擎

javascript - 基本 JS 对象 {a :1, b :2} not supported in Nashorn?

java - 删除 JButton 矩形白色边框

java - 在 Eclipse 中,maven 依赖项覆盖了项目依赖项

java - 使用 Velocity 作为 OSGi 包时 ResourceManager 类不匹配

java - 如何从 Loader 添加文本到 TextView

java - 将字节数组作为类加载到Java系统包中