Implementowanie dynamicznych wtyczek w Javie
Chciałbym zaimplementować dynamiczną funkcję wtyczki w aplikacji Java. Najlepiej:
- Aplikacja zdefiniowałaby interfejs
Plugin
za pomocą metody takiej jakgetCapabilities()
. - 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 jakgetPluginWithCapabilities("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?
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.
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ź.
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
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.
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.
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