Definiowanie komponentów usługowych z OSGi Declarative Services

Z Jacek Laskowski - Wiki Projektanta Java EE

Lektura książki OSGi and Equinox: Creating Highly Modular Java Systems gładko wprowadziła mnie w temat OSGi Declarative Services (w skrócie DS). Jest to specyfikacja komponentów usługowych w OSGi - część specyfikacji OSGi Service Platform Service Compendium wydanie 4, wersja 4.2 opisana w rozdziale 112. Declarative Services Specification. Na niecałych 50 stronach można zapoznać się z deklaratywną rejestracją usług na platformie OSGi.

OSGi Declarative Services zdejmuje z barków programisty utrzymywanie kodu, który wymagany był przez użycie OSGi w warstwie usługowej. W tonie zdejmowania obowiązków z barków programisty i parającym się OSGi zdecydowanie ulżono (nie wliczając w to poznania nowej specyfikacji). Już na etapie mojego skromnego doświadczenia w obszarze OSGi jestem w stanie zauważyć prostotę OSGi przy użyciu OSGi Declarative Services. To nic innego jak kolejna warstwa na warstwie usługowej OSGi.

Myliłby się jednak ten, kto sądziłby, że temat zarządzania usługami - tworzenie, uruchamianie, przekazywanie zależności z i do usługi, zatrzymywanie i odinstalowanie - zakończył się właśnie na etapie OSGi Declarative Services. Wyprzedzając trochę przyszłe tematy napiszę, że jest dużo trudniej wybrać to właściwe rozwiązanie, bo wybór jest nie między dwoma, ale trzeba podobnymi rozwiązaniami, z których dwa należą do ścisłego grona namaszczonych przez ciała standaryzujące kształt platformy OSGi. Jak mówią, podobno mieć wybór jest lepiej niż go nie mieć, a szczegóły opiszę w kolejnych odsłonach.

Ten wpis wciąż utrzymany jest w kanonie wpisów technicznych, gdzie nacisk kładę na poznanie technologii, a nie jej biznesowe zastosowanie (nad czym wciąż ubolewam i liczę, że w końcu komuś uda się wykrzesać z tego coś biznesowego).

Z OSGi Declarative Services użycie aktywatora w pakunku OSGi jest zawężone do bardzo specyficznych zastosowań. Jeśli obecnie jedynym powodem utrzymywania go było właśnie zarejestrowanie usługi OSGi lub w ogóle praca z usługami OSGi (śledzenie ich i zarządzanie nimi jako zależnościami pakunku), a sądzę, że tak faktycznie było w większości przypadków, to z DS możemy o nim zapomnieć na zawsze. Brak aktywatora uważam za krok w kierunku "nirwany" OSGi - taki wyższy poziom zaawansowania w tajnikach OSGi.

Niestety, zachwyconych kierunkiem rozwoju wyznaczonym przez Google Guice i Contexts and Dependency Injection for the Java EE Platform (w skrócie CDI) muszę zmartwić, bo konfiguracja usług i ich łączenie jako zależności odbywa się mechanizmami niezwykle prehistorycznymi - wciąż korzysta się wyłącznie z XML, co implikuje utratę silnego typizowania. Na zachętę wspomnę, że pracuje się nad tym i już istnieją niestandardowe, oparte na adnotacjach, rozszerzenia.

Podsumowując niekończący się wstęp do OSGi Declarative Services, wiemy już (a przynajmniej ja wierzę, że wy wiecie, albo zaczynają Was dręczyć pewne przekonania i intuicje), że w ramach platformy OSGi uruchamiamy pakunki, które z kolei rejestrują lub pozyskują dostęp do usług. Do niedawna jedynym słusznym podejściem związanym z zarządzaniem usług było wykonanie odpowiednich kroków we wspomnianym aktywatorze pakunku - klasie, która, uruchamiana przy uruchomieniu pakunku, wykonywała czynności administracyjne wokół usługi. W zasadzie, każdy aktywator przedstawiał się identycznie. Z OSGi Declarative Services można rzec "Nigdy więcej!". Jest on krokiem naprzód i w tym wpisie przedstawię, skąd rodzi się moje tak silne przekonanie. Chciałbym jednak zwrócić uwagę, że czytelnik znajdzie w tym artykule więcej odpowiedzi na pytania jak, a nie dlaczego.

Zachęcam do przesyłania uwag, które mogłyby przyczynić się do pojawienia się kolejnych artykułów z odpowiedziami na brakujące pytania. Czekam na nie pod jacek@japila.pl. Miłej lektury!

Spis treści

Przygotowanie projektu pakunku OSGi w Eclipse IDE - pl.jaceklaskowski.osgi.helloworld.polski

Jest wiele sposobów na stworzenie struktury katalogowej projektu pakunku OSGi. Idąc śladami poprzednich artykułów (chociażby Rapid OSGi development with Pax-Construct) skorzystam z Eclipse IDE oraz Eclipse Equinox. Tyle dobrego się o nich naczytałem we wspomnianej książce OSGi and Equinox: Creating Highly Modular Java Systems w kontekście budowania aplikacji opartych na OSGi, że nie sposób przejść koło nich obojętnie. Indoktrynacja zadziałała i zostałem przekonany o słuszności użycia własnie tego środowiska.

Wybieramy File > New > Other..., a następnie Plug-in Project.

Plik:osgi-ds-eclipse-plug-in-project.png

Przechodzimy do kolejnego kroku wciskając przycisk Next >.

Konwencją nazewniczą projektów-pakunków OSGi jest nadawanie im nazw odpowiadających nazwie symbolicznej pakunku (Bundle-SymbolicName w MANIFEST.MF), np. pl.jaceklaskowski.osgi.helloworld.polski i tak też zrobimy w naszym przypadku. Nazwa nie jest przypadkowa, ale to wyjaśni się niebawem.

Poza tym, wskazujemy an OSGi Framework na Equinox.

Plik:osgi-ds-eclipse-plug-in-project-details.png

Na kolejnym ekranie podajemy właściwości/charakterystykę pakunku OSGi - wartość pola ID, które stanie się wspomnianym Bundle-SymbolicName w MANIFEST.MF, odpowiada nazwie pakunku (i jednocześnie nazwie projektu). Ustawiamy pole Version na 1.0.0 i nazywamy pakunek HelloWorld :: Polski z podaniem dostawcy pakunku - pole Provider (wartość dowolna i nieistotna dla OSGi).

I najważniejsze - wyłączamy opcję utworzenia aktywatora, który nie jest potrzebny.

Plik:osgi-ds-eclipse-plug-in-project-data-to-generate-plugin.png

Zatwierdzamy przyciskiem Finish.

W niektórych konfiguracjach Eclipse może pojawić się pytanie o zmianę perspektywy, które kwitujemy stanowczym Yes (z opcjonalnym potwierdzeniem kolejnych przez włączenie opcji Remember my decision).

Plik:osgi-ds-eclipse-open-plug-in-development-perspective.png

Na zakończenie Eclipse uraczy nas otwarciem edytora manifestu OSGi pakunku.

Plik:osgi-ds-eclipse-manifest-editor.png

W widoku Package Explorer naszym oczom ukaże się świeżo utworzony projekt pl.jaceklaskowski.osgi.helloworld.polski.

Plik:osgi-ds-eclipse-package-explorer.png

Wciąż niewiele w nim kodu źródłowego, ale za chwilę się to zmieni.

Określenie interfejsu publicznego komponentu DS - pl.jaceklaskowski.osgi.helloworld.ExampleService

W artykule Rapid OSGi development with Pax-Construct utworzyliśmy projekt pakunku OSGi pl.jaceklaskowski.osgi.helloworld.api, który przez aktywator rejestrował usługę realizującą publiczny interfejs pl.jaceklaskowski.osgi.helloworld.ExampleService.

Zainteresowanych szczegółami odsyłam do lektury artykułu, a na potrzeby tego, importujemy już utworzony projekt - pl.jaceklaskowski.osgi.helloworld.api.

Z zaimportowanym projektem widok package Explorer powinien zawierać 2 projekty pakunków.

Plik:osgi-ds-eclipse-package-explorer-projects-api-polski.png

Opcjonalnie, w projekcie pl.jaceklaskowski.osgi.helloworld.api można wyłączyć rejestrację usługi ExampleService wyłączając aktywator. Jak?! Pytania proszę kierować pod jacek@japila.pl. W ten sposób zagwarantujemy, że tylko jedna usługa, która realizuje ExampleService będzie dostępna i to będzie ta, którą właśnie tworzymy, a nie poprzednia. Podkreślam, że jest to jednak krok opcjonalny.

Deklaracja dostępnych pakietów - zakładka Dependencies edytora MANIFEST.MF

Zanim możliwe będzie utworzenie usługi, należy zaimportować pakiet do przestrzeni pakunku komponentu DS. Realizujemy to w tym samym stylu, co import każdego dowolnego pakietu w OSGi - przez atrybut Bundle-ImportPackage w MANIFEST.MF. Tym razem jednak, skorzystamy ze wsparcia Eclipse IDE.

W edytorze MANIFEST.MF pakunku pl.jaceklaskowski.osgi.helloworld.polski wybieramy zakładkę Dependencies (u dołu edytora). W niej możemy skorzystać z sekcji Imported Packages, albo Automated Management of Dependencies. Wybieram tę drugą opcję ze względu na jej większą elastyczność odnośnie zarządzania zależnościami między pakunkami tak, że wszystkie wyeksportowane pakiety są automatycznie importowane (wspaniała pomoc przy aktywnym rozwoju pakunków).

W sekcji Automated Management of Dependencies dodaję (przycisk Add...) pakunek pl.jaceklaskowski.osgi.helloworld.api. Upewnij się, że opcja Import-Package u dołu sekcji jest wybrana.

Plik:osgi-ds-eclipse-manifest-editor-automated-mgmt-dependencies.png

Zaletą użycia Automated Management of Dependencies jest możliwość zadeklarowania potencjalnych pakunków, których publiczne API nie jest dodawane do MANIFEST.MF natychmiast, ale dopiero po użyciu w kodzie pakunku. W takiej sytuacji należy wybrać aktywne add dependencies i jedynie używane pakiety zostaną dodane do manifestu. O tym jednak później.

Nie obędzie się bez skorzystania z sekcji Imported Packages dodając do pakunku obowiązkowy pakiet org.osgi.framework.

Plik:osgi-ds-eclipse-manifest-editor-imported-packages.png

Utworzenie początkowej konfiguracji komponentu DS - Component Definition w Eclipse

Podstawowym bytem platformy OSGi jest pakunek. Za jego pomocą w warstwie usługowej dodawane lub usuwane są usługi. Dzięki sieci powiązanych ze sobą usług tworzymy aplikację opartą na usługach OSGi - prawdziwie usługowa platforma...SOA (!)

W OSGi Declarative Services kładzie się nacisk na ową sieć powiązanych między sobą usług, które są przyczynkiem do utworzenia komponentów DS - bytów udostępniających i/lub korzystających z usług. Jak wspomniałem wcześniej, DS określa komponent jak podstawowy budulec aplikacji OSGi. Tym razem jednak nie mówi się o usługach, ale o modelu komponentów DS.

Utworzenie jednego nie nastręcza trudności, bo sprowadza się do stworzenia zwykłej klasy - POJO, która przez mechanizm publicznych metod o określonej sygnaturze otrzymuje dostęp do innych komponentów usługowych. Jeśli komukolwiek przywodzi to na myśl mechanizm Inversion of Control (IoC) z naciskiem na Dependency Injection (DI), to właściwie zrozumiał działanie DS. OSGi Declarative Services jest właśnie DI dla platformy OSGi.

Stwórzmy komponent DS o nazwie HelloWorldPoPolsku. W tym celu skorzystamy ze wsparcia Eclipse IDE.

Z menu kontekstowego projektu pl.jaceklaskowski.osgi.helloworld.polski (pod prawym przyciskiem myszki) wybieramy New > Component Definition.

Plik:osgi-ds-eclipse-new-component-definition.png

Konwencją DS jest umieszczanie konfiguracji komponentu w pliku OSGI-INF/component.xml w pakunku i tak też zrobimy. Katalog OSGI-INF nie istnieje jeszcze, więc po prostu dopisujemy do w polu "Enter or select the parent folder". Dla zwrócenia uwagi, napiszę, że nazwa pliku konfiguracyjnego oraz katalog, w którym zostanie umieszczony są całkowicie dowolne, bo ostatecznie informacja o nich trafia do MANIFEST.MF (nie sądziliście przecież, że może być inaczej, co?!)

Pozostałe pole Name zostawiamy z wartością domyślą, która odpowiada nazwie projektu - pl.jaceklaskowski.osgi.helloworld.polski.

W polu Class korzystamy z asystenta utworzenia nowej klasy komponentu wciskając aktywny napis Class, który jest równocześnie nazwą pola. Tworzymy klasę pl.jaceklaskowski.osgi.helloworld.internal.HelloWorldPoPolsku (zgodnie z konwencją nazewniczą, przynajmniej w świecie Eclipse, pakiet internal zawiera wewnętrzne pakiety i typy, które nie są przedmiotem publicznego interfejsu pakunku - są ukryte).

Plik:osgi-ds-eclipse-component-definition-details.png

UWAGA: Tylko przechodząc kroki asystenta Class zostanie utworzona klasa komponentu DS. Samo wprowadzenie nazwy w polu już nie.

Zatwierdzamy konfigurację komponentu przyciskiem Finish.

Utworzenie komponentu DS - HelloWorldPoPolsku

Treść klasy pl.jaceklaskowski.osgi.helloworld.internal.HelloWorldPoPolsku, która jest rozwijana w duchu POJO, zmieniamy na następującą:

package pl.jaceklaskowski.osgi.helloworld.internal;
 
import pl.jaceklaskowski.osgi.helloworld.ExampleService;
 
public class HelloWorldPoPolsku implements ExampleService {
 
    @Override
    public String scramble(String text) {
        return text + "-scrambled";
    }
 
    void startup() {
        System.out.println("Utworzono mnie");
    }
 
    void shutdown() {
        System.out.println("Zatrzymano mnie");
    }
}

Warte szczególnej uwagi są dodatkowe metody spoza interfejsu pl.jaceklaskowski.osgi.helloworld.ExampleService - startup oraz shutdown, które wykorzystamy jako metody zwrotne do przechwycenia zmian stanu komponentu DS.

Konfiguracja Imported Packages w MANIFEST.MF - import pakietu pl.jaceklaskowski.osgi.helloworld

Niewielu zapewne pamięta krok, w którym określaliśmy dynamiczne wyliczanie importowanych pakietów w pakunku naszego komponentu DS. Przyszła pora skorzystać z jego dobrodziejstw.

W OSGi określenie dostępności typów - klas i interfejsów - odbywa się deklaratywnie przez atrybut Bundle-ImportPackages w manifeście pakunku. Bez tej konfiguracji jedynie typy domyślnie udostępniane przez platformę uruchomieniową - zwykle java.* oraz org.osgi.framework.* są dostępne.

W naszym przypadku korzystamy z interfejsu pl.jaceklaskowski.osgi.helloworld.ExampleService, który nie należy do wspomnianych pakietów, a więc koniecznie należy jawnie wskazać potrzebę dostępności pakietu przed uruchomieniem naszego pakunku. Kiedy określiliśmy, że nasz pakunek zależy od pakunku pl.jaceklaskowski.osgi.helloworld.api w sekcji Automated Management of Dependencies (zakładka Dependencies w edytorze MANIFEST.MF) wskazaliśmy na dynamiczną zależność między pakunkami (właściwie między pakunkiem importującym eksportowany pakiet), która nie modyfikuje manifestu, więc nie związuje pakunku z wymaganym pakietem.

Wciskając link add dependencies w zakładce Dependencies edytora manifestu, Eclipse wyliczy konieczne importy i w ten sposób doda pakiet pl.jaceklaskowski.osgi.helloworld do Imported Packages.

Plik:osgi-ds-eclipse-manifest-editor-imported-packages-after-add-dependencies.png

Nie zapominamy o zapisaniu zmian.

Konfiguracja komponentu DS - OSGI-INF/component.xml

Natychmiast po zatwierdzeniu konfiguracji komponentu przyciskiem Finish otworzy się edytor konfiguracji komponentu DS - OSGI-INF/component.xml.

W zakładce Overview określamy wartość pola Activate oraz Deactivate, które zdefiniowaliśmy wcześniej do przechwycenia zmiany stanu przy uruchamianiu i zatrzymaniu komponentu.

Plik:osgi-ds-eclipse-component-overview-tab.png

Przechodzimy do zakładki Services, w której określamy udostępnianą usługę, a właściwie jej interfejs publiczny pl.jaceklaskowski.osgi.helloworld.ExampleService.

Plik:osgi-ds-eclipse-component-services-tab.png

Wróćmy do zakładki Overview, w której jedynie dla naszych celów poznawczych (i tylko dlatego!) włączymy opcję This component is immediately activated. Jest to opcja, która jest aktywna po zdefiniowaniu usługi, którą właśnie udostępniliśmy.

Domyślnie, uruchomienie komponentu jest leniwe i opóźnione do momentu, kiedy nastąpi pierwsze jego użycie. Przy braku klienta i włączenia tego parametru poza samym wczytaniem definicji komponentu nic nie pojawiłoby się na konsoli (i niektórzy mogliby pomyśleć, że w zasadzie nic nie stworzyliśmy - nic bardziej mylnego).

Plik:osgi-ds-eclipse-component-overview-tab-this-component-is-immediately-activated.png

Kompletny plik konfiguracyjny komponentu DS - OSGI-INF/component.xml - powinien przedstawiać się następująco (zakładka Source):

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
   activate="startup" deactivate="shutdown" immediate="true" name="pl.jaceklaskowski.osgi.helloworld.polski">
   <implementation class="pl.jaceklaskowski.osgi.helloworld.internal.HelloWorldPoPolsku"/>
   <service>
      <provide interface="pl.jaceklaskowski.osgi.helloworld.ExampleService"/>
   </service>
</scr:component>

Utworzenie konfiguracji uruchomieniowej - Run Configuration

Pora przygotować konfigurację uruchomieniową dla naszego komponent DS - HelloWorldPoPolsku. Ponownie skorzystamy z dobrodziejstw Eclipse IDE, w którym zdefiniujemy konfigurację uruchomieniową - Run Configuration.

Z menu głównego wybieramy Run > Run Configurations...

Plik:osgi-ds-eclipse-run-configuration-menu.png

Zaznaczamy OSGi Framework i wciskamy przycisk New launch configuration (dostępny jako New pod prawym przyciskiem myszki).

OSGi Framework - zakładka Bundles

Nadajemy nazwę naszej konfiguracji, np. HelloWorldPoPolsku oraz wskazujemy na wymagane pakunki OSGi w konfiguracji. Skorzystaj z pola filtrowania do wyszukania odpowiednich pakunków z listy, która może zawierać aż 791 pakunków. Wyłącz wszystkie przyciskiem Deselect All (po prawej jako drugi przycisk od góry) i wybierz następujące:

  • wszystkie w kategorii Workspace:
    • pl.jaceklaskowski.osgi.helloworld.api
    • pl.jaceklaskowski.osgi.helloworld.polski
  • podane poniżej w kategorii Target Platform:
    • org.eclipse.equinox.ds
    • org.eclipse.equinox.util
    • org.eclipse.osgi
    • org.eclipse.osgi.services

Dodatkowo wyłączamy opcje Include optional dependencies when computing required bundles oraz Add new workspace bundles to this launch configuration automatically.

Zakładka Bundles powinna przedstawiać się jak na poniższym zrzucie ekranu.

Plik:osgi-ds-eclipse-launch-configuration-bundles.png

Skorzystaj z przycisku Validate Bundles, aby sprawdzić kompletność zestawu pakunków przed uruchomieniem. Poprawna kontrola zwróci komunikat No problems were detected.

Plik:osgi-ds-eclipse-launch-configuration-bundles-validate-bundles.png

OSGi Framework - zakładka Arguments

W zakładce Arguments zmieniamy VM arguments tak, aby zawierała parametr -Dequinox.ds.print=true, która Specifies that logged entries should be printed to the framework runtime console (za Equinox/RuntimeOptions). Jest to krok całkowicie opcjonalny i nie jest wymagany do poprawnego działania naszego komponentu DS, aczkolwiek może pomóc przy niepoprawnym działaniu.

Plik:osgi-ds-eclipse-launch-configuration-arguments.png

OSGi Framework - zakładka Settings

Kluczową rolę przy aktywnym rozwoju pakunków OSGi, a w szczególności komponentów DS jest parametr Clear the configuration area before launching. Platforma OSGi przechowuje stan pakunków w katalogu nazywanym Configuration Area, dzięki któremu gwarantuje ich trwałość między ponownymi uruchomieniami. Wspomniany parametr kasuje katalog tymczasowy, efektywnie kasując stan pakunków, co może być znaczące przy ciągłym dodawaniu, usuwaniu i w ogóle zmianie uruchamianych pakunków czy komponentów DS.

Plik:osgi-ds-eclipse-launch-configuration-settings.png

OSGi Framework - zakładka Common

W zakładce Common zaznaczamy pozycję Run w sekcji Display in favorites menu.

Plik:osgi-ds-eclipse-launch-configuration-common.png

W ten sposób nasza konfiguracja uruchomieniowa będzie dostępna w menu Run i stamtąd właśnie będziemy uruchamiać naszą konfigurację.

Plik:osgi-ds-eclipse-launch-configuration-run-helloworldpopolsku-menu.png

Zatwierdzamy zmiany przyciskiem Apply.

Pozostałe zakładki są w ich domyślnych konfiguracjach.

Uruchomienie komponentu DS z Eclipse Equinox

Definiując wcześniej konfigurację uruchomieniową określiliśmy, że środowiskiem wykonawczym naszego komponentu DS będzie Eclipse Equinox. Konfiguracja o nazwie HelloWorldPoPolsku dostępna jest w menu Run w menu podręcznym.

Uruchomienie konfiguracji daje następujący wynik w widoku Console:

Plik:osgi-ds-eclipse-console-view.png

Tym samym przekonaliśmy się, że uruchomienie naszego pakunku natychmiast inicjuje i uruchamia nasz komponent DS - HelloWorldPoPolsku (co nie jest domyślnym ustawieniem i nie jest również zalecane).

Wystarczy wyłączyć parametr This component is immediately activated w OSGI-INF/component.xml, aby przekonać się, że w środowisku pojawi się jedynie pośrednik (proxy) naszej usługi, więc ani metoda startup, ani nawet konstruktor klasy nie zostaną wywołane.

Wydając polecenie ss (short status) możemy poznać stan pakunków.

osgi> ss
 
Framework is launched.
 
id	State       Bundle
0	ACTIVE      org.eclipse.osgi_3.6.2.R36x_v20110210
1	ACTIVE      pl.jaceklaskowski.osgi.helloworld.polski_1.0.0
2	ACTIVE      org.eclipse.osgi.services_3.2.100.v20100503
3	ACTIVE      pl.jaceklaskowski.osgi.helloworld.api_1.0.0
4	ACTIVE      org.eclipse.equinox.ds_1.2.1.R36x_v20100803
5	ACTIVE      org.eclipse.equinox.util_1.0.200.v20100503

Wśród nich jest pakunek pl.jaceklaskowski.osgi.helloworld.polski_1.0.0 o identyfikatorze 1, który zawiera komponent DS.

Wydając polecenie bundle 1 możemy odczytać jego charakterystykę.

osgi> bundle 1
pl.jaceklaskowski.osgi.helloworld.polski_1.0.0 [1]
  Id=1, Status=ACTIVE      Data Root=/Users/jacek/Documents/eclipse-workspaces/osgi/.metadata/.plugins/
org.eclipse.pde.core/HelloWorldPoPolsku/org.eclipse.osgi/bundles/1/data
  Registered Services
    {pl.jaceklaskowski.osgi.helloworld.ExampleService}={component.name=pl.jaceklaskowski.osgi.helloworld.polski, component.id=0, service.id=31}
  No services in use.
  No exported packages
  Imported packages
    org.osgi.framework; version="1.5.0"<org.eclipse.osgi_3.6.2.R36x_v20110210 [0]>
    pl.jaceklaskowski.osgi.helloworld; version="1.0.0"<pl.jaceklaskowski.osgi.helloworld.api_1.0.0 [3]>
  No fragment bundles
  Named class space
    pl.jaceklaskowski.osgi.helloworld.polski; bundle-version="1.0.0"[provided]
  No required bundles

Polecenia ss oraz bundle należą do domyślnych poleceń Eclipse Equinox.

Uruchomienie Eclipse Equinox Declarative Services (pakunek org.eclipse.equinox.ds) pozwala na użycie dodatkowych poleceń do pracy z komponentami DS. Wydając polecenie help możemy je poznać w sekcji Service Component Runtime.

---Service Component Runtime---
	list/ls [-c] [bundle id] - Lists all components; add -c to display the complete info for each component;
			use [bundle id] to list the components of the specified bundle
	component/comp <component id> - Prints all available information about the specified component;
			<component id> - The ID of the component as displayed by the list command
	enable/en <component id> - Enables the specified component;
			<component id> - The ID of the component as displayed by the list command
	disable/dis <component id> - Disables the specified component;
			<component id> - The ID of the component as displayed by the list command
	enableAll/enAll [bundle id] - Enables all components; use [bundle id] to enable all components of the specified bundle
	disableAll/disAll [bundle id] - Disables all components; use [bundle id] to disable all components of the specified bundle

Skorzystajmy z nich. Zacznijmy od ls.

osgi> ls
All Components:
ID	State			Component Name			Located in bundle
1	Active		pl.jaceklaskowski.osgi.helloworld.polski			pl.jaceklaskowski.osgi.helloworld.polski(bid=1)

Sprawdźmy wynik polecenia comp.

osgi> comp 1
	Component[
	name = pl.jaceklaskowski.osgi.helloworld.polski
	activate = startup
	deactivate = shutdown
	modified = 
	configuration-policy = optional
	factory = null
	autoenable = true
	immediate = true
	implementation = pl.jaceklaskowski.osgi.helloworld.internal.HelloWorldPoPolsku
	state = Unsatisfied
	properties = 
	serviceFactory = false
	serviceInterface = [pl.jaceklaskowski.osgi.helloworld.ExampleService]
	references = null
	located in bundle = pl.jaceklaskowski.osgi.helloworld.polski_1.0.0 [1]
]
Dynamic information :
  The component is satisfied
  All component references are satisfied
  Component configurations :
    Configuration properties:
      component.name = pl.jaceklaskowski.osgi.helloworld.polski
      component.id = 0
      objectClass = String[pl.jaceklaskowski.osgi.helloworld.ExampleService]
    Instances:
      org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl@45b34126

Co okazuje się być prawie równoznaczne z ls -c.

osgi> ls -c
All Components:
ID	Component details
1	Component[
	name = pl.jaceklaskowski.osgi.helloworld.polski
	activate = startup
	deactivate = shutdown
	modified = 
	configuration-policy = optional
	factory = null
	autoenable = true
	immediate = true
	implementation = pl.jaceklaskowski.osgi.helloworld.internal.HelloWorldPoPolsku
	state = Unsatisfied
	properties = 
	serviceFactory = false
	serviceInterface = [pl.jaceklaskowski.osgi.helloworld.ExampleService]
	references = null
	located in bundle = pl.jaceklaskowski.osgi.helloworld.polski_1.0.0 [1]
]
Dynamic information :
  The component is satisfied
  All component references are satisfied
  Component configurations :
    Configuration properties:
      component.name = pl.jaceklaskowski.osgi.helloworld.polski
      component.id = 0
      objectClass = String[pl.jaceklaskowski.osgi.helloworld.ExampleService]
    Instances:
      org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl@45b34126

W ten sposób można nabrać pewności, że z naszym komponentem DS wszystko w należytym porządku. W kolejnych odsłonach przygotowanie do budowania dynamicznej aplikacji desktopowej. Miłej zabawy z OSGi R4 Declarative Services!

Osobiste