我有一个ServiceLoader试图加载任何扩展插件的东西。即使我已经设置了服务文件,它也找不到任何东西。
源代码(com.otabi.firestar.pajamatale.plugin.loader.PluginFinder
是类):https://github.com/firestar115/PajamaTale
插件:https://github.com/firestar115/PajamaTest
我在这里做错了什么?为什么Plugin不显示并打印“Test Kappa”?
答案 0 :(得分:1)
您需要创建一个URLClassLoader
实例,向其提供包含插件的目录的URL,并将上下文ClassLoader
作为父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);
答案 1 :(得分:1)
我可以确认URLClassLoader
代表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
将能够找到您的插件。