我有一个 ServiceLoader 试图加载任何扩展插件的东西。即使我设置了服务文件,它也没有找到任何东西。
源码(com.otabi.firestar.pajamatale.plugin.loader.PluginFinder
是类):https ://github.com/firestar115/PajamaTale
插件:https ://github.com/firestar115/PajamaTest
我在这里做错了什么?为什么插件不显示并打印“Test Kappa”?
我有一个 ServiceLoader 试图加载任何扩展插件的东西。即使我设置了服务文件,它也没有找到任何东西。
源码(com.otabi.firestar.pajamatale.plugin.loader.PluginFinder
是类):https ://github.com/firestar115/PajamaTale
插件:https ://github.com/firestar115/PajamaTest
我在这里做错了什么?为什么插件不显示并打印“Test Kappa”?
我可以确认每个代表 a的都URLClassLoader
需要a 。将类加载器实例化到包含文件的目录是不够的。所以你需要做的:URL
jar
Plugin
URL
jar
File[] pluginFiles = directory.listFiles((File dir, String name) -> name.endsWith(".jar"));
List<URL> urlsList = new ArrayList<>();
for (File file : pluginFiles) {
try {
urlsList.add(file.toURI().toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
URLClassLoader classLoader = URLClassLoader.newInstance(urlsList.toArray(new URL[]{}), Thread.currentThread().getContextClassLoader());
然后,ServiceLoader
将能够找到您的插件。
您需要创建一个实例,URLClassLoader
向其中提供包含您的插件的目录的 url,并将上下文ClassLoader
作为父类加载器(我的意思是Thread.currentThread().getContextClassLoader()
)并使用ServiceLoader.load(Plugin.class, myURLClassLoader)
而不是在ServiceLoader.load(Plugin.class)
内部使用上下文ClassLoader
,这在您的情况下是不够的,因为您的插件是不在你的类路径中。
就像是:
ClassLoader myURLClassLoader = new URLClassLoader(
new URL[]{new File("plugins").toURI().toURL()},
Thread.currentThread().getContextClassLoader()
);
ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class, myURLClassLoader);