最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Java Nashorn - ClassNotFoundException - Java.type() - Stack Overflow

programmeradmin2浏览0评论

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!

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!

Share Improve this question edited Nov 26, 2015 at 19:53 fusionlightcat asked Nov 26, 2015 at 19:04 fusionlightcatfusionlightcat 3852 gold badges5 silver badges20 bronze badges 5
  • This looks like only Java and not JavaScript... – Arg0n Commented Nov 26, 2015 at 19:07
  • does it help to set the context classloader before you create the scriptengine, as explained here stackoverflow./a/30251930/3215527 – wero Commented Nov 26, 2015 at 19:12
  • @wero I will try this, one moment! And to Arg0n: yeah the examples above are all javascript, because this is a javascript problem. if i dont use any other classes evaluating scripts from within java works perfect. – fusionlightcat Commented Nov 26, 2015 at 19:40
  • @wero well i am stuck with that link... how exactly can i get the context classloader and set it to the thread? – fusionlightcat Commented Nov 26, 2015 at 19:44
  • Okay i got it now, but now it throws this: javax.script.ScriptException: TypeError: [JavaClass io.github.advtest1.Log] has no such function "warnSel" in <eval> at line number 20 Oh and yeah the warnSel()-method is public and static – fusionlightcat Commented Nov 26, 2015 at 19:50
Add a ment  | 

2 Answers 2

Reset to default 4
  • 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 mand line option. Nashorn tries to load classes using a fresh loader created during engine creation initialized with that classpath specified. Note that nashorn mand 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 mand 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())");
   }
}

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)

发布评论

评论列表(0)

  1. 暂无评论