2016-11-07 3 views
0

자바와 함께 Nashorn을 사용하여 모듈러 플러그인 시스템을 만들고 있습니다. 플러그인은 Javascript로 작성됩니다. 중요한 기능은 Javascript 코드로 작성 될 수있는 핸들러를 갖는 것입니다. 나는 간단한 명령 시스템을 만드는 것을 목표로 시작했다. javascript는 인터페이스를 구현하고 Java 메소드를 호출하여 명령을 등록합니다. 그러나 오류가 발생합니다. Nashorn (var usingNashorn = typeof importClass !== "function";)이 true를 반환했는지 확인했습니다.

자바 스크립트 :

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

자바 코드 : 가 호출 "수신"하기 : 'F'는 자바 스크립트가 파일입니다

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

는 '엔진'이 Nashorn 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

com.techsdev.scriptengine.listeners.CommandListener의 클래스 로더를 스크립트와 Java 코드에서 인쇄합니다. 자바 스크립트에서

:

자바에서
print(Java.type("com.techsdev.scriptengine.listeners.CommandListener").class.classLoader) 

: 같은 (완전한)라는 이름의 클래스 바이트가 두 개의 서로 다른 로더에 의해로드 된 경우

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

, 그 (런타임) 클래스는 다르다 JVM 관점. javascript 및 java 코드에서 다른 클래스 로더가 표시되면 클래스 경로/클래스 로더 문제가있을 가능성이 큽니다.

+0

문제는 내가 선택한 클래스 로더의 일부였습니다. Nashorn이 클래스 로더 등을 사용하지는 않았지만 모든 것이 다른 클래스 로더에로드 된 것 같습니다. 어쨌든, 그것은 정말로 클래스 로더에 대한 문제였습니다. 고맙습니다! – Rickydaan