Реализация динамических плагинов в Java

Я хотел бы реализовать динамическую сменную опцию в JAVA-приложении. Идеально:

  • Приложение определило бы интерфейс Plugin с методом как getCapabilities().
  • Плагин был бы JAR pluginX.jar содержа класс PluginXImpl реализация Plugin (и возможно некоторые другие).
  • Пользователь поместил бы pluginX.jar в специальном каталоге или наборе параметр конфигурации, указывающий на него. Пользователю не придется обязательно включать pluginX.jar в их пути к классу.
  • Приложение нашло бы PluginXImpl (возможно, с помощью декларации JAR, возможно, отражением), и добавляют его к реестру.
  • Клиент мог получить экземпляр PluginXImpl, например, путем вызова метода как getPluginWithCapabilities("X"). Пользователю не придется обязательно знать название плагина.

У меня есть смысл, я должен быть в состоянии сделать это с peaberry, но я не могу иметь никакого смысла документации. Я инвестировал некоторое время в изучение Guice, таким образом, мой предпочтительный ответ не был бы "Spring использования Динамические Модули".

Кто-либо может дать мне простую идею того, как пойти о выполнении этого использования Guice/peaberry, OSGi или просто Java?

18
задан Chris Conway 20 January 2010 в 20:55
поделиться

5 ответов

На самом деле это довольно просто с помощью простого Java означает:

Поскольку вы не хотите, чтобы пользователь настраивал Classpath перед запуском приложения, я сначала создам URLClassLoader с массивом URL к файлам в вашем каталоге плагинов. Используйте File.listFiles, чтобы найти все банки плагинов, а затем File.toURI().toURL(), чтобы получить URL к каждому файлу. Вы должны передать системный загрузчик классов (ClassLoader.getSystemClassLoader()) в качестве родительского URLClassLoader.

Если банки плагинов содержат конфигурационный файл в META-INF/services, как описано в документации по API для java.util.ServiceLoader, то теперь вы можете использовать ServiceLoader.load(Plugin.class, myUrlClassLoader), чтобы обойти загрузчик сервисов для вашего интерфейса Plugin и вызвать на нём итератор(), чтобы получить экземпляры всех настроенных реализаций Plugin.

Вам всё равно придётся предоставить свою собственную обёртку вокруг этого для фильтрации возможностей плагина, но это не должно быть слишком большой проблемой, я полагаю.

17
ответ дан 30 November 2019 в 08:58
поделиться

Лучший способ внедрения плагинов с резиденцией состоит из MultiBindings . Связанная страница входит в подробную информацию о том, как использовать Multibindings для размещения хост-плагинов.

1
ответ дан 30 November 2019 в 08:58
поделиться

Есть ли шанс, что вы можете использовать интерфейс поставщика услуг ?

?
1
ответ дан 30 November 2019 в 08:58
поделиться

ОСГИ будет в порядке, если вы хотите заменить плагины во время выполнения I.G. Для исправлений в среде 24/7. Я сыграл некоторое время с ОСГИ, но потребовалось слишком много времени, потому что это было не требование, и вам нужен план B, если вы удалите пучок.

Мое скромное решение было, предоставляя файлы свойств с именами классов классов классов дескриптора плагинов и позвольте серверу позвонить им для регистрации (включая их возможности).

Это очевидно неоптимально, но я не могу дождаться, чтобы прочитать принятый ответ.

1
ответ дан 30 November 2019 в 08:58
поделиться

Попробуйте:

## take files.
files <- list.files(pattern=".csv")
## read data using loop
DF <- NULL
for (f in files) {
   dat <- read.csv(f, header=T, sep="\t", na.strings="", colClasses="character")
   DF <- rbind(DF, dat)
}
-121--2399345-

Мы также столкнулись с подобной проблемой. Это было достаточно давно, что я не помню точные детали, но суть его были некоторые незначительные различия между java.util.Date и то, как даты были обработаны в Javascript. Наш обходной путь фактически был таким же, как у вас, где фактическое значение, отправленное по проводу, было обычно последовательностью.

-121--3357802-

Приносите извинения, если это известно, но ознакомьтесь с методом forName класса . Он используется по крайней мере в JDBC для динамической загрузки специфичных для СУБД классов драйверов во время выполнения по имени класса.

Тогда, я полагаю, было бы нетрудно перечислить все файлы класса/банка в каталоге, загрузить каждый из них и определить интерфейс для статического метода getCapabilities () (или любое выбранное имя), который возвращает их возможности/описание в любых терминах и форматах, которые имеют смысл для вашей системы.

0
ответ дан 30 November 2019 в 08:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: