Nashorn CommandListener$$NashornJavaAdapter 无法转换为 CommandListener
Nashorn CommandListener$$NashornJavaAdapter cannot be casted to the CommandListener
我正在使用带有 Java 的 Nashorn 来制作模块化插件系统。插件将用 Java 脚本编写。一个重要的特性是拥有可以在 Java 脚本代码中编写的处理程序。一开始我的目标是制作一个简单的命令系统。 javascript实现了一个接口,调用了一个Java方法来注册命令。但是,我收到一个错误。我确保我正在使用 Nashorn (var usingNashorn = typeof importClass !== "function";
) 返回 true。
Java脚本:
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代码:
调用 "listen":
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' 是 Java 脚本文件
其中 'engine' 是 Nashorn ScriptEngine
其中 'this' 是 ScriptManager
在 ScriptManager class 这个方法负责注册实际的命令:
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$Recompilation6A$\^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:?]
如果我遗漏了什么,请告诉我。
提前谢谢你。
我将从脚本和 Java 代码中打印 com.techsdev.scriptengine.listeners.CommandListener 的 classloader。
来自Java脚本:
print(Java.type("com.techsdev.scriptengine.listeners.CommandListener").class.classLoader)
来自Java:
System.out.println(com.techsdev.scriptengine.listeners.CommandListener.class.getClassLoader());
如果两个不同的加载程序加载了相同(完全限定)命名的 class 字节,则这些(运行时)classes 与 JVM 的观点不同。如果您从 java 脚本和 java 代码中看到不同的 class 加载程序,很可能是您遇到了 classpath/classloader 问题。
我正在使用带有 Java 的 Nashorn 来制作模块化插件系统。插件将用 Java 脚本编写。一个重要的特性是拥有可以在 Java 脚本代码中编写的处理程序。一开始我的目标是制作一个简单的命令系统。 javascript实现了一个接口,调用了一个Java方法来注册命令。但是,我收到一个错误。我确保我正在使用 Nashorn (var usingNashorn = typeof importClass !== "function";
) 返回 true。
Java脚本:
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代码: 调用 "listen":
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' 是 Java 脚本文件 其中 'engine' 是 Nashorn ScriptEngine 其中 'this' 是 ScriptManager
在 ScriptManager class 这个方法负责注册实际的命令:
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$Recompilation6A$\^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:?]
如果我遗漏了什么,请告诉我。 提前谢谢你。
我将从脚本和 Java 代码中打印 com.techsdev.scriptengine.listeners.CommandListener 的 classloader。
来自Java脚本:
print(Java.type("com.techsdev.scriptengine.listeners.CommandListener").class.classLoader)
来自Java:
System.out.println(com.techsdev.scriptengine.listeners.CommandListener.class.getClassLoader());
如果两个不同的加载程序加载了相同(完全限定)命名的 class 字节,则这些(运行时)classes 与 JVM 的观点不同。如果您从 java 脚本和 java 代码中看到不同的 class 加载程序,很可能是您遇到了 classpath/classloader 问题。