ServiceLoader找不到插件

时间:2016-06-29 18:49:16

标签: java jar serviceloader

我有一个ServiceLoader试图加载任何扩展插件的东西。即使我已经设置了服务文件,它也找不到任何东西。

源代码(com.otabi.firestar.pajamatale.plugin.loader.PluginFinder是类):https://github.com/firestar115/PajamaTale

插件:https://github.com/firestar115/PajamaTest

我在这里做错了什么?为什么Plugin不显示并打印“Test Kappa”?

2 个答案:

答案 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将能够找到您的插件。