Das OSGi-Komponentenmodell

Flucht aus der "Jar-Hölle"

Sven Johann und Bernd Böllert

OSGi lässt es zu, einige Lücken zwischen logischen Komponenten und physischen Java-Elementen wie jar, war und ear zu schließen. In einem OSGi-Bundle sind die Abhängigkeiten zu anderen Bundles explizit beschrieben. Zusätzlich wird interessierten Bundles mitgeteilt, auf welche Services sie zugreifen können. Das steht in der Manifest-Datei des OSGi-Bundles (Kasten: „Import/Export der Komponente „com.acme.waz“ in OSGi“).

Nur ein Problem löst OSGi noch nicht: den verfeinerten Komponentenbaum, also Komponenten, die aus anderen zusammengebaut werden. Die Betonung liegt auf noch nicht. Denn genau das ist für die neue OSGi-Generation geplant. Der „Early Draft 3“ der OSGi-Version 4.2 beschreibt den „RFC 0138 Multiple Frameworks In One JVM“ [6]. Dieser erlaubt es, Vater-Kind-Beziehungen auf OSGi-Ebene zu definieren. Die Beziehungen werden in der Composite-Manifest-Datei beschrieben. Endgültig soll das aber erst in OSGi 5 passieren. Trotzdem implementieren einige OSGi-Frameworks wie Eclipse Equinox [7] oder Google Lemmon [8] den RFC bereits teilweise.

Import/Export der Komponente „com.acme.waz“ in OSGi

In Abbildung 1 sehen wir, dass die Komponente com.acme.waz.1.0 der Anwendung com.acme.system Services der Komponente com.acme.bar.2.3 nutzt. OSGi beschreibt das durch einen Eintrag in der Import-Package-Liste: Import-Package: com.acme.bar;version=2.3.

Genauso funktioniert der Export von Services. com.acme.waz.1.0 exportiert Services, die von com.acme.foo.2.2 genutzt werden. Das wird durch die Export-Package-Liste beschrieben: Export-Package: com.acme.waz.

Das heißt auch, dass nur die Klassen sichtbar sind, deren Package explizit exportiert wird. Wir haben also neue Sichtbarkeitsregeln: public ist nun nicht mehr public für alle Klassen, sondern nur noch für Klassen innerhalb des Bundles. Für andere Bundles sind nur noch die Teile des Bundles public, die durch die Manifest-Datei festgelegt wurden. Die Komponente com.acme.waz.1.0 sieht also nur die public-Services des Packages com.acme.bar und keine Implementierungsdetails, z. B. von com.acme.bar.impl.

Starkes Komponentenmanagement durch OSGi

Die Verwaltung von jar-Dateien in einer Java-EE-Anwendung ist so katastrophal, dass sie manchmal als „Jar-Hölle“ beschrieben wird (u. a. unter [9]). Selbst in kleinen Anwendungen ist es mittlerweile extrem schwer, die Abhängigkeiten der jar-Dateien untereinander nachzuvollziehen. Schlimmer noch: jar-Dateien sind völlig unübersichtlich in verschiedensten Verzeichnissen abgelegt, z. B. in einem ear-lib-Ordner, mehreren war-lib-Ordnern, im Server-lib des Application-Servers oder in einem endorsed-Verzeichnis des Application Servers. Welche Datei wann und von wem in welcher Version angezogen wird, bleibt dem Entwickler oftmals ein Rätsel. Es scheint auch anders zu gehen, denkt sich der Nutzer von Maven oder Eclipse. Hier gibt es mehr Ordnung: Maven hat eine saubere Verwaltung von jar-Dateien im Maven Repository. Ähnlich sieht es bei Eclipse aus: Es gibt ein Verzeichnis (/plugins/), in dem alle jar-Dateien mit Versions- und Abhängigkeitsinfo zu finden sind.

SpringSource stellt mit dem dm-Server [10] einen OSGi-Application-Server bereit, der sich dieser Probleme annimmt: Der dm-Server besitzt ein Repository-Verzeichnis, in dem alle benötigten jar-Dateien genau einmal als OSGi-Bundles zur Verfügung gestellt werden (wenn nötig, in mehreren Versionen). Die jar-Dateien sind allerdings nicht so schön geordnet wie bei Maven, sondern werden flach abgelegt. Alle Enterprise-Applikationen, die im dm-Server deployt sind, bedienen sich dann aus diesem Repository. Die Enterprise-Applikation selbst wird im Pickup-Verzeichnis abgelegt. Es gibt hier vielfältige Möglichkeiten (als jar-, war- oder par-Datei), die z. B. unter [11] ausführlich beschrieben werden. SpringSource bietet mit der Spring-Toolsuite [12] eine gute Unterstützung für OSGi und den Spring-dm-Server, so wie es auch für klassische Webapplikationen bekannt ist. Der dm-Server wird übrigens ein Eclipse-Projekt werden: Da kann man sich schon auf weitere Innovationen freuen [13].

OSGi überall

Die Einsatzmöglichkeiten für ein Servicekomponentenmodell sind vielfältig. Im Großen (SOA) aber auch im Kleinen (den Embedded Systems) ist OSGi im Einsatz. Neu ist die Verwendung auf Google-Android-Systemen und im Cloud Computing dank Scala. Aber was macht OSGi nun für diese Systeme so interessant? Google Android umfasst eine VM, die Java sehr stark ähnelt. Daher ist eine Portierung von OSGi-Frameworks möglich. Auf Android-Geräten gibt es eine Menge von nebenläufigen Prozessen, die oft denselben Service benötigen, manchmal aber in unterschiedlichen Versionen. Das ist, wie bereits beschrieben, mit OSGi ohne Weiteres möglich. Ein anderes Plus bietet die Möglichkeit, die Services während des Betriebs zu aktualisieren, was in einer Multithread-Umgebung ohne OSGi nicht trivial ist. Da Apache Felix eine sehr ressourcenschonende Implementierung ist, bietet sich für die Verwendung mit Android an, es auf schwacher Hardware einzusetzen. Die gleichen Punkte machen OSGi auch in der Verwendung im Cloud Computing interessant. Scala stellt für Cloud Computing die notwendige Architektur mit einem Actor Model und funktionalen Sprachelementen zur Verfügung. Was fehlt, ist ein Lifecycle sowie die Verwaltung von parallelen Versionen. Scala hat diese Schwäche gelöst, indem die etablierte OSGi-Architektur verwendet wird. Da Scala auf Java-basiert und in einer Anwendung zwischen Scala und Java hin- und hergewechselt werden kann, bietet es sich an, den Wechsel jeweils über eine OSGi-Serviceschicht zu entkoppeln. Durch diese Entkopplung ist es möglich, existierende Anwendungen schrittweise zu modularisieren und wahlweise in Scala oder Pure Java zu realisieren.

Fazit und Ausblick

Probleme mit aktuellen Java-EE-Anwendungen lassen sich also mit OSGI mindern, wenn nicht sogar lösen. Versionsprobleme von jar-Dateien gehören der Vergangenheit an. Jeder bekommt, was er benötigt. Anwendungen sind Dank des geringen Footprints, Lazy Loadinga und des Lifecycle-Modells ressourcenschonend, starten schneller und lassen sich zügiger und gezielter aktualisieren.

OSGi hat seinen Ursprung in den Embedded Systems im Automotive- oder Mobiltelefonbereich, aber alle in diesem Artikel vorgestellten Vorteile haben zu einer weiteren Verbreitung in Richtung Desktop (z. B. Eclipse) und Infrastruktur/Middleware (z. B. Oracle Weblogic basiert auf OSGi, JBoss stellt auf OSGi um) geführt. Der folgerichtige Schritt ist, dass nun auch Enterprise-Anwendungen diesen Weg einschlagen. Spring macht dies mit dem SpringSource-dm-Server. Weitere Schritte werden folgen. Das OSGi-Framework entwickelt sich stetig weiter und auch die Toollandschaft in diesem Bereich wird weiter wachsen, um die Entwicklung zu vereinfachen. Wichtig ist, dass OSGi die Lücke zwischen logischem Entwurf und physikalischer Implementierung schließen wird. Logische Komponenten finden sich bald nicht mehr nur in Modellen wieder, sondern es wird sie dank der Composite Bundles auch auf physikalischer Ebene geben. Ein Schritt in diese Richtung ist mit dem Bundle-Konzept und der Import-/Exportdefinition der Schnittstellen in der Manifest-Datei schon getan.

Wir dürfen gespannt sein, wie Oracle/Sun darauf reagiert. Der erste Schritt war, dass Oracle und SpringSource das Eclipse-Gemini-Projekt [14] für Enterprise OSGi gegründet haben.

Sven Johann ist Senior Software Engineer bei der adesso AG und befasst sich seit 2002 mit Komponentenentwicklung und seit 2006 mit OSGi.

Bernd Böllert ist Senior Software Engineer bei der adesso AG und befasst sich seit 1999 mit Unternehmensarchitekturen und Methoden rund um Java.

Geschrieben von
Sven Johann und Bernd Böllert
Kommentare

Schreibe einen Kommentar

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