2016-11-07 46 views
0

我正在使用Nashorn和Java來創建模塊化插件系統。插件將用Javascript編寫。一個重要的特性是具有可以用Javascript代碼編寫的處理程序。從我開始,我的目標是制定一個簡單的指揮系統。 javascript實現一個接口,並調用Java方法來註冊該命令。但是,我收到一個錯誤。我確信我正在使用Nashorn(var usingNashorn = typeof importClass !== "function";)返回true。

的JavaScript:

var CommandListener = Java.extend(Java.type("com.techsdev.scriptengine.listeners.CommandListener"), { 
    invoke : function(sender, command, args) { 
     java.lang.System.out.println("Received a command: " + command); 
    } 
}); 

var listen = function(scriptManager) { 
    var listener = new CommandListener(); 
    scriptManager.registerCommand("plugin name", "test", listener); 
} 

的Java代碼: 要調用 「聽」:

try { 
    engine.eval(new FileReader(f)); 
    Invocable invocable = (Invocable) engine; 
    invocable.invokeFunction("listen", this); 
} catch(Exception e) { 
    logger.error("Failed to load script "+f.getName(), e); 
} 

,其中 'F' 是JavaScript文件 其中 '發動機' 是犀牛的ScriptEngine 其中'this'是ScriptManager

在ScriptManager類中,此方法負責註冊實際命令:

public void registerCommand(String plugin, String command, CommandListener listener) { 
     if(commandHandlers.containsKey(command.toLowerCase())) { 
      logger.warn("Command "+command+" tried to be registered, but is already registered!"); 
      return; 
     } 

     commandHandlers.put(command.toLowerCase(), listener); 
} 

然而,這個代碼拋出以下異常:

java.lang.ClassCastException: com.techsdev.scriptengine.listeners.CommandListener$$NashornJavaAdapter cannot be cast to com.techsdev.scriptengine.listeners.CommandListener 
    at com.techsdev.scriptengine.JsScriptManager.registerCommand(JsScriptManager.java:168) ~[scriptengine-mod.jar:?] 
    at jdk.nashorn.internal.scripts.Script$Recompilation$2$616A$\^eval\_.listen(<eval>:22) ~[?:?] 
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:625) ~[nashorn.jar:?] 
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494) ~[nashorn.jar:?] 
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393) ~[nashorn.jar:?] 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:199) ~[nashorn.jar:?] 
    at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:383) ~[nashorn.jar:?] 
    at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190) ~[nashorn.jar:?] 
    at com.techsdev.scriptengine.JsScriptManager.loadFile(JsScriptManager.java:134) [JsScriptManager.class:?] 
    at com.techsdev.scriptengine.JsScriptManager.loadFolder(JsScriptManager.java:116) [JsScriptManager.class:?] 
    at com.techsdev.scriptengine.JsScriptManager.init(JsScriptManager.java:104) [JsScriptManager.class:?] 

請讓我知道如果我錯過了什麼。 預先感謝您。

回答

1

我會從腳本和Java代碼中打印com.techsdev.scriptengine.listeners.CommandListener的類加載器。

從JavaScript:

print(Java.type("com.techsdev.scriptengine.listeners.CommandListener").class.classLoader) 

從Java:

System.out.println(com.techsdev.scriptengine.listeners.CommandListener.class.getClassLoader()); 

如果相同的(完全限定)命名的類字節是由兩個不同的加載器加載,那些(運行)班來自不同JVM的觀點。如果你從javascript和java代碼中看到不同的類加載器,那麼很可能你會遇到類路徑/類加載器問題。

+0

問題確實是我選擇的類加載器的一部分。顯然,所有的東西都加載到不同的類加載器上,而Nashorn沒有使用該類加載器,或類似的東西。無論哪種方式,這確實是類加載器的一個問題。謝謝! – Rickydaan