我正在编写Java应用程序,我想编写一些简单的插件系统。我想拥有基类插件。其他类扩展了Plugin,这些文件位于其他目录的类路径之外。
public class Plugin {
public Plugin() {
//code
}
public void proc() {
//code
}
}
和类加载器:
public class PluginLoader {
private static final FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return Pattern.matches("^.*[a-zA-Z]*[.]class$", name);
}
};
public static final String removeExtension(String str) {
if (str == null)
return null;
int pos = str.lastIndexOf(".");
if (pos == -1)
return str;
return str.substring(0, pos);
}
@SuppressWarnings("unchecked")
public static LinkedList<Plugin> loadEffects(String path) {
LinkedList<Plugin> result = new LinkedList<Plugin>();
Plugin instance = null;
File[] classesList = null;
System.out.println("Searching in " + path);
try {
File classDir = new File(path);
URL[] url = { classDir.toURI().toURL() };
URLClassLoader urlLoader = new URLClassLoader(url);
String filename;
classesList = classDir.listFiles(filter);
System.out.println(classesList.length + " class files found:");
for (File file : classesList) {
System.out.println("- " + file.getName());
}
for (File file : classesList) {
filename = removeExtension(file.getName());
if (filename.equals(".") || filename.equals("..") || filename.startsWith("."))
continue;
if (filename.equals("Plugin")) {
System.err.println("File name is Plugin");
continue;
}
System.out.println("Reading " + filename);
instance = (Plugin) urlLoader.findClass(filename).getConstructor().newInstance();
System.out.println("Adding: " + url + ", " + filename);
result.push(instance);
}
urlLoader.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
此代码导致 java.lang.NoClassDefFoundError:D:\ test \ PluginImpl / class(错误名称:test / PluginImpl)。插件类在D:\ test。
答案 0 :(得分:1)
您正在调用File#getAbsolutePath(),它将包含整个路径和驱动器号(D:\
)。存储在类中的类名与您提供的类名不匹配,因此Java会抛出错误。
尝试只使用类名调用findClass,它应该可以工作