05 września 2008

OSGi - 4.5 Pakunek systemowy, 4.6 Zdarzenia oraz 4.7 Uruchomienie i zatrzymanie Platformy

Podstawowym bytem specyfikacji OSGi jest pakunek. Każda aplikacja oparta o OSGi to zestaw pakunków dostarczających pewnej funkcjonalności. Podobnie jest z samą Platformą OSGi, która nie tylko, że jest środowiskiem uruchomieniowym (kontenerem) pakunków, to sama jest również pakunkiem - pakunkiem systemowym.
 jlaskowski@work /cygdrive/c/apps/felix
$ java -jar ./bin/felix.jar

Welcome to Felix.
=================
...
-> ps
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.0.4)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.1)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.1)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.0.3)
W powyższym zrzucie z pracy Felix'a będzie to System Bundle o identyfikatorze 0.

Pakunek systemowy udostępnia interfejs rejestrowania nowych usług, np. Package Admin.
 -> services 0

System Bundle (0) provides:
---------------------------
objectClass = org.osgi.service.startlevel.StartLevel
service.id = 1
----
objectClass = org.osgi.service.packageadmin.PackageAdmin
service.id = 2
Pakunek systemowy jest zawarty w liście zainstalowanych pakunków zwracanej przez BundleContext.getBundles() (jak można przekonać się po wykonaniu polecenia ps w Felix).

Cechy pakunku systemowego:
  • Posiada identyfikator 0
  • Metoda getLocation() zwraca ciąg System Bundle zgodnie z deklaracją w Constants
  • Nazwa pakunku (Bundle-SymbolicName) jest unikalna dla danej wersji Platformy, jednakże nazwa system.bundle musi być rozpoznawana jako jej alias
  • Obsługa cyklu rozwojowego jest odmienna od typowych pakunków w ten sposób, że:
    • start jest operacją "pustą" (noop) - pakunek musi być zawsze uruchomiony
    • stop kończy pracę całej Platformy
    • update zatrzymuje i ponownie uruchamia Platformę
    • uninstall powoduje zgłoszenie wyjątku BundleException, gdyż pakunek systemowy nie może zostać odinstalowany
Rozdział 4.6 Zdarzenia przedstawia typy zdarzeń wspierane z warstwą zarządzania cyklem rozwojowym pakunków (dalej: warstwa rozwojowa) - BundleEvent oraz FrameworkEvent. Pierwszy, BundleEvent zawiera zmiany w cyklu rozwojowym pakunków, podczas gdy FrameworkEvent niesie informacje o uruchomieniu Platformy, zmianie w poziomie startowym, odświeżeniu pakietów lub wystąpieniu błędu.

Typ zdarzenia można odczytać za pomocą metody getType(), która zwraca wartość typu int odpowiadającą stałej zdefiniowanej w klasie zdarzenia. Nierozpoznane typy zdarzeń powinny być ignorowane.

Ze zdarzeniami związani są słuchacze (ang. listeners) - BundleListener oraz SynchronousBundleListener dla zdarzeń BundleEvent i FrameworkListener dla zdarzeń FrameworkEvent.

Zarządzanie rejestracjami słuchaczy odbywa się za pomocą metod interfejsu BundleContext.

Zdarzenia są (zazwyczaj) dostarczane asynchronicznie w wątku innym niż ten, w którym je zgłoszono.

Platforma zgłosi FrameworkEvent.ERROR, jeśli wystąpił niekontrolowany wyjątek podczas przekazywania zdarzenia do słuchacza (chyba, że miałoby to prowadzić do nieskończonej pętli, gdy przekazanie zdarzenia FrameworkEvent.ERROR spowodowałoby jego wystąpienie).

Zaleca się, aby pakunek wywoływał metody słuchacza poza sekcją objętą monitorem (sychronizacji), co mogłoby prowadzić do wystąpienia zakleszczenia.

W rozdziale 4.7 Uruchomienie i zatrzymanie Platformy znajdziemy informacje o krokach podejmowanych przez implementację podczas uruchamiania i zatrzymywania Systemu.

Uruchomieniu Systemu towarzyszy uruchomienie podsystemu obsługi zdarzeń, tak aby zdarzenia mogły być dostarczane do zainteresowanych słuchaczy, pakunek systemowy przechodzi w stan STARTING, wszystkie pakunki poprzednio zarejestrowane jako uruchomione zostają uruchomione, a wszelkie błędy opakowane jako BundleException, które z kolei są publikowane jako FrameworkEvent.ERROR, pakunek systemowy przechodzi w stan ACTIVE i rozgłaszane jest zdarzenie FrameworkEvent.STARTED.

Podczas zatrzymania Systemu pakunek systemowy przechodzi w stan STOPPING, wszystkie aktywne pakunki są zatrzymane z wyjątkami opakowanymi jako BundleException i rozgłoszone jako FrameworkEvent.ERROR i ostatecznie podsystem obsługi zdarzeń zostaje zatrzymany.

Jakby w prezencie pojawiła się nowa wersja Spring-DM (Spring Dynamic Modules for OSGi Service Platforms) 1.2.0 M1 - Spring Dynamic Modules 1.2.0 M1 Released. Jeszcze się z nią nie próbowałem, ale gdyby komuś się to udało, pożądanym jest podzielenie się wrażeniami ze światem. Na uwagę zasługuje przykład aplikacji webowej opartej o Spring-MVC dystrybuowanej w ramach Spring-DM.