18 września 2008

OSGi - 3.14 Pakunki częściowe

Ostatnimi czasy wielokrotnie spotykałem się z terminami OSGi fragment lub OSGi fragment bundle i zawsze kończyło się na...odłożeniu rozpoznania tematu na później (nawet podczas relacji lektury rozdziału 3. Warstwa modułowa w Kolejny łyk OSGi - rozdział 3. Warstwa modułowa nie napisałem o nich ani słowa!). Rozdział 3.14 Fragment Bundles to jedynie 4 strony (plus niewielki diagram), więc samej lektury na niecałe 5-10 minut i można ją powtórzyć (nawet kilkakrotnie).

Przyjrzyjmy się dokładniej, cóż specyfikacja ma do powiedzenia nt. pakunków częściowych w rodziale 3.14 Fragment Bundles.

Pakunki częściowe (ang. fragment bundles) są całkowicie zależne od pakunku wiodącego (przewodniego, ang. host bundle). Podczas fazy rozwiązywania (zależności) pakunku wiodącego Platforma OSGi dołącza do niego wszystkie dostępne pakunki częściowe. Innymi słowy pakunki częściowe stają się logicznie integralną częścią pakunku wiodącego (aczkolwiek fizycznie są wciąż osobnymi bytami). Stąd też pakunki częściowe współdzielą ładowarkę klas (ang. classloader) pakunku wiodącego.

Specyfikacja OSGi określa rolę pakunków częściowych jako dostawców tłumaczeń, co umożliwia dostarczanie ich niezależnie od pakunku wiodącego (w późniejszym terminie). Można sobie wyobrazić działanie pakunku wiodącego jako aplikacji webowej, do której tłumaczenia są dostarczane jako osobne pakunki częściowe, które ostatecznie stają się częścią aplikacji webowej. Wszystko obsługuje Platforma OSGi.

Aktualizacja pakunku częściowego jest widoczna dla pakunku wiodącego dopiero po ponownym uruchomieniu Platformy OSGi lub odświeżeniu pakunku wiodącego. Do tego momentu uaktualniony pakunek częściowy jest dołączony do pakunku wiodącego równolegle do poprzedniej wersji, ale pozostaje nieaktywny.

Usługa Package Admin zwraca ostatnią wersję dołączonego pakunku częściowego.

Pakunek częściowy może deklarować import części chronionej (prywatnej) pakunku wiodącego.

Podczas rozwiązywania środowiska dla pakunku częściowego jakikolwiek konflikt w deklaracjach z pakunkiem wiodącym działają na niekorzyść tego pierwszego, co w efekcie prowadzi do niezwiązania go z pakunkiem wiodącym. Poprawne rozwiązanie pakunku częściowego to pomyślnie związanie go z pakunkiem wiodącym i przejście do stanu RESOLVED.

Przeszukiwanie zasobów pakunku częściowego odbywa się po przeszukaniu zawartości pakunku wiodącego.

Pakunek częściowy nie może być zadeklarowany jako obowiązkowy przez nagłówek Require-Bundle.

Deklaracja środowiska pakunku częściowego zadeklarowana w jego META-INF/MANIFEST.MF jest dołączana na końcu odpowiednich deklaracji pakunku wiodącego (patrz: Bundle-Classpath). Kolejność dowiązania pakunków częściowych odpowiada porządkowi ładowania poszczególnych pakunków częściowych, czyli zgodnie z ich identyfikatorami, rosnąco.

Pakunek staje się pakunkiem częściowym przez użycie nagłówka Fragment-Host ze wskazaniem na pakunek wiodący z opcjonalnym wskazaniem na jego wersję (domyślnie najwyższa), np.
 Fragment-Host: org.springframework.bundle.osgi.extender;bundle-version=1.1.0
Nazwa pakunku wiodącego użyta w Fragment-Host musi być inna niż pakunku częściowego.

Pakunek wiodący zezwala na dowiązanie pakunków częściowych, jeśli zadeklarował BundlePermission[<nazwa symboliczna pakunku>,HOST], podczas gdy pakunek częściowy musi zadeklarować BundlePermission[<nazwa symboliczna pakunku>,FRAGMENT], aby został związany.

Pakunek częściowy jest związany, dopóty jego pakunek wiodący jest w stanie RESOLVED. Przejście w stan INSTALLED powoduje odłączenie pakunków częściowych. Wywołanie metod org.osgi.service.packageadmin.PackageAdmin.refreshPackages(Bundle[] bundles) lub org.osgi.service.packageadmin.PackageAdmin.resolveBundles(Bundle[] bundles) z pakunkiem wiodącym i/lub częściowym może spowodować zmianę stanu pakunku częściowego na INSTALLED.

Zabronione jest, aby pakunek częściowy deklarował własny aktywator (nagłówek Bundle-Activator).

Ostatecznie, dla utrwalenia wiadomości, warto zapoznać się z dokumentem E.1. OSGi Fragments w dokumentacji Spring Dynamic Modules (Spring-DM).

Niezwykle istotną informacją dotyczącą wsparcia pakunków częściowych (i potencjalnie dalszej ewaluacji Spring-DM) przez dostępne platformy OSGi jest jego brak w Apache Felix - FELIX-29 Implement bundle fragments oraz FELIX-656 Implement fragment support for extending a host's bundle class path. Ciekawy jest komentarz do zgłoszenia FELIX-656, gdzie można przeczytać "I got some feedback from the GlassFish team that after I fixed the last bug it has started working for their test case, so I am resolving this for now, but there is definitely more work to be done in this area." autorstwa Richard'a Hall'a, a przecież Richard przeszedł niedawno do Sun - Sun Hires Richard Hall, więc można spodziewać się więcej tego typu komentarzy (w końcu GlassFish v3 pracuje na kontenerze OSGi, podobnie jak IBM WebSphere Application Server 6.1 czy Eclipse IDE).

Dla zainteresowanych do czego zmierzam z rozpoznawaniem roli pakunków częściowych polecam lekturę dokumentu 8.4. Configuring the web extender w dokumentacji Spring-DM. Zdaje się, że bez zrozumienia pakunków częściowych nie ma co marzyć o zrozumieniu działania Spring-DM i jego poprawnej konfiguracji (z potencjalnym rozwiązywaniem błędów). Wciąż żądni wiedzy o OSGi?! Niedługo kolejne odsłony i relacje z moich rekonesansów po terenach OSGi.

1 komentarz:

  1. W ramach uzupełnienia:
    Do czego stosuje się w praktyce pakunki częściowe?
    1. Dołączanie dodatkowych zasobów do pakunku, w szczególności pliki z tłumaczeniami lub konfiguracją
    2. Jako rozwiązanie problemu:
    -mamy gotowy pakunek, którego nie możemy/nie chcemy zmieniać (np. nie jest nasz)
    -potrzebujemy dodać klasę w jednym z pakietów tego pakunku (bo np. wymaga ona dostępu do pól lub metod protected lub package-protected innych klas z tego pakietu.
    Nie możemy zrobić swojego pakunku z naszą klasą i wyeksportować w nim pakietu - ten sam pakiet byłby wtedy wyeksportowany z dwóch pakunków - co w praktyce daje problemy - patrz "split-packages"
    Rozwiązaniem jest utworzenie pakunku częściowego z dodatkową klasą i ustawienie mu pakunku wiodocego.
    3.w pakunkach częściowych można dostarczać "hooks" dla platformy osgi np. org.eclipse.equinox.weaving.hook z Equinox AspectJ

    OdpowiedzUsuń