I'm trying to write a scripting system in Java and I've managed to get my scripts to compile and instantiate but when I try to cast the script into a "DeftScript" it throws a ClassCastError
even thought the script itself extends the class "DeftScript"
Error (the important part at least):
java.lang.ClassCastException: scripts.Compass cannot be cast to com.deft.core.scripts.DeftScript
at com.deft.core.scripts.DeftScriptManager.instantiate(DeftScriptManager.java:52) ~[?:?]
The error is caused by this
deftScript = (DeftScript)obj;
Compiling and Instantiating:
public static DeftScript instantiate(String java) {
File file = new File("./plugins/Deft-Core/scripts/" + java);
DeftScript deftScript = null;
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
List<String> optionList = new ArrayList<String>();
optionList.addAll(Arrays.asList("-classpath", System.getProperty("java.class.path") + ";./plugins/Deft-Core.jar"));
Iterable<? extends JavaFileObject> compilationUnit = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(file));
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionList, null, compilationUnit);
if (task.call()) {
Object obj = null;
try {
String jarFile = "./plugins/Deft-Core.jar";
URLClassLoader classLoader = new URLClassLoader (new URL[] {new File(jarFile).toURI().toURL(), new File("./plugins/Deft-Core/").toURI().toURL()}, Thread.currentThread().getContextClassLoader());
Class<?> loadedClass;
loadedClass = Class.forName("scripts.Compass", false, classLoader);
obj = loadedClass.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | MalformedURLException e) {
e.printStackTrace();
}
deftScript = (DeftScript)obj;
deftScript.onEnable();
} else {
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
System.out.format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource().toUri());
}
}
return deftScript;
}
Calling the instantiate method:
String script = "Compass.java";
DeftScriptManager.instantiate(script);
DeftScript.java
package com.deft.core.scripts;
public abstract class DeftScript {
public abstract void onEnable();
}
Compass.java
package scripts;
import com.deft.core.scripts.DeftScript;
public class Compass extends DeftScript {
@Override
public void onEnable() {}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…