0

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

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

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

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

4

2 回答 2

2

我可以确认每个代表 a的都URLClassLoader需要a 。将类加载器实例化到包含文件的目录是不够的。所以你需要做的:URLjarPluginURLjar

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

于 2017-04-04T08:18:48.350 回答
1

您需要创建一个实例,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);
于 2016-06-29T18:54:19.363 回答