Java Nashorn - ClassNotFoundException - Java.type()

时间秒杀一切 提交于 2019-12-12 04:58:08

问题


I am currently creating a plugin for the Bukkit-Server, but i have a problem using the Nashorn scripting engine. I am evaluating the external javascript file from my Java-Plugin. I cant get my javascript to import the classes from my plugin, only standard java classes are working (like var JavaBool = Java.type('java.lang.Boolean');, but not var Holder = Java.type('io.github.advtest1.js.JSHolder');)

Whenever I try to load one of these I get the following error:

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

After a bit of researching i found that it has something to do with my plugin-classes beeing in the classpath, but how can i add it to the classpath when Bukkit itself loads the plugin and i don't want any other startoptions for the server then java -jar bukkit.jar?

Feel free to ask, if you need additional information. Thanks in advance!


回答1:


  • Nashorn uses the thread context loader found at the time of engine creation to find Java classes from Java.type API.

  • Nashorn also uses another loader if you use "-classpath" nashorn command line option. Nashorn tries to load classes using a fresh loader created during engine creation initialized with that classpath specified. Note that nashorn command line options can be passed via "nashorn.args" Java System property. So, if you specific -Dnashorn.args="-classpath your_path" elsewhere (say, in your config), then Nashorn can access classes from that your_path specified.

If cannot pass Nashorn engine options via System property [or via command line in the case "jjs" tool use], you can set thread context loader to be appropriate loader as suggested by an earlier answer.

If that is not desired because of other application dependencies, you get java.lang.Class object of the desired class and expose the same as variable to the script (from your Java code, you could get Class object and call ScriptEngine.put method). The script then can access "static" property on that to get 'type' object. With type object, usual "new", static method calls etc. work as expected.

Example:

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:


As @wero mentioned, I needed to add

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

before I invoke the js-function from java.

plugin stands for the main class (the class which extends JavaPlugin)



来源:https://stackoverflow.com/questions/33945507/java-nashorn-classnotfoundexception-java-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!