我目前正在开发一个开源项目,人们可以在其中添加自己的 .jar 来扩展所包含的功能。但是,我对如何加载 jar 中的类感到困惑。
我有一个抽象类,它有一个抽象方法 onEnable()
和一些 getter,它提供了一些与应用程序一起使用的对象。该插件需要我的插件类 BasePlugin
的子类。该 jar 应该添加到/plugins 中,因此我希望在应用程序启动时加载/plugins 文件夹中的所有 *.jar 文件。
我现在遇到的问题是,在我发现的所有方法中,我需要在 jar 文件中声明类的类路径,但我不知道。我也不知道 jar 文件的名称。因此,我需要扫描/plugins 文件夹中的任何 *.jar 文件,并在实现 BasePlugin
的 jar 中加载相应的类,并调用 onEnable()
方法。
最佳答案
基本思想太...
- 读取特定目录中的所有文件
- 将每个结果的
文件
引用转换为URL
- 使用
URLClassLoader
,以URL
结果作为种子来加载每个结果 - 使用
URLClassLoader#findResources
查找具有特定名称的所有匹配资源 - 迭代匹配的资源并加载每个资源,这至少应该给出“入口点”类名称
- 加载“入口点”属性指定的类
例如...
public List<PluginClass> loadPlugins() throws MalformedURLException, IOException, ClassNotFoundException {
File plugins[] = new File("./Plugins").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.getName().endsWith(".jar");
}
});
List<URL> plugInURLs = new ArrayList<>(plugins.length);
for (File plugin : plugins) {
plugInURLs.add(plugin.toURI().toURL());
}
URLClassLoader loader = new URLClassLoader(plugInURLs.toArray(new URL[0]));
Enumeration<URL> resources = loader.findResources("/META-INFO/Plugin.properties");
List<PluginClass> classes = new ArrayList<>(plugInURLs.size());
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
Properties properties = new Properties();
try (InputStream is = resource.openStream()) {
properties.load(is);
String className = properties.getProperty("enrty-point");
PluginClass pluginClass = loader.loadClass(className);
classes.add(pluginClass);
}
}
return classes
}
nb:我没有运行过这个,但这是“基本”
关于Java从目录加载jar文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55465579/