SlideShare a Scribd company logo
1 of 7
Download to read offline
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
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
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
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
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
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
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

More Related Content

Similar to JM 01/09 - OSGi in kleinen Dosen 2

Eclipse Magazin 12 - Security does matter
Eclipse Magazin 12 - Security does matterEclipse Magazin 12 - Security does matter
Eclipse Magazin 12 - Security does matterHeiko Seeberger
 
Javamagazin 1.2016 jdk9_ea_b83_jigsaw
Javamagazin 1.2016 jdk9_ea_b83_jigsawJavamagazin 1.2016 jdk9_ea_b83_jigsaw
Javamagazin 1.2016 jdk9_ea_b83_jigsawWolfgang Weigend
 
Morphia, Spring Data & Co
Morphia, Spring Data & CoMorphia, Spring Data & Co
Morphia, Spring Data & CoTobias Trelle
 
DHI-WASY Aktuell 04/2011
DHI-WASY Aktuell 04/2011DHI-WASY Aktuell 04/2011
DHI-WASY Aktuell 04/2011DHI-WASY GmbH
 
OSGi und Spring MVC - inovex BrownBag
OSGi und Spring MVC - inovex BrownBag OSGi und Spring MVC - inovex BrownBag
OSGi und Spring MVC - inovex BrownBag inovex GmbH
 
Von Maven zu Gradle in 45 Minuten
Von Maven zu Gradle in 45 MinutenVon Maven zu Gradle in 45 Minuten
Von Maven zu Gradle in 45 MinutenQAware GmbH
 
Server Revolutions- Der Spring Source DM Server
Server Revolutions- Der Spring Source DM ServerServer Revolutions- Der Spring Source DM Server
Server Revolutions- Der Spring Source DM ServerSandro Sonntag
 
Jalimo Slides Linuxtag2007
Jalimo Slides Linuxtag2007Jalimo Slides Linuxtag2007
Jalimo Slides Linuxtag2007smancke
 
JSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederJSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederChristoph Pickl
 
iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...
iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...
iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...Lukas Eder
 
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7hwilming
 
Article - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der EntwicklerArticle - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der EntwicklerWolfgang Weigend
 
Monitoring und Profiling von Java-Anwendungen
Monitoring und Profiling von Java-AnwendungenMonitoring und Profiling von Java-Anwendungen
Monitoring und Profiling von Java-Anwendungengedoplan
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6GFU Cyrus AG
 

Similar to JM 01/09 - OSGi in kleinen Dosen 2 (20)

OSGi: Grundlagen und Konzepte
OSGi: Grundlagen und KonzepteOSGi: Grundlagen und Konzepte
OSGi: Grundlagen und Konzepte
 
Eclipse Magazin 12 - Security does matter
Eclipse Magazin 12 - Security does matterEclipse Magazin 12 - Security does matter
Eclipse Magazin 12 - Security does matter
 
Javamagazin 1.2016 jdk9_ea_b83_jigsaw
Javamagazin 1.2016 jdk9_ea_b83_jigsawJavamagazin 1.2016 jdk9_ea_b83_jigsaw
Javamagazin 1.2016 jdk9_ea_b83_jigsaw
 
JM 08/09 - ScalaModules
JM 08/09 - ScalaModulesJM 08/09 - ScalaModules
JM 08/09 - ScalaModules
 
CDI
CDICDI
CDI
 
Morphia, Spring Data & Co
Morphia, Spring Data & CoMorphia, Spring Data & Co
Morphia, Spring Data & Co
 
DHI-WASY Aktuell 04/2011
DHI-WASY Aktuell 04/2011DHI-WASY Aktuell 04/2011
DHI-WASY Aktuell 04/2011
 
OSGi und Spring MVC - inovex BrownBag
OSGi und Spring MVC - inovex BrownBag OSGi und Spring MVC - inovex BrownBag
OSGi und Spring MVC - inovex BrownBag
 
Modularisierung - was soll das?
Modularisierung - was soll das?Modularisierung - was soll das?
Modularisierung - was soll das?
 
Von Maven zu Gradle in 45 Minuten
Von Maven zu Gradle in 45 MinutenVon Maven zu Gradle in 45 Minuten
Von Maven zu Gradle in 45 Minuten
 
Server Revolutions- Der Spring Source DM Server
Server Revolutions- Der Spring Source DM ServerServer Revolutions- Der Spring Source DM Server
Server Revolutions- Der Spring Source DM Server
 
Jalimo Slides Linuxtag2007
Jalimo Slides Linuxtag2007Jalimo Slides Linuxtag2007
Jalimo Slides Linuxtag2007
 
JSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederJSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael Greifeneder
 
JUGM 07 - AspectJ
JUGM 07 - AspectJJUGM 07 - AspectJ
JUGM 07 - AspectJ
 
iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...
iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...
iJUG Java Aktuell [Februar 2015] Lukas Eder - jOOQ - ein alternativer Weg mit...
 
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
 
Article - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der EntwicklerArticle - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der Entwickler
 
Monitoring und Profiling von Java-Anwendungen
Monitoring und Profiling von Java-AnwendungenMonitoring und Profiling von Java-Anwendungen
Monitoring und Profiling von Java-Anwendungen
 
JavaMagazin - AngularJS
JavaMagazin - AngularJSJavaMagazin - AngularJS
JavaMagazin - AngularJS
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6
 

More from Heiko Seeberger

Scaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of ScalazScaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of ScalazHeiko Seeberger
 
RheinJUG 2010 - Sprechen Sie Scala?
RheinJUG 2010 - Sprechen Sie Scala?RheinJUG 2010 - Sprechen Sie Scala?
RheinJUG 2010 - Sprechen Sie Scala?Heiko Seeberger
 
Objektforum 2010 - Sprechen Sie Scala?
Objektforum 2010 - Sprechen Sie Scala?Objektforum 2010 - Sprechen Sie Scala?
Objektforum 2010 - Sprechen Sie Scala?Heiko Seeberger
 
JM 08/09 - Beginning Scala Review
JM 08/09 - Beginning Scala ReviewJM 08/09 - Beginning Scala Review
JM 08/09 - Beginning Scala ReviewHeiko Seeberger
 
OSGi DevCon Europe 09 - OSGi on Scala
OSGi DevCon Europe 09 - OSGi on ScalaOSGi DevCon Europe 09 - OSGi on Scala
OSGi DevCon Europe 09 - OSGi on ScalaHeiko Seeberger
 
JAX 09 - OSGi Service Components Models
JAX 09 - OSGi Service Components ModelsJAX 09 - OSGi Service Components Models
JAX 09 - OSGi Service Components ModelsHeiko Seeberger
 
Eclipse Magazin 12 - Design by Contract
Eclipse Magazin 12 - Design by ContractEclipse Magazin 12 - Design by Contract
Eclipse Magazin 12 - Design by ContractHeiko Seeberger
 
EclipseCon 08 - Agile RCP
EclipseCon 08 - Agile RCPEclipseCon 08 - Agile RCP
EclipseCon 08 - Agile RCPHeiko Seeberger
 
W-JAX 07 - AOP im Einsatz mit OSGi und RCP
W-JAX 07 - AOP im Einsatz mit OSGi und RCPW-JAX 07 - AOP im Einsatz mit OSGi und RCP
W-JAX 07 - AOP im Einsatz mit OSGi und RCPHeiko Seeberger
 
W-JAX 08 - Declarative Services versus Spring Dynamic Modules
W-JAX 08 - Declarative Services versus Spring Dynamic ModulesW-JAX 08 - Declarative Services versus Spring Dynamic Modules
W-JAX 08 - Declarative Services versus Spring Dynamic ModulesHeiko Seeberger
 
JAX 08 - Experiences using Equinox Aspects in a real-world Project
JAX 08 - Experiences using Equinox Aspects in a real-world ProjectJAX 08 - Experiences using Equinox Aspects in a real-world Project
JAX 08 - Experiences using Equinox Aspects in a real-world ProjectHeiko Seeberger
 
Eclipse Summit Europe 08 - Aspect Weaving for OSGi
Eclipse Summit Europe 08 - Aspect Weaving for OSGiEclipse Summit Europe 08 - Aspect Weaving for OSGi
Eclipse Summit Europe 08 - Aspect Weaving for OSGiHeiko Seeberger
 

More from Heiko Seeberger (20)

Scaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of ScalazScaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of Scalaz
 
Java Magazin - Lift
Java Magazin - LiftJava Magazin - Lift
Java Magazin - Lift
 
JavaSPEKTRUM - Scala 3
JavaSPEKTRUM - Scala 3JavaSPEKTRUM - Scala 3
JavaSPEKTRUM - Scala 3
 
JavaSPEKTRUM - Scala 2
JavaSPEKTRUM - Scala 2JavaSPEKTRUM - Scala 2
JavaSPEKTRUM - Scala 2
 
JavaSPEKTRUM - Scala 1
JavaSPEKTRUM - Scala 1JavaSPEKTRUM - Scala 1
JavaSPEKTRUM - Scala 1
 
RheinJUG 2010 - Sprechen Sie Scala?
RheinJUG 2010 - Sprechen Sie Scala?RheinJUG 2010 - Sprechen Sie Scala?
RheinJUG 2010 - Sprechen Sie Scala?
 
Objektforum 2010 - Sprechen Sie Scala?
Objektforum 2010 - Sprechen Sie Scala?Objektforum 2010 - Sprechen Sie Scala?
Objektforum 2010 - Sprechen Sie Scala?
 
W-JAX 09 - ScalaModules
W-JAX 09 - ScalaModulesW-JAX 09 - ScalaModules
W-JAX 09 - ScalaModules
 
W-JAX 09 - Lift
W-JAX 09 - LiftW-JAX 09 - Lift
W-JAX 09 - Lift
 
JM 08/09 - Beginning Scala Review
JM 08/09 - Beginning Scala ReviewJM 08/09 - Beginning Scala Review
JM 08/09 - Beginning Scala Review
 
OSGi DevCon Europe 09 - OSGi on Scala
OSGi DevCon Europe 09 - OSGi on ScalaOSGi DevCon Europe 09 - OSGi on Scala
OSGi DevCon Europe 09 - OSGi on Scala
 
JAX 09 - OSGi on Scala
JAX 09 - OSGi on ScalaJAX 09 - OSGi on Scala
JAX 09 - OSGi on Scala
 
JAX 09 - OSGi Service Components Models
JAX 09 - OSGi Service Components ModelsJAX 09 - OSGi Service Components Models
JAX 09 - OSGi Service Components Models
 
JAX 08 - Agile RCP
JAX 08 - Agile RCPJAX 08 - Agile RCP
JAX 08 - Agile RCP
 
Eclipse Magazin 12 - Design by Contract
Eclipse Magazin 12 - Design by ContractEclipse Magazin 12 - Design by Contract
Eclipse Magazin 12 - Design by Contract
 
EclipseCon 08 - Agile RCP
EclipseCon 08 - Agile RCPEclipseCon 08 - Agile RCP
EclipseCon 08 - Agile RCP
 
W-JAX 07 - AOP im Einsatz mit OSGi und RCP
W-JAX 07 - AOP im Einsatz mit OSGi und RCPW-JAX 07 - AOP im Einsatz mit OSGi und RCP
W-JAX 07 - AOP im Einsatz mit OSGi und RCP
 
W-JAX 08 - Declarative Services versus Spring Dynamic Modules
W-JAX 08 - Declarative Services versus Spring Dynamic ModulesW-JAX 08 - Declarative Services versus Spring Dynamic Modules
W-JAX 08 - Declarative Services versus Spring Dynamic Modules
 
JAX 08 - Experiences using Equinox Aspects in a real-world Project
JAX 08 - Experiences using Equinox Aspects in a real-world ProjectJAX 08 - Experiences using Equinox Aspects in a real-world Project
JAX 08 - Experiences using Equinox Aspects in a real-world Project
 
Eclipse Summit Europe 08 - Aspect Weaving for OSGi
Eclipse Summit Europe 08 - Aspect Weaving for OSGiEclipse Summit Europe 08 - Aspect Weaving for OSGi
Eclipse Summit Europe 08 - Aspect Weaving for OSGi
 

JM 01/09 - OSGi in kleinen Dosen 2

  • 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