我目前正在为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
经过一番研究后我发现它与我在类路径中的插件类有关,但是当Bukkit本身加载插件时我怎么能将它添加到类路径中而我不想要任何然后服务器的其他启动选项java -jar bukkit.jar
?
如果您需要其他信息,请随时询问。 提前谢谢!
答案 0 :(得分:3)
Nashorn使用在创建引擎时找到的线程上下文加载器从Java.type API中查找Java类。
如果使用" -classpath" Nashorn也使用另一个加载器nashorn命令行选项。 Nashorn尝试使用在指定的类路径初始化的引擎创建期间创建的新加载器加载类。请注意,nashorn命令行选项可以通过" nashorn.args" Java系统属性。所以,如果你具体-Dnashorn.args =" -classpath your_path"在其他地方(例如,在您的配置中),然后Nashorn可以从指定的your_path访问类。
如果无法通过系统属性传递Nashorn引擎选项[或通过命令行" jjs"工具使用],您可以将线程上下文加载器设置为适当的加载器,如前面的答案所示。
如果由于其他应用程序依赖性而不希望这样,则获取所需类的java.lang.Class对象并将相同的变量公开给脚本(从Java代码中,您可以获取Class对象并调用ScriptEngine。把方法)。然后脚本可以访问"静态"获得'类型'宾语。对于类型对象,通常" 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())");
}
}
答案 1 :(得分:2)
正如@wero所说,我需要添加
ClassLoader cl = plugin.getClass().getClassLoader();
Thread.currentThread().setContextClassLoader(cl);
在我从java调用js-function之前。
plugin
代表主类(扩展JavaPlugin的类)