I am trying to implement a simple modular application with a self written plugin loader. For that I created a gradle multiproject build. The main project is going to be the started application. In the subproject spi
is a module containing the Plugin interface, while in the subproject simple-plugin
I wanted to create a plugin to test the plugin loading.
The Plugin
interface is very simple:
package io.github.zeroneca.orgascreen.spi;
public interface Plugin {
String getId();
}
module-info.java
:
module io.github.zeroneca.orgascreen.spi {
exports io.github.zeroneca.orgascreen.spi;
}
SimplePlugin.java
:
package io.github.zeroneca.orgascreen.plugins.simple;
import io.github.zeroneca.orgascreen.spi.Plugin;
public class SimplePlugin implements Plugin {
private final String id = "SimplePlugin";
@Override
public String getId() { return id; }
}
module-info.java
module io.github.zeroneca.orgascreen.plugins.simple {
requires io.github.zeroneca.orgascreen.spi;
provides io.github.zeroneca.orgascreen.spi.Plugin with io.github.zeroneca.orgascreen.plugins.simple.SimplePlugin;
}
Now in the class PluginLoader
I'm loading all jars from a directory and want to add all Plugins to a List:
package io.github.zeroneca.orgascreen;
// several imports
public class PluginLoader {
private static final List<Plugin> PLUGINS = new ArrayList<>();
public static void load() {
URL[] pluginURLs = getPluginURLs(); // returns all URLs of jar files in a directory
URLClassLoader urlClassLoader = URLClassLoader.newInstance(pluginURLs);
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, urlClassLoader);
for (Plugin plugin : serviceLoader) {
PLUGINS.add(plugin);
}
}
// some more methods hidden here
}
module-info.java
module io.github.zeroneca.orgascreen {
requires io.github.zeroneca.orgascreen.spi;
uses io.github.zeroneca.orgascreen.spi.Plugin;
}
Now after building with gradle and copying the resulting jar simple-plugin-0.1.jar
into the directory, I can see, that the URL of the file is in pluginJars
but the List PLUGINS
remains empty. I'm not sure what I'm doing wrong, online searches didn't help, I cannot see a difference to working solution, but the use of gradle.
gradle 6.5.1 is in use and modularity.inferModulePath
is set to true
.
Help is greatly appreciated!
Note: when adding META-INF/services/io.github.zeroneca.orgascreen.spi.Plugin
to the jar of SimplePlugin
it works, so something must be wrong with the module declarations. But I just can't see what.