Your SlideShare is downloading. ×
JM 01/09 - OSGi in kleinen Dosen 2
JM 01/09 - OSGi in kleinen Dosen 2
JM 01/09 - OSGi in kleinen Dosen 2
JM 01/09 - OSGi in kleinen Dosen 2
JM 01/09 - OSGi in kleinen Dosen 2
JM 01/09 - OSGi in kleinen Dosen 2
JM 01/09 - OSGi in kleinen Dosen 2
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

JM 01/09 - OSGi in kleinen Dosen 2

560

Published on

Second article "OSGi in kleinen Dosen" in German Java Magazin 01/09.

Second article "OSGi in kleinen Dosen" in German Java Magazin 01/09.

Published in: Technology, News & Politics
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
560
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
37
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Core OSGi in kleinen Dosen – Teil 2 Immer in Bewegung – Bundles und Life Cycle Wir haben uns im vorigen Java Magazin mit den drei herausragenden Eigenschaften von OSGi beschäftigt: Modularisierung, Laufzeitdynamik und Serviceorientierung. Jetzt ist es an der Zeit, Modularisierung und Laufzeitdynamik und deren Zusammenspiel unter die Lupe zu nehmen. von Heiko Seeberger Cohesive: Die Elemente eines Moduls diese Form der Modularisierung zu fein- ozu brauchen wir eigentlich granular, um damit nicht-triviale So - Modularisierung bzw. ein Mo- haben einen starken logischen Bezug waresysteme adäquat zu modularisieren. dule System? Die Antwort ist zueinander. Loose Coupling: Module besitzen un- Mit anderen Worten: Java fehlt ein Mo- einfach: zur Reduktion von Komplexi- dulkonzept „oberhalb“ der Packages. tät. Module abstrahieren vom schwer tereinander eine geringe Kopplung. Public API: Ein Modul besitzt eine Bevor wir betrachten, wie OSGi überschaubaren Problem hin zu über- diese Lücke schließt, de nieren wir zu- sichtlichen Herausforderungen. Diese wohl de nierte ö entliche Schnittstel- nächst, was wir eigentlich genau unter können isoliert voneinander und mög- le und verbirgt die Interna der Imple- einem Modul verstehen wollen: licherweise auch arbeitsteilig in Angri mentierung. Dependencies: Die Abhängigkeiten ei- genommen werden und bieten die Mög- Self-contained: Ein Modul ist eine lichkeit der Wiederverwendung. nes Moduls sind wohl de niert. Deployment Format: Ein Modul „läu “ Was bedeutet das konkret für Java? Komposition aus kleineren Teilen, mit Als objektorientierte Programmierspra- Ausnahme von wohl de nierten Ab- in einem Container bzw. einer Lauf- che bietet Java ein Modulkonzept in Form hängigkeiten und kann nur als Ganzes zeitumgebung und wird dort in einem von Klassen und Packages. Allerdings ist verwendet werden. wohl de nierten Format installiert. Diese Eigenscha en führen nicht nur Artikelserie: OSGi in kleinen Dosen dazu, dass komplexe So waresysteme in überschaubare Module herunter- Teil 1: Erste Schritte mit OSGi gebrochen werden können, wodurch Teil 2: Immer in Bewegung – Bundles und Life Cycle zweifellos die Produktivität und Qua- Teil 3: Was wünschen Sie? – Services a là OSGi Teil 4: Alles XML oder was? – Services auf deklarative Weise lität in der Entwicklung gesteigert wer- Teil 5: Hier wird „Service“ groß geschrieben – Ausgewählte OSGi-Standardservices den kann. Sie fördern auch die Flexibili- tät und wirken sich dadurch positiv auf 26 javamagazin 1|2009 www.JAXenter.de
  • 2. OSGi in kleinen Dosen – Teil 2 Core lung dieses Artikels 1.2.1) in das Projekt- Time-to-Market und die Nutzung neuer verzeichnis und fügen die Datei bin/felix. Marktchancen aus. jar unter J B P |L zu Beispiel und Entwicklungs- den Libraries hinzu. Dann exportieren umgebung wir diese Library unter J B P |O E , sodass unsere Pro- Wir beginnen mit einem Beispiel, das jekte auf die darin enthaltene OSGi-API wir in den folgenden Teilen dieser Ar- Zugri haben. Anschließend erzeugen tikelserie sukzessive ausbauen werden. wir mittels R | R C Dabei handelt es sich um ein „universel- Abb. 1: Struktur eines Bundles … eine neue Run Configuration vom les Adressbuch“, das Kontakte aus belie- Typ Java Application, benennen Sie mit bigen Repositories gemeinsam verwal- Layer des OSGi Frameworks, der für org.apache.felix, wählen org.apache.felix. ten kann. Sämtlicher Sourcecode sowie dessen weitere Schichten die Grundlage Main als Main Class und setzen die fol- die speziell benötigte So ware be nden bildet. Darin wird das Bundle als OSGi- genden VM Arguments: -Dfelix.cache. sich auf der Begleit-CD und können Einheit für Modularisierung de niert. dir=.cache -Dfelix.cache.pro le=default. ebenfalls heruntergeladen werden [1]. Ein Bundle besteht aus Java-Klassen und Die Ausführung dieser Run Con gura- Eclipse PDE wurde als Entwick- Ressourcen wie Properties-Dateien und tion startet Apache Felix, wobei per De- lungswerkzeug für Bundles sowie Eclip- wird als JAR-Archiv im OSGi Frame- fault „Welcome to Felix.“ auf der Konsole se Equinox als OSGi-Implementierung work installiert (Abb. 1). ausgegeben wird. Die Begleit-CD enthält bereits vorgestellt. Wir werden weiterhin Darüber hinaus enthält ein Bun- unter anderem bereits dieses Projekt, so- Eclipse als Java-Entwicklungswerkzeug dle Metadaten, z.B. über die ö entliche dass wir dieses nur in unseren Workspace verwenden, aber diesmal mit Bnd [2] Schnittstelle oder die Abhängigkeiten, importieren müssen. und Apache Felix [3], und Alternativen die vom OSGi Framework verwendet für die Entwicklung bzw. die OSGi-Im- werden, um obige Eigenschaften si- Modularisierung à la OSGi plementierung aufzeigen. cherzustellen. Diese Metadaten wer- Bnd wird von Peter Kriens, Director den im Bundle Manifest (META-INF/ Die OSGi-Spezi kation adressiert das MANIFEST.MF) spezi ziert, das ohne- of Technology der OSGi Alliance [4], Thema Modularisierung im Module entwickelt und dient unter anderem zum Erstellen von OSGi Bundles. Mit- hilfe von bnd-Dateien, deren Syntax der des Bundle Manifests ähnelt, sowie der Analyse des Imports von Klassendatei- en erstellt Bnd aus Java-Projekten OSGi Bundles. Es kann per Kommandozeile als Ant-Task oder Eclipse-Plug-in ver- wendet werden. Wir werden es als Eclip- se Plug-in einsetzen, indem wir die aktu- elle produktive Version (zum Zeitpunkt der Erstellung dieses Artikels 0.0.249, als bnd-0.0.249.jar auf der Begleit-CD) in das Verzeichnis dropins unserer Eclipse- Installation kopieren und Eclipse an- schließend neu starten. Danach stellt das Bnd-Plug-in im Kontextmenü von bnd- Dateien im Package Explorer den Menü- Anzeige punkt M zur Verfügung. Um Apache Felix ebenfalls in Eclip- se zu integrieren, erstellen wir ein Java- Projekt org.apache.felix und stellen in den Project Properties (Kontextmenü P ) unter J B P | den Default output folder auf org. S apache.felix oder jeden beliebigen ande- ren Pfad außer org.apache.felix/bin. An- schließend entpacken wir den Download der aktuellen produktiven Version von Apache Felix (zum Zeitpunkt der Erstel- www.JAXenter.de
  • 3. Core OSGi in kleinen Dosen – Teil 2 hin Bestandteil der JAR-Spezifikation sorgt durch eine ausgeklügelte Classloa- Contact[] getAllContacts(); void remove(Contact contact); ist. Damit ist ein Bundle außerhalb des ding-Architektur dafür, dass Bundles } OSGi Frameworks ein ganz gewöhnli- self-contained sind und ihr lokaler Klas- ches JAR-Archiv und kann in jedem be- senpfad ausschließlich aus Elementen liebigen Java-System verwendet werden. innerhalb des Bundles besteht. Wird der Das Projekt für das Implementierungs- entsprechende Manifest Header Bundle- So sind z.B. sämtliche Libraries des Spring Bundle benötigt natürlich eine Abhängig- Classpath weggelassen, wird per Default Frameworks seit Version 2.5 OSGi Bund- keit zum Projekt für das Kern-API, sodass les, was jedoch bei „klassischer“ Verwen- das Wurzelverzeichnis des Bundles ver- wir diese über die Project Properties (J dung völlig transparent bleibt. wendet. Dies ist empfehlenswert, um B P |P ) hinzufügen. An- schließend erstellen wir ein InMemory- Jedes Bundle besitzt einen obligato- Bundles als „ganz normale“ JAR-Libra- ContactRepository, das ContactReposito- rischen symbolischen Namen, der mit- ries verwenden zu können. tels Bundle-SymbolicName spezifiziert ry implementiert, indem es alle Contacts Unser Beispiel, 1. Iteration in einer Collection verwaltet: wird. Wir empfehlen als Best Practice, bei der Benennung die Reverse-Do- Für unser Beispiel benötigen wir zwei public class InMemoryContactRepository implements main-Name-Konvention zu verwenden, Bundles: ContactRepository { um Namenskollisionen zu vermeiden. private final Collection<Contact> contacts; com.weiglewilczek.example.osgi.con- Dabei beginnt der symbolische Name .... tacts.core: Das Kern-API des Adress- mit dem umgekehrten Domain-Namen } und spezi ziert dann „Sinn und Zweck“, buchs. z.B. com.weiglewilczek.example.osgi.con- com.weiglewilczek.example.osgi.con- Die öffentliche Schnittstelle tacts.core. Gemeinsam mit der Version, tacts.core.inmemory: Eine nicht per- die mittels Bundle-Version gesetzt wird, sistente Implementierung des Kern- Wie oben erläutert, kann ein Bundle a identi ziert der symbolische Name ein APIs. priori nur auf die „eigenen“ Klassen zu- Bundle eindeutig innerhalb des OSGi greifen. Werden andere Klassen benö- Frameworks. Daraus wird unmittelbar Dazu erstellen wir je ein gleichnamiges tigt, so sind zweierlei Voraussetzungen ersichtlich, dass es möglich ist, das gleiche Java-Projekt mit Eclipse. Das Kern-API- zu erfüllen. Erstens müssen nutzende Bundle enthält im Package com.weigle- Bundle (mit demselben symbolischen Bundles explizit ihre Abhängigkeiten im wilczek.example.osgi.contacts.core die Namen) in mehreren unterschiedlichen Bundle Manifest deklarieren (Import) Versionen zu installieren. Zusammen mit Bean Contact mit Properties für Vor- und zweitens müssen Bundles, die ande- der weiter unten erläuterten Möglich- und Nachname, Anschri etc.: ren Bundles einen Teil ihrer Klassen als keit, bei Abhängigkeiten auf bestimmte ö entliche Schnittstelle zur Verfügung public class Contact { Versionen abzuzielen, bietet OSGi damit stellen, dies ebenfalls im Bundle Mani- private String firstName; einen Ausweg aus der leider allzu häu g fest deklarieren (Export). private String lastName; au retenden Java-Sackgasse, bestimmte Mit dem Manifest Header Export ... Libraries gleichzeitig in verschiedenen Package werden die Namen sämtlicher } Versionen zu benötigen. Packages spezi ziert, die zur ö entlichen Der lokale Klassenpfad eines Bund- Schnittstelle gehören. Dabei werden die les kann aus mehreren Verzeichnissen Package-Namen mit Kommata voneinan- Des Weiteren enthält es das Interface der getrennt: Export-Package: p1,p2. Es ist ContactRepository zur Verwaltung der innerhalb des Bundles bestehen und so- gar eingebettete JAR-Archive enthalten. möglich und empfehlenswert, pro Packa- Kontakte: Wichtig: Es ist nicht möglich, Klassen ge eine Versionsnummer anzugeben, was public interface ContactRepository { durch das version-Attribut erzielt werden oder JAR-Archive außerhalb des Bund- void add(Contact contact); kann: Export-Package: p;version=quot;1.0.0quot;. les zu verwenden. Das OSGi Framework Um Namenskollisionen bei den exportier- Manifest Header Bedeutung ten Packages zu vermeiden, empfehlen wir für diese ebenfalls eine Namenskonventi- Bundle-SymbolicName Eindeutiger Name innerhalb des OSGi Frameworks. Obligatorisch! on: Das oberste Package sollte den symbo- Empfehlung: Reverse Domain Name Convention lischen Namen des Bundles tragen, z.B. Bundle-Version Dient zusammen mit dem symbolischen Namen als eindeutige ID. Format: „major.minor.micro.qualifier“, z.B. “1.2.3.test”. Default “0.0.0” com.weiglewilczek.example.osgi.contacts. Bundle-Classpath Listet alle Verzeichnisse und/oder eingebettete JARs auf, die zum core.inmemory. Um darüber hinaus auf lokalen Klassenpfad des Bundles gehören. Default „.“ den ersten Blick erkennen zu können, was Bundle-Activator Voll-qualifizierter Name eines BundleActivators, dessen Methoden exportiert wurde und was nicht, bietet sich beim Starten und Stoppen des Bundles aufgerufen werden an, nicht-exportierte Packages mit einem Import-Package Listet die Abhängigkeiten in Form von Package-Namen auf internal im Namen zu versehen, z.B. com. Export-Package Listet die öffentliche Schnittstelle in Form von Package-Namen auf weiglewilczek.example.osgi.contacts.core. inmemory.internal. Bei der Verwendung Tabelle 1: Wichtige Manifest Header 28 javamagazin 1|2009 www.JAXenter.de
  • 4. OSGi in kleinen Dosen – Teil 2 Core nifest Header Import-Package werden von Eclipse PDE bekommen wir dadurch gigkeiten, z.B. optionale Imports, spezi- sogar den Vorteil, Compiler-Warnungen die Namen von Packages spezi ziert, die sche Attribute etc. Für diese sei auf die für Discouraged Access zu erhalten, wenn vom Bundle benötigt werden. Alterna- hervorragende OSGi-Spezi kation [5] tiv kann der Manifest Header Require- wir solche Packages importieren. verwiesen. Bundle verwendet werden, mit dem Unser Beispiel, 2. Iteration Unser Beispiel, 3. Iteration benötigte Bundles spezi ziert werden, von denen alle exportierten Packages Das Kern-API-Bundle muss natürlich das Um das Implementierungs-Bundle zu Package com.weiglewilczek.example.osgi. genutzt werden können. Allerdings erstellen, benötigen wir zunächst die fol- hat Require-Bundle mehrere Nachteile, contacts.core als ö entliche Schnittstelle gende bnd-Datei: insbesondere wird das Prinzip der lo- deklarieren. Wie oben erläutert, erstellen # com.weiglewilczek.example.osgi.contacts.core. sen Kopplung verletzt. Beispielsweise wir das Bundle Manifest nicht manuell, inmemory.bnd wäre es in den meisten Fällen unsinnig, sondern verwenden Bnd als Eclipse- Bundle-Version: 1.0.0 wenn sich ein Bundle ganz konkret von Plug-in, um aus Java-Projekten Bundles Private-Package: com.weiglewilczek.example.osgi. einem MySql-Bundle abhängig macht, einschließlich Bundle Manifest zu erzeu- contacts.core.inmemory.internal nur weil es das JDBC API benötigt. Mit gen. Bnd ermittelt bestimmte Informati- Import-Package hingegen haben wir die onen für das Bundle Manifest, z.B. die zu Möglichkeit, die Abhängigkeiten auch importierenden Packages, durch Analyse Da wir hier kein Package exportieren, müssen wir Bnd mittels Private-Package durch andere Bundles zu erfüllen, z.B. der Klassendateien. Allerdings benötigt mit einem Oracle-, einem Derby- oder Bnd auch eine Reihe von Metadaten in mitteilen, welche Packages zum Bundle Form einer bnd-Datei, die dem Bundle einem anderen Bundle, das das JDBC gehören. Alternativ zur expliziten Anga- API exportiert. Wir werden daher im Manifest sehr ähnelt, aber hinsichtlich be von Namen könnte auch die Wildcard Folgenden ausschließlich Import-Pa- der Syntax leichter handzuhaben ist. Dar- „*“ verwendet werden. Um die zu im- ckage verwenden. Analog zu Export-Pa- über hinaus gibt es zahlreiche Hilfsmittel, portierenden Packages müssen wir uns ckage werden die Namen der benötigten z.B. die Verwendung von Wildcards. Für keine Gedanken machen, weil Bnd diese Packages kommasepariert aufgelistet: das Kern-API-Bundle benötigen wir die anhand der Klassendateien analysiert. Import-Package: p1,p2,p3. folgende bnd-Datei, die wir im Wurzel- Das resultierende Bundle Manifest sieht Mit dem version-Attribut werden verzeichnis des Projekts ablegen: folgendermaßen aus. Versionsintervalle spezifiziert. Dabei # com.weiglewilczek.example.osgi.contacts.core.bnd Manifest-Version: 1.0 stehen eckige Klammern für geschlos- Bundle-Version: 1.0.0 Bundle-ManifestVersion: 2 sene und runde Klammern für offene Export-Package: com.weiglewilczek.example.osgi. Bundle-SymbolicName: com.weiglewilczek.example. Intervalle, d.h. im ersten Fall gehört die contacts.core;version=1.0.0 osgi.contacts.core.inme betro ene Versionsnummer noch zum mory Intervall und im zweiten Fall nicht: Bundle-Version: 1.0.0 Über M im Kontextme- Import-Package: com.weiglewilczek.example.osgi. Import-Package: p;version=quot;[1.0.0,2.0.0)quot; nü der bnd-Datei im Package Explorer contacts.core,org.osgi. framework;version=quot;1.4quot; können wir nun das Kern-API-Bundle erstellen. Es wird unter dem Namen der bnd-Datei ebenfalls im Wurzelverzeich- Es ist auch möglich, nur eine Versions- Bundle Life Cycle nis des Projekts abgelegt und enthält das nummer anzugeben, was einem nach folgende Bundle Manifest: oben offenen Intervall entspricht, so- Das OSGi Framework stellt die Lauf- dass alle Versionsnummern größer oder zeitumgebung für Bundles dar: Bundles Manifest-Version: 1.0 gleich sind: können installiert, aktualisiert und wie- Bundle-ManifestVersion: 2 der deinstalliert werden. Zudem kön- Bundle-SymbolicName: com.weiglewilczek.example. Import-Package: p;version=quot;1.0.0quot; nen sie gestartet und wieder gestoppt osgi.contacts.core werden. Abbildung 2 zeigt die Zustände, Bundle-Version: 1.0.0 die ein Bundle während seines Lebens- Wozu dienen nun die Versionsnum- Export-Package: com.weiglewilczek.example.osgi. zyklus innerhalb des OSGi Frameworks mern? Das OSGi Framework versucht, contacts.core;version=quot; einnehmen kann. zu einem bestimmten Zeitpunkt im Le- 1.0.0quot; Import-Package: com.weiglewilczek.example.osgi. Bevor wir auf die Frage eingehen, benszyklus von Bundles deren Abhän- contacts.core;version=quot; wie der Lebenszyklus gesteuert wer- gigkeiten aufzulösen, indem zu jedem 1.0.0quot; den kann, widmen wir uns der Bedeu- Package-Import ein passender Packa- tung der einzelnen Zustände und deren ge-Export gesucht wird. Dabei werden Übergängen. Durch das Installieren natürlich die Versionsnummern be- Abhängigkeiten eines Bundles wird dieses innerhalb des rücksichtigt, sofern sie spezi ziert wur- OSGi Frameworks persistiert, d.h. in den. Es gibt noch einige weitere Details Für die Deklaration der Abhängigkeiten einem lokalen Bundle Cache abgelegt. hinsichtlich der Au ösung von Abhän- gibt es zwei Möglichkeiten. Mit dem Ma- javamagazin 1|2009 29 www.JAXenter.de
  • 5. Core OSGi in kleinen Dosen – Teil 2 setzt. Wenn ein Activator spezi ziert ist, falls auch dies ohne eindeutiges Ergebnis wird dessen start()-Methode aufgerufen bleibt, wird das Bundle mit der kleinsten und wenn diese erfolgreich zurückkehrt, ID ausgewählt. Auf diese Weise kann wird das Bundle auf ACTIVE gesetzt, vom OSGi Framework immer eine ein- andernfalls wieder auf RESOLVED. deutige Zuordnung zwischen einem Analog verhält es sich mit dem Stoppen. importierenden und einem exportie- Um die Startup-Performance zu ver- renden Bundle getro en werden: Dies bessern, kann ein Bundle mit dem Ma- wird Wiring genannt. Es ist jedoch emp- nifest Header Bundle-ActivationPolicy fehlenswert, mittels Versionsnummern Abb. 2: Zustände innerhalb des Bundle Life Cycle spezi zieren, dass die Aktivierung lazy und gegebenenfalls weiterer Attribute erfolgen soll. Dann wird der Aufruf der möglichst genaue Vorgaben zu tre en, Die Voraussetzung dafür ist, dass es ein start()-Methode solange verzögert und um „selbst die Kontrolle zu behalten“. gültiges Format und gültige Metadaten Wichtig: Bundles im Zustand RESOL- das Bundle verbleibt solange im Zustand enthält. Bei der Installation wird dem STARTING, bis zum ersten Mal eine VED können bereits verwendet werden, Bundle eine eindeutige ID vom Typ long Klasse aus dem Bundle geladen wird. indem andere Bundles ihr API benutzen. zugewiesen und das Bundle wird in den Zustand INSTALLED versetzt. Wenn ein Bundle deinstalliert Es ist nicht erforderlich, jedes Bundle zu wird, geht es zunächst in den Zustand starten, denn dies dient einem besonderen Dem OSGi Framework steht o en, UNINSTALLED über. Sofern es keine Zweck: Mit dem Manifest Header Bundle- ob es sofort nach der Installation eines Activator wird der voll quali zierte Name Packages exportiert, die im Wiring ver- Bundles oder erst später versucht, des- wendet wurden, wird es sofort aus dem einer Klasse angegeben, die das Interface sen Abhängigkeiten aufzulösen. Eclipse BundleActivator implementiert: persistenten Speicher des OSGi Frame- Equinox und Apache Felix z.B. verhalten works gelöscht. Andernfalls bleiben die sich hier lazy, um Ressourcen zu scho- public interface BundleActivator { Package-Exports bis zu einem Neustart nen. Beim so genannten Resolving ver- void start(BundleContext context); des OSGi Frameworks erhalten, sodass sucht das OSGi Framework für jedes zu void stop(BundleContext context); durch das Deinstallieren eines Bund- importierende Package ein passendes } les nicht automatisch alle abhängigen exportiertes Package zu finden. Nur Bundles funktionsunfähig werden. wenn dies für alle nicht optionalen Pa- Beim Aktualisieren wird ein Bundle ckage-Imports gelingt, wird das Bundle Wenn ein Bundle einen Activator spe- in den Zustand RESOLVED versetzt, erneut eingelesen und persistiert. Dabei zifiziert, wird beim Starten vom OSGi andernfalls bleibt es INSTALLED und bleibt die Bundle ID erhalten, wohinge- Framework eine Instanz erzeugt und des- sen start()-Methode und beim Stoppen gen durch Deinstallieren und anschlie- kann nicht verwendet werden, bis mög- dessen stop()-Methode aufgerufen. Da ßendes erneutes Installieren eine neue licherweise zu einem späteren Zeitpunkt Bundle ID vergeben wird. Das OSGi alle Abhängigkeiten aufgelöst werden diese Aufrufe synchron vom Framework Framework versetzt das Bundle beim können. read erfolgen, ist es wichtig, dass sie so Aktualisieren wieder in den Ausgangs- Falls mehrere passende exportier- schnell wie möglich zurückkehren, um die zustand, sodass z.B. ein ursprünglich te Packages vorliegen, wird das mit der Ausführung des Systems nicht zu blockie- gestartetes Bundle zunächst gestoppt, höchsten Version verwendet. Falls im- ren. Lang laufende Vorgänge sollten daher dann erneut eingelesen und aufgelöst mer noch kein eindeutiger Bezug herge- in eigenen reads ausgeführt werden. und danach wieder gestartet wird. Auf stellt werden kann, wird die Version der Beim Starten wird das Bundle zu- nächst in den Zustand STARTING ver- diese Weise kann ein So waresystem im exportierenden Bundles verglichen und laufenden Betrieb feingranular – näm- lich auf Ebene von Bundles – aktualisiert Befehl Bedeutung werden. Mit anderen Worten bietet OSGi Ps Listet die installierten Bundles mit Basisinformationen auf ein Hot Deployment auf Modulebene. install <url> Installiert das Bundle von der angegebenen URL Life Cycle Management update <id> Aktualisiert das angegebene Bundle Wie kann nun der Lebenszyklus von resolve <id> Löst das angegebene Bundle auf Bundles gesteuert werden? Dazu bietet refresh <id> Führt ein Package Refresh für das angegebene Bundle das OSGi Framework ein schlankes API start <id> Startet das angegebene Bundle an, das im Wesentlichen aus den folgen- den drei Klassen besteht: BundleContext, stop <id> Stoppt das angegebene Bundle Bundle, BundleListener. uninstall <id> Deinstalliert das angegebene Bundle Der BundleContext stellt die einzige Shutdown Beendet das OSGi Framework Schnittstelle zur Interaktion mit dem Help Listet die verfügbaren Befehle mit Erläuterungen auf OSGi Framework dar. Um eine Refe- renz auf den BundleContext zu erhalten, Tabelle 2: Wichtige Befehle der Apache Felix Text Shell 30 javamagazin 1|2009 www.JAXenter.de
  • 6. OSGi in kleinen Dosen – Teil 2 Core Sowohl Eclipse Equinox als auch Apache muss ein Activator verwendet werden, nen Activator (Listing 1) hinzu, der in der in dessen start()- und stop()-Methoden start()- und stop()-Methode Tracing-Aus- Felix enthalten diesen Service. der BundleContext für das jeweilige gaben nach System.out schreibt. Weiter er- Für das Life Cycle Management bieten die OSGi-Implementierungen in der Re- Bundle übergeben wird. Mit dessen installBundle()-Methoden kann ein gel so genannte Management Agents als Bestandteil der Implementierung oder als Bundle im OSGi Framework installiert Listing 1 separate Bundles an. Eclipse Equinox ent- werden. Als Rückgabe erhalten wir eine public class Activator implements BundleActivator { Referenz vom Typ Bundle, mit der wir hält die Equinox Console und Apache Fe- lix bringt per Default die Bundles Shell und den Lebenszyklus des Bundles steuern public void start(final BundleContext context) { Shell Text UI mit. Beides sind textbasierte können, z.B. mit den Methoden start(), System.out.println(MessageFormat.format(”[{0}] starting ...“, context stop(), update() und uninstall(). Um Management Agents mit sehr ähnlichen .getBundle().getSymbolicName())); Funktionen. Darüber hinaus gibt es weite- den Lebenszyklus beliebiger Bundles final ContactRepository repository = createRepository(); re Management Agents auf Basis von Swing zu verfolgen und gegebenenfalls darauf for (final Contact contact : repository.getAllContacts()) { zu reagieren, können BundleListener oder webbasierte Agents. Letztendlich System.out.println(contact); } über den BundleContext beim OSGi kann jedes So waresystem auf Basis von } OSGi einen eigenen Management Agent Framework registriert werden. An die- se werden BundleEvents versendet, die in Form eines oder mehreren Bundles public void stop(final BundleContext context) { implementieren. Da wir für unser Beispiel Informationen über die Änderung im System.out.println(MessageFormat.format(”[{0}] stopping ...“, Apache Felix verwenden, stellen wir in Ta- Lebenszyklus enthalten. context .getBundle().getSymbolicName())); belle 2 die wichtigsten Befehle für dessen Wichtig: Es gibt kein API im OSGi } Text Shell vor. Framework zur Steuerung des Resol- ving. Dazu gibt es einen optionalen private ContactRepository createRepository() { Unser Beispiel, 4. Iteration Standardservice, den Package Admin ... } Service, der Operationen wie refreshPa- Damit unser Beispiel bereits in diesem ckages() und resolveBundles() anbietet. Stadium aktiv werden kann, fügen wir ei- Anzeige javamagazin 1|2009 31 www.JAXenter.de
  • 7. Core OSGi in kleinen Dosen – Teil 2 Abschließend zeigen wir noch eines contacts.core.inmemor y.internal.Activator der OSGi-Highlights schlechthin: Wir aktualisieren das Implementierungs- Bundle im laufenden Betrieb. Dazu Nun ist es an der Zeit, unsere beiden passen wir dessen Activator an, sodass Bundles im OSGi Framework zu instal- er eine andere Menge von Kontakten lieren, zu starten, zu aktualisieren etc. Abb. 3: Installierte Bundles auflisten enthält, lassen Bnd das Bundle erneut er- Dazu starten wir zunächst Apache Felix mittels der Run Con guration org.apa- stellen und führen dann in der Konsole das Kommando update aus. che.felix aus dem gleichnamigen Projekt. In der Konsole geben wir ps ein, um die Wie Abbildung 7 zeigt, wird das Bundle zunächst gestoppt, dann transpa- aktuell installierten Bundles aufzulisten rent aktualisiert und anschließend wie- (Abb. 3). Abb. 4: Bundles installieren der gestartet. Und tatsächlich nden wir Anschließend verwenden wir das Kommando install, um die Bundles zu einen neuen Kontakt in der Ausgabe. installieren und listen danach wieder die Schlussbemerkung und Ausblick installierten Bundles auf (Abb. 4). Unsere beiden neu installierten Wir haben die wichtigsten Details des Abb. 5: Bundles auflösen Bundles be nden sich nun im Zustand Module und Life Cycle Layer kennen- INSTALLED. Um sie aufzulösen, geben gelernt: Bundles sind JAR-Archive mit wir das Kommando resolve mit der ID zusätzlichen Metadaten. Diese werden Abb. 6: Bundles starten des Implementierungs-Bundles ein. Da- im Bundle Manifest spezi ziert und de- durch wird auch das Kern-API-Bundle klarieren u.a. die ö entliche Schnittstelle aufgelöst, um die Abhängigkeiten er- und die Abhängigkeiten eines Bundles. füllen zu können, d.h. unsere beiden Das OSGi Framework bietet Bundles ei- Abb. 7: Bundles aktualisieren Bundles be nden sich nun im Zustand ne Laufzeitumgebung, wo diese u.a. ins- RESOLVED (Abb. 5). talliert, gestartet und aktualisiert werden Nun starten wir das Implementie- können. Dazu dient ein Management zeugen wir beim Starten eine Instanz des InMemoryContactRepository und geben rungs-Bundle mit dem Kommando Agent der OSGi-Implementierung, z.B. start. Dadurch wird der Activator ins- dessen Kontakte nach System.out aus. eine textbasierte Konsole. Im nächsten tanziiert und dessen start()-Methode Die zugehörige bnd-Datei muss nun Teil dieser Artikelserie werden wir die noch um die Bundle-Activator-Direktive ausgeführt, sodass die Tracing-Ausgabe dritte wesentliche Eigenscha von OSGi sowie die Liste der Kontakte ausgegeben unter die Lupe nehmen: Das OSGi Ser- erweitert werden, die – abgesehen von werden (Abb. 6). vice Model. der Umformatierung in das spezielle Manifest-Format – in das Bundle Mani- fest übernommen wird: # com.weiglewilczek.example.osgi.contacts.core. inmemory.bnd Heiko Seeberger ist als Technical Director für die Weigle Wilczek GmbH Bundle-Version: 1.0.0 tätig. Sein technischer Schwerpunkt liegt in der Entwicklung von Unterneh- Private-Package: com.weiglewilczek.example.osgi. mensanwendungen mit OSGi, Eclipse RCP, Spring, AspectJ und Java EE. contacts.core.inmemory.internal Seine Erfahrungen aus über zehn Jahren IT-Beratung und Softwareentwick- Bundle-Activator: lung fließen in die Eclipse Training Alliance ein. Zudem ist Heiko Seeberger com.weiglewilczek.example.osgi.contacts.core. aktiver Committer in Eclipse-Projekten, Autor zahlreicher Fachartikel und inmemory.internal.Activator Redner auf einschlägigen Konferenzen. Das resultierende Bundle Manifest sieht nun folgendermaßen aus: Links & Literatur Manifest-Version: 1.0 [1] WeigleWilczek-Examples: www.weiglewilczek.com/examples/ Bundle-ManifestVersion: 2 Bundle-SymbolicName: com.weiglewilczek.example. [2] Bnd: www.aqute.biz/Code/Bnd osgi.contacts.core.inme [3] Apache Felix: felix.apache.org mory [3] OSGi Alliance: www.osgi.org Bundle-Version: 1.0.0 [3] Manifest Format: java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html Import-Package: com.weiglewilczek.example.osgi. [3] OSGi-Spezifikation: www.osgi.org/Specifications/ contacts.core,org.osgi. [3] Seeberger, OSGi in kleinen Dosen, Teil, Java Magazin 12.08 framework;version=quot;1.4quot; Bundle-Activator: com.weiglewilczek.example.osgi. 32 javamagazin 1|2009 www.JAXenter.de

×