Applikationsdesign im Zeitalter von OSGi - JAXenter

Applikationsdesign im Zeitalter von OSGi

Das Extension-Modell in Eclipse

Eclipse setzt mit seinen Extension Points und Extensions auf die zweite Strategie; ein Bundle (hier Plug-in) definiert seine Erweiterungspunkte in einer speziellen XML-Datei, die dem Plug-in beiliegt (plugin.xml). Plug-ins, die Implementierungen dieser Erweiterungspunkte (Extensions) beisteuern, deklarieren sie ebenfalls in dieser Datei. Bei Installation eines Plug-ins werden diese Metadaten ausgewertet und in einer speziellen Komponente registriert (Extension Registry), die Abfragen nach Extensions zulässt (ähnlich zur Service Registry). Das Plug-in braucht dazu nicht gestartet werden. Eclipse nutzt diesen Mechanismus beispielsweise, um Aktionen in Toolbars anbieten zu können, ohne dass die relevanten Klassen geladen und Objekte erzeugt werden müssen. Das geschieht dann erst bei Verwendung der Aktion; ggf. also nie. Dieser ressourcenschonende Ansatz erlaubt Eclipse-Installationen mit einer sehr großen Anzahl von Plug-ins und trotzdem akzeptabler Startzeit.

Die Extension Registry von Eclipse ist Bestandteil von Equinox, und auch außerhalb von Eclipse für eigene Applikationen nutzbar. Diese können auch in anderen OSGi-Frameworks laufen, wenn die Extension Registry dort installiert ist. Entscheidet man sich dafür, muss man allerdings eine weitere externe Abhängigkeit in Kauf nehmen.

Abhängigkeiten planen

Schlechte Entwürfe zeichnen sich oftmals durch die ungeschickte Wahl von Abhängigkeiten aus. Diese können die Wiederverwendung einzelner Module behindern und das Warten und Testen der Software erschweren. Daher ist das Planen von Abhängigkeiten eine zentrale Aufgabe im Design.

Die Verwendung von Java allein begünstigt die Erstellung monolithischer Systeme, da echte Modularisierungsmittel oberhalb von Paketen und Mechanismen zum Abhängigkeitsmanagement fehlen. Natürlich lassen sich mit Java trotzdem gute Entwürfe realisieren, wenn allgemeine Designprinzipien wie zum Beispiel das Open Closed Principle oder Dependency Injection berücksichtigt werden, die Rahmenbedingungen klar sind und bewusstes Abhängigkeitsmanagement betrieben wird. An dieser Stelle unterstützt Sie OSGi in verschiedenerlei Hinsicht. In den Metainformationen eines Bundles können Vorgaben bezüglich der erforderlichen Laufzeitumgebung (Execution Environment) hinterlegt werden. In diesen Bereich fällt zum Beispiel die benötigte Java-Version. Abhängigkeiten zu Paketen, die mit java.* anfangen, werden nicht explizit im Manifest aufgeführt. Es ist daher guter Stil, diese Abhängigkeit zur Laufzeitumgebung zu deklarieren (z.B. „J2SE-1.4“). Je weniger Sie fordern, desto höher ist die Wahrscheinlichkeit, dass das Bundle in unterschiedlichen Szenarien wiederverwendet werden kann.

Abhängigkeiten zu Fremdbibliotheken (z.B. Log4j) können über das Importieren der entsprechenden Packages mit Versionsvorgaben deklariert werden. Dieser Ansatz setzt voraus, dass im späteren Betrieb ein Bundle im System vorliegt, das die Packages in einer passenden Version exportiert. Als Alternative können die betreffenden JAR Files auch innerhalb des Bundles mitverteilt werden. Diese Entscheidung erleichtert zwar das Deployment Ihrer Bundles, führt aber schnell zu Redundanzen in der Laufzeitumgebung und will deshalb wohl überlegt sein.

Wenn Sie Ihr eigenes Softwaresystem in Bundles zerlegen, deklarieren Sie die im Entwurf festgelegten Abhängigkeiten untereinander ebenfalls auf Paketebene. Durch das explizite Exportieren legen Sie fest, was Sie als Schnittstelle veröffentlichen wollen. Diese Entscheidung sollte unabhängig vom Schnitt der Bundles sein. Hilfreich ist es hier, spezielle Pakete für die Implementierungsdetails zu schaffen und diese nach außen zu verbergen. Von OSGi abhängige Teile sollten ebenfalls in separate Pakete ausgelagert werden, um sie von den unabhängigen, generell wiederverwendbaren Teilen zu trennen. Dies betrifft speziell Bundle-Aktivatoren, oder genereller Anwendungsteile, die auf die dynamischen Aspekte von OSGi setzen.

Die Empfehlungen im Überblick
  • Halte Deinen eigentlichen Entwurf und dessen Realisierung frei von OSGi.
  • Eclipse ist nicht gleich OSGi.
  • Analysiere Anforderungen bezüglich Erweiterbarkeit und Dynamik.
  • Plane Abhängigkeiten bewusst.
  • Trenne Schnittstellen von Implementierungen.
  • Erwäge den Einsatz unterstützender Technologien.
Mit bloßen Händen?

Die gesamte dynamische Funktionalität von OSGi kann über dessen API programmatisch genutzt werden, allerdings ist dies regelmäßig mit viel Arbeit verbunden. Dabei sind die Aufgaben, die bewältigt werden müssen, regelmäßig dieselben. Mit dem ServiceTracker steht mittlerweile eine Hilfsklasse zur Verfügung, die das Arbeiten mit der Service Registry ein wenig erleichtert. Nichtsdestotrotz bleibt einiges an Handarbeit, und bei einer Entscheidung für ein Extension-basiertes Erweiterungsmodell auch noch einiges mehr. Verschiedene Open-Source-Lösungen unterstützen Sie hierbei. Dazu zählen unter anderem Implementierungen der OSGi-eigenen Declarative Services [OSGi Service Platform, Service Compendium, Release 4, Version 4.1], Spring Dynamic Modules oder das bei Apache Felix beheimatete iPOJO.

Die Verwendung derartiger Frameworks ist attraktiv, birgt aber auch Risiken. In jedem Fall muss man weitere Abhängigkeiten in Kauf nehmen, zudem ist die Zukunft einzelner Lösungen ungewiss. Die Entscheidung für eine der Bibliotheken will daher wohl überlegt sein. Beachten Sie, dass sich die genannten Lösungen insbesondere im Maß ihrer Invasivität unterscheiden. Das hat Auswirkung auf die Frage, ob die Entscheidung für eine Lösung in vertretbarem Aufwand zurücknehmbar ist.

Fazit

OSGi erweitert Java um Ausdrucksmittel für gewollte und unerwünschte Abhängigkeiten und die Erweiterbarkeit zur Laufzeit. Der Entwurf einer Anwendung unter Verwendung von OSGi zwingt Sie, bei der Umsetzung Dinge explizit zu machen (z.B. das Bilden von Modulen, das Deklarieren von Abhängigkeiten), die für ein gutes Design ohnehin unerlässlich sind.

Stefan Zörner arbeitet als Berater und Trainer bei der oose Innovative Informatik GmbH in Hamburg im Bereich Software-Engineering. Er ist Autor zahlreicher Artikel rund um Java sowie Büchern zu den Themen LDAP und Portlets.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.