Я пытаюсь реализовать простое модульное приложение с самописным загрузчиком плагинов. Для этого я создал мультипроектную сборку gradle. Основным проектом будет запущенное приложение. В подпроекте spi
находится модуль, содержащий интерфейс подключаемого модуля, а в подпроекте simple-plugin
я хотел создать подключаемый модуль для проверки загрузки подключаемого модуля.
Интерфейс Plugin
очень прост:
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;
}
Сейчас в классе PluginLoader
Я загружаю все jar-файлы из каталога и хочу добавить все плагины в список:
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;
}
Теперь, после сборки с помощью gradle и копирования в результате jar simple-plugin-0.1.jar
в каталог, я вижу, что URL-адрес файла находится в pluginJars
, но список PLUGINS
остается пустым. Я не уверен, что я делаю неправильно, онлайн-поиск не помог, я не вижу разницы в рабочем решении, но используется gradle.
используется gradle 6.5.1 и modularity.inferModulePath
установлен на true
.
Помощь приветствуется!
Примечание: при добавлении META-INF/services/io.github.zeroneca.orgascreen.spi.Plugin
в банку SimplePlugin
он работает, поэтому что-то должно быть не так с модулем декларации. Но я просто не могу понять, что.