Java ServiceLoader找不到插件

Java ServiceLoader找不到插件,java,jar,serviceloader,Java,Jar,Serviceloader,我有一个ServiceLoader,它尝试加载扩展插件的任何内容。它找不到任何东西,即使我已经设置了服务文件 源代码(com.otabi.firestar.pajamatale.plugin.loader.PluginFinder是类): 插件: 我做错了什么?为什么插件不显示并打印“Test Kappa”您需要创建一个URLClassLoader的实例,向其提供包含插件的目录的url,并将上下文ClassLoader作为父类加载器(我的意思是Thread.currentThread().get

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

源代码(
com.otabi.firestar.pajamatale.plugin.loader.PluginFinder
是类):

插件:


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

您需要创建一个
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);
ClassLoader myURLClassLoader=新的URLClassLoader(
新URL[]{new File(“plugins”).toURI().toURL()},
Thread.currentThread().getContextClassLoader()
);
ServiceLoader=ServiceLoader.load(Plugin.class,myURLClassLoader);

您需要创建一个
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);
ClassLoader myURLClassLoader=新的URLClassLoader(
新URL[]{new File(“plugins”).toURI().toURL()},
Thread.currentThread().getContextClassLoader()
);
ServiceLoader=ServiceLoader.load(Plugin.class,myURLClassLoader);

我可以确认
URLClassLoader
需要为每个
jar
提供一个
URL
来表示
插件。用
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());
File[]pluginFiles=directory.listFiles((File dir,String name)->name.endsWith(“.jar”);
List urlsList=new ArrayList();
用于(文件:pluginFiles){
试一试{
添加(文件.toURI().toURL());
}捕获(格式错误){
e、 printStackTrace();
}
}
URLClassLoader=URLClassLoader.newInstance(urlsList.toArray(新URL[]{}),Thread.currentThread().getContextClassLoader());

然后,
ServiceLoader
将能够找到您的插件。

我可以确认,
URLClassLoader
需要一个
URL
用于表示
插件的每个
jar
。用
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());
File[]pluginFiles=directory.listFiles((File dir,String name)->name.endsWith(“.jar”);
List urlsList=new ArrayList();
用于(文件:pluginFiles){
试一试{
添加(文件.toURI().toURL());
}捕获(格式错误){
e、 printStackTrace();
}
}
URLClassLoader=URLClassLoader.newInstance(urlsList.toArray(新URL[]{}),Thread.currentThread().getContextClassLoader());

然后,
ServiceLoader
将能够找到您的插件。

问题是什么?我如何能够让不在类路径中的jar显示在ServiceLoader中@NicolasFilottow问题是什么?我怎样才能让我的类路径中没有的JAR显示在ServiceLoader中@NicolasFilottoSo基本上是
ServiceLoader.load(新的URLClassLoader(“plugins/”)
?是的,这是将上下文类加载器作为父类加载器创建URL的想法。我是使用
文件://
协议还是只使用普通的
插件
?您需要一个可以通过新文件(“foo”).toURI().tour()获得的URL你能提供一个方法示例吗?(在答案中)那么基本上
ServiceLoader.load(new URLClassLoader(“plugins/”)
?是的,这是将上下文类加载器作为父类加载器的想法。对于创建URL,我是使用
文件://
协议还是只使用普通的
插件
?您需要一个可以通过新文件(“foo”).toURI().tour()获得的URL你能提供一个方法示例吗?(在答案中)如果你在谷歌上搜索这个问题并登陆到这个页面,这确实是你想要的答案!我尝试了另一种选择,正如我所说的,仅仅拥有目录是不够的,你需要JAR。如果你用谷歌搜索这个问题并登陆到这个页面,这确实是你想要的答案!我尝试了另一个选项,正如前面所说的,只有目录是不够的,您需要jar