Java plugin jar loading

Java Language
Реализации Java-плагинов

Если вы используете систему IDE и / или сборки, гораздо проще настроить такой проект. Вы создаете основной модуль приложения, затем модуль API, затем создаете модуль плагина и делаете его зависимым от модуля API или обоих. Затем вы настраиваете, где должны быть помещены артефакты проекта — в нашем случае скомпилированные плагины могут быть отправлены прямо в каталог «plugins», что позволяет избежать ручного перемещения.

Использование URLClassLoader

Существует несколько способов реализации плагиновой системы для Java-приложения. Одним из самых простых является использование URLClassLoader . В следующем примере будет задействован бит кода JavaFX.

Предположим, что у нас есть модуль основного приложения. Предполагается, что этот модуль загружает плагины в форме Jars из папки «plugins». Исходный код:

package main; public class MainApplication extends Application < @Override public void start(Stage primaryStage) throws Exception < File pluginDirectory=new File("plugins"); //arbitrary directory if(!pluginDirectory.exists())pluginDirectory.mkdir(); VBox loadedPlugins=new VBox(6); //a container to show the visual info later Rectangle2D screenbounds=Screen.getPrimary().getVisualBounds(); Scene scene=new Scene(loadedPlugins,screenbounds.getWidth()/2,screenbounds.getHeight()/2); primaryStage.setScene(scene); primaryStage.show(); >public static void main(String[] a) < launch(a); >> 

Затем мы создаем интерфейс, который будет представлять собой плагин.

package main; public interface Plugin < default void initialize() < System.out.println("Initialized "+this.getClass().getName()); >default String name() > 

Мы хотим загрузить классы, реализующие этот интерфейс, поэтому сначала нам нужно отфильтровать файлы с расширением «.jar»:

File[] files=pluginDirectory.listFiles((dir, name) -> name.endsWith(".jar")); 

Если есть какие-либо файлы, нам необходимо создать коллекции URL-адресов и имен классов:

 if(files!=null && files.length>0) < ArrayListclasses=new ArrayList<>(); ArrayList urls=new ArrayList<>(files.length); for(File file:files) < JarFile jar=new JarFile(file); jar.stream().forEach(jarEntry -> < if(jarEntry.getName().endsWith(".class")) < classes.add(jarEntry.getName()); >>); URL url=file.toURI().toURL(); urls.add(url); > > 

Давайте добавим статический HashSet к MainApplication, который будет содержать загруженные плагины:

static HashSet plugins=new HashSet<>(); 

Затем мы создаем экземпляр URLClassLoader и повторяем имена классов, создавая экземпляры классов, которые реализуют интерфейс Plugin :

URLClassLoader urlClassLoader=new URLClassLoader(urls.toArray(new URL[urls.size()])); classes.forEach(className-> < try < Class cls=urlClassLoader.loadClass(className.replaceAll("/",".").replace(".class","")); //transforming to binary name Class[] interfaces=cls.getInterfaces(); for(Class intface:interfaces) < if(intface.equals(Plugin.class)) //checking presence of Plugin interface < Plugin plugin=(Plugin) cls.newInstance(); //instantiating the Plugin plugins.add(plugin); break; >> > catch (Exception e) >); 

Затем мы можем вызвать методы плагина, например, для их инициализации:

if(!plugins.isEmpty())loadedPlugins.getChildren().add(new Label("Loaded plugins:")); plugins.forEach(plugin -> < plugin.initialize(); loadedPlugins.getChildren().add(new Label(plugin.name())); >); 

Окончательный код MainApplication :

package main; public class MainApplication extends Application < static HashSetplugins=new HashSet<>(); @Override public void start(Stage primaryStage) throws Exception < File pluginDirectory=new File("plugins"); if(!pluginDirectory.exists())pluginDirectory.mkdir(); File[] files=pluginDirectory.listFiles((dir, name) ->name.endsWith(".jar")); VBox loadedPlugins=new VBox(6); loadedPlugins.setAlignment(Pos.CENTER); if(files!=null && files.length>0) < ArrayListclasses=new ArrayList<>(); ArrayList urls=new ArrayList<>(files.length); for(File file:files) < JarFile jar=new JarFile(file); jar.stream().forEach(jarEntry -> < if(jarEntry.getName().endsWith(".class")) < classes.add(jarEntry.getName()); >>); URL url=file.toURI().toURL(); urls.add(url); > URLClassLoader urlClassLoader=new URLClassLoader(urls.toArray(new URL[urls.size()])); classes.forEach(className-> < try < Class cls=urlClassLoader.loadClass(className.replaceAll("/",".").replace(".class","")); Class[] interfaces=cls.getInterfaces(); for(Class intface:interfaces) < if(intface.equals(Plugin.class)) < Plugin plugin=(Plugin) cls.newInstance(); plugins.add(plugin); break; >> > catch (Exception e) >); if(!plugins.isEmpty())loadedPlugins.getChildren().add(new Label("Loaded plugins:")); plugins.forEach(plugin -> < plugin.initialize(); loadedPlugins.getChildren().add(new Label(plugin.name())); >); > Rectangle2D screenbounds=Screen.getPrimary().getVisualBounds(); Scene scene=new Scene(loadedPlugins,screenbounds.getWidth()/2,screenbounds.getHeight()/2); primaryStage.setScene(scene); primaryStage.show(); > public static void main(String[] a) < launch(a); >> 

Давайте создадим два плагина. Очевидно, что источник плагина должен быть в отдельном модуле.

package plugins; import main.Plugin; public class FirstPlugin implements Plugin < //this plugin has default behaviour >
package plugins; import main.Plugin; public class AnotherPlugin implements Plugin < @Override public void initialize() //overrided to show user's home directory < System.out.println("User home directory: "+System.getProperty("user.home")); >> 

Эти плагины должны быть упакованы в стандартные Jars — этот процесс зависит от вашей среды разработки или других инструментов.

Когда Jars будут помещены в «плагины» напрямую, MainApplication обнаружит их и создаст соответствующие классы.

  • Начало работы с Java Language
  • 2D-графика в Java
  • Apache Commons Lang
  • API Reflection
  • API стека
  • AppDynamics и TIBCO BusinessWorks для легкой интеграции
  • Autoboxing
  • BigDecimal
  • BigInteger
  • BufferedWriter
  • ByteBuffer
  • CompletableFuture
  • Enum, начиная с номера
  • FileUpload для AWS
  • FTP (протокол передачи файлов)
  • HttpURLConnection
  • InputStreams и OutputStreams
  • Java Pitfalls — использование исключений
  • Java Pitfalls — синтаксис языка
  • JavaBean
  • Java-агенты
  • Java-версии, версии, выпуски и дистрибутивы
  • JAXB
  • JAX-WS
  • JMX
  • JNDI
  • JShell
  • JSON в Java
  • LinkedHashMap
  • log4j / log4j2
  • NIO — Сеть
  • NumberFormat
  • ServiceLoader
  • SortedMap
  • Streams
  • StringBuffer
  • StringBuilder
  • sun.misc.Unsafe
  • ThreadLocal
  • TreeMap и TreeSet
  • Varargs (переменный аргумент)
  • WeakHashMap
  • XJC
  • XOM — Объектная модель XML
  • Альтернативные коллекции
  • Анализ XML с использованием API JAXP
  • Аннотации
  • Апплеты
  • Атомные типы
  • аудио
  • Безопасность и криптография
  • Безопасность и криптография
  • Бит-манипуляция
  • Валюта и деньги
  • Ведение журнала (java.util.logging)
  • Видимость (контроль доступа к членам класса)
  • Виртуальная машина Java (JVM)
  • Виртуальный доступ Java
  • Вложенные и внутренние классы
  • Возможности Java SE 7
  • Возможности Java SE 8
  • Выбор коллекций
  • Выражения
  • Генерация случайных чисел
  • Геттеры и сеттеры
  • Даты и время (java.time. *)
  • Двигатель JavaScript Nashorn
  • Дженерики
  • Документирование кода Java
  • Загрузчики классов
  • Защищенные объекты
  • Изменение байтового кода
  • Инкапсуляция
  • Интерфейс Dequeue
  • Интерфейс Java Native
  • Интерфейс инструмента JVM
  • Интерфейсы
  • Исключения и обработка исключений
  • Исполнители, Исполнительные службы и пулы потоков
  • Использование ThreadPoolExecutor в приложениях MultiThreaded.
  • Использование других языков сценариев в Java
  • Использование ключевого слова static
  • Итератор и Итерабель
  • Календарь и его подклассы
  • Карта Enum
  • Карты
  • Класс — отражение Java
  • Класс EnumSet
  • Класс java.util.Objects
  • Класс даты
  • Класс свойств
  • Классы и объекты
  • Клонирование объектов
  • Кодировка символов
  • Коллекции
  • Команда Java — «java» и «javaw»
  • Команды выполнения
  • Компилятор Java — «javac»
  • Компилятор Just in Time (JIT)
  • Консольный ввод-вывод
  • Конструкторы
  • литералы
  • Локализация и интернационализация
  • Лямбда-выражения
  • Массивы
  • Менеджер по безопасности
  • Местное время
  • Местный внутренний класс
  • Методы и конструкторы классов объектов
  • Методы по умолчанию
  • Методы сбора коллекции
  • Модель памяти Java
  • Модификаторы без доступа
  • Модули
  • наборы
  • наследование
  • Настройка производительности Java
  • Неизменяемые объекты
  • Неизменяемый класс
  • Необязательный
  • Новый ввод-вывод файлов
  • Обработка аргументов командной строки
  • Общие ошибки Java
  • Одиночки
  • операторы
  • Операции с плавающей точкой Java
  • Ориентиры
  • Основные управляющие структуры
  • Отправка динамического метода
  • Оценка XML XPath
  • Очереди и Deques
  • Ошибки Java — Nulls и NullPointerException
  • Ошибки Java — потоки и параллелизм
  • Ошибки Java — проблемы с производительностью
  • пакеты
  • Параллельное программирование (темы)
  • Параллельное программирование с использованием структуры Fork / Join
  • Параллельные коллекции
  • Перечисления
  • Полиморфизм
  • предпочтения
  • Преобразование в строки и из них
  • Преобразование типа
  • Примитивные типы данных
  • Процесс
  • Путь Класса
  • Разборка и декомпиляция
  • Развертывание Java
  • Разделение строки на части с фиксированной длиной
  • Реализации Java-плагинов
  • Регулярные выражения
  • Рекурсия
  • Ресурсы (на пути к классам)
  • Розетки
  • Свободный интерфейс
  • Сериализация
  • сетей
  • сканер
  • Служба печати Java
  • Создание изображений программно
  • Создание кода Java
  • Сокеты Java
  • Списки
  • Список против SET
  • Сравнение C ++
  • Сравнительный и компаратор
  • Ссылки на объекты
  • Стандарт официального кода Oracle
  • Строковый токенизатор
  • Струны
  • супер ключевое слово
  • Тестирование устройства
  • Типы ссылок
  • Типы ссылочных данных
  • Удаленный вызов метода (RMI)
  • Управление памятью Java
  • Установка Java (стандартная версия)
  • Утверждая
  • Файловый ввод-вывод
  • Файлы с несколькими релизами JAR
  • Флаги JVM
  • Функциональные интерфейсы
  • Хеш-таблица
  • Читатели и писатели
  • Шифрование RSA

Источник

Читайте также:  Array php все функции
Оцените статью