JAX 08 - Experiences using Equinox Aspects in a real-world Project
JM 03/09 - OSGi in kleinen Dosen 4
1. Java Core OSGi in kleinen Dosen – Teil 4
Services auf
deklarative Weise
Die OSGi Service Platform (OSGi) hat sich zu einem sehr bedeutenden
Standard im Java-Umfeld entwickelt. Also wird es für den engagierten Java-
Entwickler allerhöchste Zeit, sich damit näher auseinanderzusetzen.
von Heiko Seeberger
BundleActivator bereitstellen. Dessen
n den ersten drei Artikeln die- ist, rasch eine hohe Komplexität errei-
Methode start() bietet Zugriff auf den
ser Serie über die technischen chen. Wenn beispielsweise ein Service
BundleContext, mit dem z. B. Services
Grundlagen von OSGi wurden andere zwingend benötigt, dann müssen
an der OSGi Service Registry registriert
die drei wesentlichen OSGi-Prinzipien die erforderlichen Services beobachtet
oder ServiceTracker zu Beobachtung
kennengelernt: Modularisierung, Lauf- und der abhängige je nach deren Ver-
und Nutzung von Services erzeugt wer-
zeitdynamik und Services. Au auend fügbarkeit registriert bzw. deregistriert
den können. Dieser programmatische
auf diesem Fundament bieten OSGi De- werden. Diese Komplexität kann sich
Ansatz ist zwar sehr flexibel und für
clarative Services (DS) einen Ansatz zur insbesondere bei „größeren“ Projekten
„kleine“ Systeme hervorragend geeig-
Vereinfachung des Umgangs mit dyna- nachteilig bemerkbar machen. Zweitens
net, kann jedoch die folgenden beiden
mischen Services. werden beim programmatischen Ansatz
Nachteile mit sich bringen: Services gleich beim Starten der Bundles
Wozu ein deklarativer Ansatz? erzeugt und registriert, ganz unabhän-
gig davon, ob sie überhaupt jemals be-
Das OSGi Service Model aus dem letz- Hohe Komplexität
nötigt werden. Gerade bei Systemen, die
ten Artikel ermöglicht Kollaboration Lange Start-up-Dauer und hoher Spei-
aus zahlreichen Bundles bestehen, kann
zwischen Bundles, ohne diese starr an- cherverbrauch
dies leicht zu einer allzu hohen Start-up-
einanderzukoppeln. Damit ein Bundle
Dauer führen. Natürlich stellt auch der
Services anbieten oder nutzen kann, Erstens kann der Code, der zum Um-
möglicherweise unnötige Speicherver-
muss es gestartet werden und einen gang mit dynamischen Services nötig
brauch für Systeme, die mit den verfüg-
baren Ressourcen schonend umgehen
müssen, ein ernstha es Problem dar.
Artikelserie: OSGi in kleinen Dosen Die Declarative Services Speci ca-
tion [1] aus dem Service Compendium
Teil 1: Erste Schritte mit OSGi
der OSGi-Spezi kation adressiert genau
Teil 2: Immer in Bewegung – Bundles und Life Cycle
diese beiden Nachteile: Durch ein dekla-
Quellcode Teil 3: Was wünschen Sie? – Services à la OSGi
ratives Service Component Model wird
auf CD Teil 4: Services auf deklarative Weise die Handhabung von OSGi Services ver-
Teil 5: Hier wird „Service“ groß geschrieben – Ausgewählte OSGi-Standardservices einfacht, und durch die Möglichkeit von
Delayed Components können Start-up-
16 javamagazin 3|2009 www.JAXenter.de
2. OSGi in kleinen Dosen – Teil 4 Java Core
Dauer und Speicherverbrauch optimiert der kompletten Target Platform auf der
werden. Begleit-CD oder als Download [6].
Bevor wir uns im Detail mit OSGi
Service Components
Declarative Services beschä igen, sei er-
wähnt, dass es noch weitere vergleichba- Wie sieht nun der deklarative Ansatz des
re Ansätze gibt. Ein sehr populärer Ver- Service Component Models aus? Abbil-
treter ist Spring Dynamic Modules [2], dung 1 zeigt exemplarisch zwei aktive
das gemäß der aktuellen Early-Draft- Bundles, die je eine Service Component
Version der OSGi-Spezi kation 4.2 [3] enthalten. Da Declarative Services, wie
als RCF 124 Blueprint Service standardi- erwähnt, auf dem OSGi Service Model Abb. 1: OSGi Service Component Model
siert werden wird. Weitere Ansätze sind aufsetzen, gilt analog, dass Bundles ge-
z. B. Apache Felix iPOJO [4] und Guice startet werden müssen, damit ihre Ser-
Peaberry [5]. All diesen gemeinsam ist, vice Components erzeugt werden. Al-
dass sie keine proprietären Mechanis- lerdings ist kein BundleActivator mehr
men zur Kollaboration verwenden, son- erforderlich, und die tatsächliche Er-
dern auf dem OSGi Service Model auf- zeugung kann verzögert erfolgen, doch
bauen. Dadurch sind sie untereinander dazu später mehr.
und auch mit dem programmatischen Service Components bestehen aus
Ansatz vollständig kompatibel, sodass in einer XML-Beschreibung (Component
einem System durchaus mehrere dieser Description) und einem Objekt (Com-
Ansätze gleichzeitig verwendet werden ponent Instance). Sie können OSGi
Abb. 2: Service Component Runtime
können. Services sowohl bereitstellen als auch
referenzieren. Die Component Descrip-
Beispiel und tion enthält alle Informationen über die <component name=quot;com.weiglewilczek...shellquot;>
Entwicklungsumgebung <implementation class=quot;com.weiglewilczek...
Service Component, z. B. den Klassen-
Componentquot;/>
namen für die Component Instance, die
Das etablierte Beispiel des „universellen
</component>
Service Interfaces für die bereitgestellten
Adressbuchs“ aus den letzten Artikeln
Services etc.
wird zum Teil auf OSGi Declarative Ser-
So weit, so gut, doch wer erzeugt ei-
vices umgestellt. Dazu wird das bereits O gibt es pro Bundle nur eine Service
existierende Bundle com.weiglewilczek. gentlich die Service Components? Da- Component, und dann ist es ein gängiges
example.osgi.contacts.shell angepasst, zu kommt ein besonderes Pattern zum Pattern [8], wie in unserem Beispiel die
Einsatz: Das Extender Model [7]. Dar-
und zwar wird ein eigenes Kommando Klasse mit Component und die Compo-
nent Description mit component.xml zu
in gibt es ein spezielles Bundle, das alle
für die Equinox Console hinzugefügt,
indem das Interface CommandProvider anderen Bundles beobachtet, analysiert bezeichnen.
und anhand von gewissen Kriterien
implementiert und als Service regis-
Services bereitstellen
triert wird. Über die Methode _listAll(), Aktionen im Namen dieser Bundles
durchführt. Im konkreten Fall handelt
deren Signatur zwingend mit einem Un- Eine solche minimale Service Com-
es sich beim Extender Bundle um die so
terstrich beginnen muss, wird das Kom- ponent ist natürlich ohne praktische
genannte Service Component Runtime
mando mit dem abgeleiteten Namen Relevanz. Interessant wird es, sobald
listAll für die Equinox Console verfügbar (Abb. 2). Diese prü für alle gestarteten die Service Component einen Service
Bundles, ob deren Bundle Manifest den
gemacht. Wie der Name erahnen lässt, bereitstellt. Dazu dient in der Compo-
nent Description das Element service
Manifest Header Service Component
sollen für alle verfügbaren ContactRepo-
enthält, der eine oder auch mehrere
sitorys alle Contacts ausgegeben werden. mit einem oder mehreren Subelemen-
ten provide für die Angabe von Service
Component Descriptions referenziert,
Alles, was hierbei mit Services zu tun hat,
z. B.:
wird mittels OSGi Dynamic Services um- Interfaces:
gesetzt. Dazu benötigen wir einige weite-
Service-Component: OSGI-INF/component.xml <component immediate=quot;falsequot; ...>
re Bundles in unserer Target Platform:
...
<service>
org.eclipse.osgi.services: API für OSGi Aufgrund der Informationen in den
<provide interface=quot;org.eclipse...
Standard Services, u. a. DS Component Descriptions erzeugt die CommandProviderquot;/>
org.eclipse.equinox.ds und org.eclipse. Service Component Runtime die Service </service>
equinox.util: Equinox-Implementie- Components für diese „DS-powered“ </component>
rung für DS Bundles. Eine minimale Component
Description enthält nur deren Namen,
Wie immer nden Sie den kompletten der global eindeutig sein muss, sowie den Service Components, die einen Service
Sourcecode des Beispiels einschließlich Klassennamen der Component Instance: bereitstellen, sind standardmäßig De-
javamagazin 3|2009 17
www.JAXenter.de
3. Java Core OSGi in kleinen Dosen – Teil 4
tiviert wird, wenn mindestens ein Con-
layed Components. Das bedeutet, dass spezi ziert wird. Damit wird zwischen
tactRepository Service vorhanden ist.
sie nicht gleich erzeugt werden, sondern einfachen und mehrfachen sowie opti-
Gleichzeitig wird unsere Component
an ihrer Stelle ein Proxy in der Service Re- onalen und obligatorischen Referenzen
auch erst dann als CommandProvider
gistry registriert wird. Erst wenn der be- unterschieden. Wenn eine Referenz
Service registriert. Insgesamt verein-
reitgestellte Service erstmalig verwendet mittels „1..1“ oder „1..n“ als obligato-
facht sich der Code durch die Verwen-
werden soll, wird eine Delayed Compo- risch deklariert wird, wird die Service
dung von OSGi Declarative Services
nent erzeugt. Dieses Verhalten kann über Component frühestens dann aktiviert,
das Attribut immediate des Elements (Listing 2) im Vergleich zum program-
wenn die Referenz erfüllt werden kann,
component modi ziert werden. matischen Ansatz (Listing 1) erheblich.
d. h. wenn ein passender Service regis-
In unserem Beispiel stellt die Service triert wurde. Weiter wird, falls die Ser-
Schlussbemerkung und
Component im Bundle com.weiglewil- vice Component einen Service anbietet,
Ausblick
czek.example.osgi.contacts.shell den Ser- dieser bzw. dessen Proxy erst dann in der
vice CommandProvider zur Verfügung. Service Registry registriert, wenn die Die Spezi kation der OSGi Declarati-
Um ganz nach POJO-Prinzip die eigent- Referenz erfüllt wird. Umgekehrt wird ve Services bietet noch etliche Details,
lichen Domänenobjekte frei von OSGi- die Service Component deaktiviert und z. B. zum Lebenszyklus von Service
API zu halten, bietet es sich an, nicht die ein allfälliger Service deregistriert, wenn Components, zu Referenzen, zu Facto-
Domänenobjekte selbst als Component die Referenz nicht mehr erfüllt werden ry Components etc. Doch schon diese
kann. Über das Attribut name wird ein
Instances zu verwenden, sondern Wrap- kurze Einführung zeigt, wie wir von den
per einzusetzen [8]. In unserem Beispiel lokaler Name spezi ziert, über den im Vereinfachungen im Umgang mit OSGi
ist das „Domänenobjekt“ die Klasse Code der Component Instance auf die Services pro tieren können, die das Ser-
ListAllCommand, die Abhängigkeiten Referenz zugegriffen werden kann, je vice Component Model bietet. Abschlie-
nach Kardinalität mittels Component-
auf die registrierten ContactRepository ßend soll nochmals ausdrücklich betont
Context.loacteService() oder Compo-
Services hat. Diese Serviceabhängigkei- werden, dass OSGi Declarative Servi-
nentContext.locateServices(). Der da-
ten werden von der Service Component ces ohne Einschränkung mit dem pro-
verwaltet, also von der Klasse Compo- für erforderliche ComponentContext grammatischen Ansatz oder auch mit
nent. So kann ListAllCommand frei von wird in der optionalen Methode acti- anderen OSGi-Komponentenmodellen
vate() übergeben, die nicht Bestandteil
OSGi-API bleiben, wenngleich in die- kombiniert werden können, sodass de-
sem einfachen Beispiel natürlich spezi- eines Interfaces ist, sondern per Re ec- ren Einsatz keinerlei Einschränkung für
fischer Code für die Equinox Console tion gefunden wird und gemäß Spezi - die Flexibilität des Gesamtsystems dar-
kation public oder protected sein muss. In
enthalten ist. stellt. Im nächsten Artikel werden weite-
diesem Beispiel wird eine obligatorische re ausgewählte OSGi Standard Services
Services referenzieren Referenz auf mehrere ContactReposi- betrachtet und damit diese Einführung
tory Servcies verwendet. Das bedeutet, in die Grundlagen von OSGi abgeschlos-
Ihre volle Stärke entfalten Service
dass unsere Component erst dann ak- sen.
Components, wenn sie OSGi Services
referenzieren. Dabei gibt es zahlreiche
Optionen, z. B. Look-up- oder Event-
Strategie, statische oder dynamische Po-
licy etc. Für diese Details sei auf die Spe-
Heiko Seeberger ist als Technical Director für die Weigle Wilczek
zi kation verwiesen. In allen Fällen wird
GmbH tätig. Sein technischer Schwerpunkt liegt in der Entwicklung von
zum Referenzieren von OSGi Services
Unternehmensanwendungen mit OSGi, Eclipse RCP, Spring, AspectJ
das Element reference verwendet: und Java EE. Seine Erfahrungen aus über zehn Jahren IT-Beratung und
Softwareentwicklung fließen in die Eclipse Training Alliance ein. Zudem ist
<component ...> Heiko Seeberger aktiver Committer in Eclipse-Projekten, Autor zahlreicher
Fachartikel und Redner auf einschlägigen Konferenzen.
...
<reference name=quot;contactRepositoriesquot;
interface=quot;com.weiglewilczek...
ContactRepositoryquot;
Links & Literatur
cardinality=quot;1..nquot;/>
</component>
[1] OSGi-Spezifikation: www.osgi.org/Specifications/
[2] Spring Dynamic Modules: www.springsource.org/osgi/
[3] OSGi 4.2, Early Draft 2: www.osgi.org/download/osgi-4.2-early-draft2.pdf
Das Attribut interface spezifiziert das
[4] Apache Felix iPOJO: felix.apache.org/site/apache-felix-ipojo.html
Service Interface und mit dem optio-
[5] Guice Peaberry: code.google.com/p/peaberry/
nalen Attribut target könnte auch noch
[6] WeigleWilczek-Examples: www.weiglewilczek.com/examples/
ein Filter-Ausdruck angegeben wer-
[7] Extender Model: www.osgi.org/blog/2007/02/osgi-extender-model.html
den. Besondere Bedeutung genießt
[8] Buch „Equinox and OSGi”: equinoxosgi.blogspot.com
die Kardinalität, die mittels cardinality
18 javamagazin 3|2009 www.JAXenter.de