Herausforderung "Modularisierung"

OSGi ist ein dynamisches Modulsystem für Java™. Wie hilft es Ihnen?

Effektive Softwaremodule haben die folgenden Merkmale:
  • Eigenständig: Obwohl sich ein Modul aus kleineren Komponenten zusammensetzt, kann das gesamte Modul anstelle der einzelnen Komponenten des Moduls verschoben, installiert und deinstalliert werden.
  • Hohe Kohäsion: Jedes Modul hat eine kohärente logische Funktion.
  • Flexibel verbunden: Zwischen Modulen werden klare Grenzen definiert.
Modularisierte Systeme, die diese Merkmale aufweisen, lassen sich einfacher verwalten und erweitern.

Objektorientierte Sprachen wie Java unterstützen die Modularisierung. Allerdings konzentrieren sich diese Sprachen auf die Kapselung von Instanzvariablen. Dies ist eine Hilfe auf Objekt- und Klassenebene, unterstützt aber keine höheren Formen der Modularität. Java EE hilft ein wenig mehr, indem es eine Isolierung der Anwendungsmodule auf Anwendungsebene innerhalb einer Unternehmensanwendung ermöglicht.

Muster wie SOA und Abhängigkeitsinjektion (Dependency Injection) fördern das modulare Design großer Unternehmensanwendungen. Diese Modularität setzt jedoch Architektur-Governance voraus und keine Förderung oder Umsetzung durch die Laufzeitumgebung.

In der Java-Plattform werden Daten in einer Klasse gekapselt, Klassen sind innerhalb eines Pakets definiert und Pakete werden in einer Java-Archivdatei (JAR) zusammengefasst. Die Sichtbarkeitsoptionen für Java-Klassen sind privat, paketbezogen, geschützt und öffentlich. Es gibt keinen Zugriffsmodifikator, der eine JAR-Datei anstelle eines Pakets als Implementierungseinheit unterstützt. Die meisten JAR-Dateien setzen sich aus mehreren Paketen zusammen, und wenn die JAR-Datei eine kohäsive Funktion darstellt, müssen die Klassen in einem Paket gewöhnlich auf Klassen in einem anderen Paket derselben JAR-Datei zugreifen. Dies setzt voraus, dass diese Klasse öffentlich zugänglich ist, was die Klasse auch für andere Klassen in anderen JAR-Dateien sichtbar macht. JAR-Dateien unterstützen keine Sichtbarkeitssteuerung. Selbst gut funktionierende Anwendungen, die nur die Klassen verwenden, die ein JAR-Dateianbieter für die externe Verwendung vorsieht, unterliegen dem Java-Klassenpfad, da eine erforderliche Klasse möglicherweise in mehreren JAR-Dateien verfügbar ist und die Klasse, die geladen wird, die erste verfügbare Instanz im globalen Klassenpfad ist.

JAR-Dateien können die Sichtbarkeit ihres Inhalts nicht definieren und auch eigene Abhängigkeiten nicht deklarieren. Viele JAR-Dateien haben implizite Abhängigkeiten von anderen JAR-Dateien, was bedeutet, dass diese JAR-Dateien nicht unabhängig voneinander installiert oder verschoben werden können. Wenn eine JAR-Datei installiert wird und Abhängigkeiten fehlen, wird das Problem häufig erst in der Laufzeitumgebung erkannt.

Beim Laden von Java-Klassen wird der Klassenpfad durchsucht, um in jeder JAR-Datei im Klassenpfad nach der erforderlichen Klasse zu suchen. Dieser Prozess weist drei Einschränkungen auf:
  • Die Klassenpfadreihenfolge bestimmt, welche Instanz einer Klasse geladen wird, und damit auch, aus welcher JAR-Datei die Klasse geladen wird.
  • Es ist nur eine einzige Version einer Klasse im Klassenpfad verfügbar, die erneut durch die erste gefundene Instanz bestimmt wird.
  • Wenn die Abhängigkeiten einer Klasse nicht aufgelöst werden, ist der erste Hinweis auf das Problem häufig das Eintreten einer Laufzeitausnahme des Typs "ClassNotFoundException".
Diese Mängel bezüglich Klassenpfaden und JAR-Dateien werden häufig auch als JAR-Hölle bezeichnet. Java EE mildert diese Probleme teilweise. Java EE führt die Enterprise-Archivdatei (EAR) ein, sowohl als Methode zur Bereitstellung einer Unternehmensanwendung als auch als Laufzeit-Isolationsbereich für die Module, die Teil dieser Anwendung sind. Java EE Anwendungen verfügen über eine Klassenlader-Hierarchie, die teilweise zwischen den Unternehmensanwendungen gemeinsam genutzt wird und teilweise zwischen den Anwendungen isoliert ist. In einer Unternehmensanwendung, die ein WAR-Modul (Web Application Archive, Webanwendungsarchiv) enthält, werden die einzelnen WAR-Module in der Anwendung beispielsweise standardmäßig voneinander und von allen Komponenten in einer Anwendung isoliert.
Obwohl sich die Probleme der JAR-Hölle durch die Verwaltung unterschiedlicher Klassenpfade mit unterschiedlichen Unternehmensanwendungen verringern, gibt es weiterhin Einschränkungen, wenn Sie möchten, dass Bibliotheken wie Open-Source-Frameworks oder Dienstprogrammbibliotheken von Anwendungen gemeinsam genutzt werden. WebSphere® Application Server bietet einige erweiterte Optionen für die Konfiguration von Unternehmensanwendungen für den Zugriff auf Bibliotheken, die nicht als Teil der EAR-Datei bereitgestellt werden:
  • Sie können eine isolierte Bibliothek installieren und deren Klassenladeprogramm administrativ Modulen oder Anwendungen zuordnen oder das Klassenladeprogramm dem Server zuordnen, um es für alle Anwendungsmodule sichtbar zu machen.
  • Sie können das Delegierungsmuster für Klassenladeprogramme konfigurieren, um Probleme bei der Versionskompatibilität zu beheben. Beispielsweise können Sie den Delegierungsmodus für Klassenladeprogramme mit "Übergeordneter zuerst" festlegen, so dass eine von der Anwendung bereitgestellte Klasse vorzugsweise vor einer Klasse geladen wird, die von einem Server bereitgestellt wird.
Diese Ansätze erfüllen die Modularitätsanforderungen von Anwendungen jedoch nur teilweise. Das OSGi-Framework bietet eine bessere Lösung.