Applikationsdesign im Zeitalter von OSGi - JAXenter

Applikationsdesign im Zeitalter von OSGi

Hybride Artefakte

Bundles sind „normale“ JAR-Files. Es ist daher möglich, Software in Java so zu realisieren, dass sie in einem OSGi-Container betrieben werden kann, aber auch außerhalb lauffähig ist. Einige verbreitete Open-Source-Produkte sind bereits als OSGi-Bundles verfügbar, teilweise bereitgestellt durch die Projekte selbst, teilweise durch dritte. Im Falle des Spring Frameworks oder des Jetty Webservers sind die Bundles beispielsweise keine speziellen JAR-Files, sondern die offiziellen Release Binaries, angereichert um OSGi-spezifische Metainformationen.

Im Fall von Bibliotheken ist der Schritt, Artefakte mundgerecht für OSGi bereitzustellen, ohne die Verwendung von OSGi zu erzwingen, vergleichsweise einfach. Die Bundles haben dann keinen Aktivator, veröffentlichen und nutzen keine Services etc., sondern sind lediglich JAR Files, die im Manifest neben anderen Bundle-Informationen (vor allem: Bundle-SymbolicName) über den Header Export-Package Java-Klassen und -Schnittstellen zur Verfügung stellen. Benötigte Pakete werden ebenfalls in den Metainformationen beschrieben. Im Fall des Betriebs der JAR Files als Bundles in einem OSGi-Framework greift das Prüfen der Abhängigkeiten. Bei anderer Verwendung (z.B. als Klassenbibliothek in einer Webapplikation) werden die Metainformationen von der Laufzeitumgebung ignoriert.

Man kann noch weiter gehen und z.B. Funktionalität des JAR-Files dynamisch über Bundle-Aktivatoren als Dienste in der Service Registry bereitstellen. Besonders naheliegend ist das bei von OSGi standardisierten Services wie Logging oder HTTP. Entsprechend finden sich in öffentlichen Bundle Repositories (z.B. OSGi Bundle Repository) Varianten von Jetty oder Apache Commons Logging als Bundles, bereitgestellt von Projekten wie Apache Felix oder JOnAS. Bei der Implementierung isoliert man OSGi-spezifische Klassen idealerweise in einem gesonderten Package. Das Adapter-Pattern leistet gute Dienste, um eine vorhandene Komponente über eine OSGi-spezifische Schnittstelle bereitzustellen. Ergebnis ist dann beispielsweise ein Bundle, das Jetty zur Implementierung des standardisierten HTTP-Services [OSGi Service Platform, Service Compendium, Release 4, Version 4.1] nutzt, und im Rahmen des Aktivators die Embedded-Variante des Servlet-Containers startet bzw. stoppt und den Dienst registriert. OSGi operiert in diesem Beispiel lediglich als eine Option, um den Server zu starten. Es ist den Entwicklern gelungen, den eigentlichen Applikationscode (ihren Servlet-Container) vom OSGi-Framework unabhängig zu halten.

Der Ansatz lässt sich auch für selbstdefinierte, also nicht standardisierte Dienste verwenden. Allerdings kann man dann natürlich nicht von einem bestehenden Design profitieren. Schnittstellen, Protokolle etc. müssen selbst entworfen werden. Kann man sich vielleicht sonst irgendwo etwas abgucken?

Von Eclipse lernen?

Eclipse wird oft als Beispiel für eine produktionsreife und erfolgreiche Anwendung auf Basis von OSGi genannt. Daraus könnte man versucht sein abzuleiten, dass Eclipse viele Best Practices der OSGi-Welt vorbildhaft umsetzt. Entscheidungen im Entwurf Pattern-artig ähnlich wie in Eclipse zu treffen hieße dann automatisch, ebenfalls ein gutes Design für OSGi zu erhalten.

Der Plan geht so nicht auf. Erst ab Release 3.0 setzt Eclipse auf das neue Modulsystem, zuvor gab es bereits ein eigenes Plug-in-Konzept. Auch wenn die Lösung dazu massiv überarbeitet wurde, wurden nicht alle grundlegenden Konzepte vollständig über Bord geworfen. Eclipse ist also nicht von Grund auf auf Basis von OSGi entworfen worden. Und es hätte sich, wenn man der Empfehlung nach Technologieunabhängigkeit im Entwurf folgt, ohnehin nicht von OSGi, sondern den konkreten Anforderungen leiten lassen sollen. Die Entwurfsentscheidungen innerhalb von Eclipse 3.0 waren teilweise Kompromisse, geboren aus der Notwendigkeit der Migration auf OSGi. Vielleicht hat auch eine Rolle gespielt, dass die bestehende Plug-in-Entwicklergemeinde nicht verprellt werden sollte.

In jedem Fall werden die Anforderungen und Rahmenbedingungen, die den Entscheidungen innerhalb des Eclipse-Projekts zugrunde lagen, für Ihr eigenes Softwaresystem nicht exakt so gelten, genauso wenig wie die anderen Eclipse-spezifischen Besonderheiten, vor allem der Migrationsaspekt. Das macht ein Abgucken für eine eigene Lösung, die für Erweiterungs- und Dynamikaspekte von Beginn an auf OSGi setzen kann, heikel. Konkretes Beispiel für eine solche Entscheidung ist die Tatsache, dass in Eclipse Abhängigkeiten in der Regel zwischen Bundles (im Eclipse-Sprachgebrauch „Plug-ins“) deklariert werden, und nicht, wie vielfach empfohlen, zwischen Packages. Auch die Wahl eines Extension-basierten Ansatzes für Erweiterungen ist sicherlich nicht immer angemessen. Was hat es damit auf sich?

Das Open Closed Principle

Eine zentrale Entscheidung beim Einsatz von OSGi dreht sich um die Frage, wie die zu entwerfende Lösung später erweiterbar sein soll. Welche Erweiterungspunkte (damit sind hier nicht zwingend Eclipse Extension Points gemeint!) sollen angeboten werden, und wie dynamisch sollen Implementierungen derselben in Betrieb und wieder aus dem Rennen genommen werden können? Und wie sollen sich Komponenten unabhängig voneinander ändern können?

Im Extremfall wird OSGi ausschließlich zur Strukturierung der Softwareartefakte des Systems sowie zur expliziten Vereinbarung von Abhängigkeiten inklusive Versionen eingesetzt, und auf dynamische OSGi-Features zur Erweiterbarkeit völlig verzichtet. Eine solche Entscheidung ist denkbar, denn jedes größere Java-Vorhaben wird allein schon von OSGis Möglichkeiten zum Abhängigkeitsmanagement profitieren.

Kommentare

Schreibe einen Kommentar

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