Implementowanie dynamicznych wtyczek w Javie

Chciałbym zaimplementować dynamiczną funkcję wtyczki w aplikacji Java. Najlepiej:

  • Aplikacja zdefiniowałaby interfejs Plugin za pomocą metody takiej jak getCapabilities().
  • plugin byłby JAR pluginX.jar zawierający klasę PluginXImpl implementującą Plugin (i może kilka innych).
  • użytkownik umieszcza pluginX.jar w specjalnym katalogu lub ustawia parametr konfiguracyjny wskazujący na niego. Użytkownik nie powinien koniecznie włączać pluginX.jar do swojej ścieżki klasowej.
  • The aplikacja znalazłaby PluginXImpl (może poprzez manifest jar, może przez odbicie) i dodałaby go do rejestru.
  • klient może uzyskać instancję PluginXImpl, np. poprzez wywołanie metody takiej jak getPluginWithCapabilities("X"). Użytkownik niekoniecznie musi znać nazwę wtyczki.

Mam poczucie, że powinienem być w stanie to zrobić z peaberry , ale nie mogę zrozumieć żadnego sensu dokumentacji. Zainwestowałem trochę czasu w naukę Guice, więc moją preferowaną odpowiedzią nie byłoby " użyj Sprężynowe Moduły Dynamiczne ."

Czy ktoś może mi dać prosty pomysł jak to zrobić używając Guice/peaberry, OSGi lub po prostu zwykłej Javy?

Author: Chris Conway, 2010-01-20

5 answers

Jest to w rzeczywistości dość proste, używając zwykłej Javy oznacza:

Ponieważ nie chcesz, aby użytkownik skonfigurował classpath przed uruchomieniem aplikacji, chciałbym najpierw utworzyć URLClassLoader z tablicą adresów URL do plików w katalogu wtyczki. Użyj Pliku.listFiles, aby znaleźć wszystkie słoiki wtyczek, a następnie plik.toURI ().toURL (), aby uzyskać adres URL do każdego pliku. Należy przekazać system classloader (ClassLoader.getSystemClassLoader ()) jako rodzic dla Twojego Urlclassloadera.

Jeśli wtyczka jar zawiera plik konfiguracyjny w META-INF / services opisany w dokumentacji API dla języka java.util.ServiceLoader, możesz teraz użyć ServiceLoader.load (Plugin.class, myUrlClassLoader) do obatin a service loader for your Plugin interface and call iterator() on it to get instances of all configured Plugin implementations.

Nadal musisz DOSTARCZYĆ swój własny wrapper wokół tego filtrowania plugin capabilites, ale to nie powinno być zbyt wiele kłopotów, przypuszczam.

 17
Author: jarnbjo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-20 21:22:57

OSGI byłoby w porządku, jeśli chcesz wymienić wtyczki podczas wykonywania np. dla poprawek błędów w środowisku 24/7. Grałem trochę z OSGI, ale zajęło to zbyt dużo czasu, ponieważ nie było to wymaganie, a potrzebujesz planu b, jeśli usuniesz pakiet.

Moim skromnym rozwiązaniem było wtedy dostarczenie pliku właściwości z nazwami klas deskryptorów wtyczek i umożliwienie serwera wywołania ich do rejestracji (w tym kwestionowanie ich możliwości).

To oczywiste, że nieoptymalne, ale ja nie mogę się doczekać, aby przeczytać zaakceptowaną odpowiedź.

 1
Author: stacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-20 21:43:11

Jest jakaś szansa na wykorzystanie interfejsu dostawcy usług ?

 1
Author: trashgod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 01:19:36

Najlepszym sposobem na zaimplementowanie wtyczek z Guice jest użycie Multibindings . Powiązana strona szczegółowo opisuje, jak używać multibindingów do hostowania wtyczek.

 1
Author: Jesse Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 08:45:01

Przeproś, jeśli to wiesz, ale sprawdź forName metodę Klasy . Jest on używany przynajmniej w JDBC do dynamicznego ładowania specyficznych dla DBMS klas sterowników runtime według nazwy klasy.

Wtedy myślę, że nie byłoby trudno wyliczyć wszystkie pliki klas / jar w katalogu, załadować każdy z nich i zdefiniować interfejs dla statycznej metody getCapabilities() (lub dowolnej wybranej nazwy), która zwraca ich możliwości/opis w dowolnym terminie i formacie, który ma sens dla Twojego systemu.

 0
Author: Bandi-T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-20 20:55:24