【问题标题】:Java Nashorn - ClassNotFoundException - Java.type()Java Nashorn - ClassNotFoundException - Java.type()
【发布时间】:2015-11-26 19:04:40
【问题描述】:

我目前正在为 Bukkit-Server 创建一个插件,但是我在使用 Nashorn 脚本引擎时遇到了问题。我正在评估我的 Java-Plugin 中的外部 javascript 文件。我无法让我的 javascript 从我的插件中导入类,只有标准的 java 类在工作(如var JavaBool = Java.type('java.lang.Boolean');,但不是var Holder = Java.type('io.github.advtest1.js.JSHolder');

每当我尝试加载其中之一时,我都会收到以下错误:

Caused by: java.lang.ClassNotFoundException: io.github.advtest1.js.JSHolder

经过一番研究,我发现它与我在类路径中的插件类beeing有关,但是当 Bukkit 本身加载插件并且我不想要任何其他启动选项时,如何将它添加到类路径中对于服务器然后java -jar bukkit.jar

如果您需要更多信息,请随时询问。 提前致谢!

【问题讨论】:

  • 这看起来只有Java 而不是JavaScript...
  • 在创建脚本引擎之前设置上下文类加载器是否有帮助,如此处所述stackoverflow.com/a/30251930/3215527
  • @wero 我会试试这个,一会儿!对于 Arg0n:是的,上面的示例都是 javascript,因为这是一个 javascript 问题。如果我不使用任何其他类来评估 java 中的脚本,那就完美了。
  • @wero 好吧,我被那个链接卡住了......我究竟如何才能获得上下文类加载器并将其设置到线程?
  • 好的,我现在知道了,但现在它抛出了这个:javax.script.ScriptException: TypeError: [JavaClass io.github.advtest1.Log] has no such function "warnSel" in <eval> at line number 20 哦,是的,warnSel() 方法是公共的和静态的

标签: javascript java bukkit nashorn


【解决方案1】:
  • Nashorn 使用在引擎创建时找到的线程上下文加载器从 Java.type API 中查找 Java 类。

  • 如果您使用“-classpath”nashorn 命令行选项,Nashorn 也会使用另一个加载器。 Nashorn 尝试使用在引擎创建期间使用指定的类路径初始化的新加载器来加载类。请注意,nashorn 命令行选项可以通过“nashorn.args”Java 系统属性传递。因此,如果您在其他地方(例如,在您的配置中)指定了 -Dnashorn.args="-classpath your_path",那么 Nashorn 可以从指定的 your_path 访问类。

如果无法通过系统属性 [或在使用“jjs”工具的情况下通过命令行] 传递 Nashorn 引擎选项,您可以按照先前答案的建议将线程上下文加载器设置为适当的加载器。

如果由于其他应用程序依赖项而不希望这样做,您可以获取所需类的 java.lang.Class 对象并将其作为变量公开给脚本(从您的 Java 代码中,您可以获取 Class 对象并调用 ScriptEngine.放方法)。然后脚本可以访问其上的“静态”属性以获取“类型”对象。使用类型对象,通常的“新”、静态方法调用等按预期工作。

例子:

import javax.script.*;

public class Main {
   public static void main(String[] args) throws Exception {
       ScriptEngineManager m = new ScriptEngineManager();
       ScriptEngine e = m.getEngineByName("nashorn");
       e.put("Vec", java.util.Vector.class); // replace it with any Class object
       e.eval("var T = Vec.static; var obj = new T()"); // create new Vector
       e.eval("print(obj.getClass())");
   }
}

【讨论】:

    【解决方案2】:

    正如@wero 提到的,我需要添加

    ClassLoader cl = plugin.getClass().getClassLoader();
    Thread.currentThread().setContextClassLoader(cl);
    

    在我从 java 调用 js 函数之前。

    plugin代表主类(扩展JavaPlugin的类)

    【讨论】:

      猜你喜欢
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      相关资源
      最近更新 更多