Java Nashorn - ClassNotFoundException - Java.type()

Java Nashorn - ClassNotFoundException - Java.type()

我目前正在为 Bukkit-Server 创建一个插件,但我在使用 Nashorn 脚本引擎时遇到了问题。我正在评估来自我的 Java-Plugin 的外部 javascript 文件。我无法让我的 java 脚本从我的插件中导入 类,只有标准的 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

经过一番研究,我发现它与我的插件有关-类 在类路径中发出蜂鸣声,但是当 Bukkit 本身加载插件时我如何将它添加到类路径中,而我没有然后 java -jar bukkit.jar?

想要服务器的任何其他启动选项

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

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

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

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

plugin代表主要的class(扩展JavaPlugin的class)

  • Nashorn 使用引擎创建时找到的线程上下文加载器从 Java.type API 中找到 Java classes。

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

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

如果由于其他应用程序依赖性而不需要这样做,您将获得所需 class 的 java.lang.Class 对象并将其作为变量暴露给脚本(来自您的 Java 代码,你可以获得 Class 对象并调用 ScriptEngine.put 方法)。然后脚本可以访问 "static" 属性 以获得 'type' 对象。对于类型对象,通常 "new"、静态方法调用等按预期工作。

示例:

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())");
   }
}