Open Source im professionellen Einsatz

Java und das Betriebssystem

80 Prozent Java

Reine Java-Programme laufen auf allen Plattformen. Doch manchmal ist eine engere Verzahnung mit dem jeweiligen Betriebssystem notwendig. Wie das zu bewerkstelligen ist und welche Pakete es dafür in der Open-Source-Landschaft bereits gibt, zeigt dieser Beitrag.

Die Plattformunabhängigkeit wird immer als gewichtiges Argument für Java in die Waagschale geworfen. Ich halte dieses Argument aber für eher schwach, da Linux ja auch auf nahezu allen Plattformen läuft und mit der Verfügbarkeit des GCC und der Pakete Autoconf und Automake die Anwendungen sehr einfach auf vielen unterschiedlichen Betriebssystemen installierbar sind. Als Entwickler ist für mich die allgemeine Verfügbarkeit von standardisierten APIs für alle Bereiche wichtiger: Bei grafischen Oberflächen gibt's keine Diskussionen à la Qt gegen Gtk; Messaging ist mit JMS flexibel und doch standardisiert; beim Mailing hilft das Java-Mail-API. Es gibt noch viele weitere Beispiele.

Selbst wenn ein Programm nur für eine spezielle Plattform entwickelt wird, ist also Java eine gute Wahl. Doch trotz umfassend vorhandener APIs gilt auch für Java, was für alle Bereiche der EDV gilt: Nothing is perfect. Es gibt daher mindestens drei Gründe C- oder C++-Code in Java einzubinden:

  • Performance: Als interpretierte Sprache kann Java nie die Geschwindigkeit erreichen, die native Programme haben. Insbesondere bei rechenintensiven Programmen zahlt sich der Aufwand aus übersetzten Code zu verwenden.
  • Legacy Code: Müssen Schnittstellen vorhandener Anwendungssysteme aus Java heraus bedient werden, bleibt nur die Möglichkeit, das Java Native Interface (kurz JNI) zu nutzen.
  • Plattformspezifische Funktionen: Java kann nur den kleinsten gemeinsamen Nenner der üblichen Betriebssystem-Funktionen unterstützen. Aus Java heraus sind deshalb Abfragen beispielsweise von Dateiberechtigungen nicht möglich - einfach deshalb, weil dieses Konzept unter Windows (fast) nicht vorhanden ist.

Gemeinsame Bibliotheksbenutzung mit dem JNI

Seit der ersten Java-Version ist eine Schnittstelle zwischen Java und nativen Programmen vorhanden. Das JNI erlaubt den Zugriff aus Java heraus auf Funktionen in Ladebibliotheken (Shared Libraries: unter Unix mit der Extension .so, unter Windows die bekannten und gefürchteten DLLs). Ebenso kann ein C- oder C++-Programm eine virtuelle Maschine starten, etwa um Scripting-Funktionalität zu implementieren. Hier gibt es aber mit Skriptsprachen wie Python deutlich bessere Optionen.

Das JNI wurde in einem früheren Coffee-Shop schon einmal im Detail vorgestellt [1], deshalb gehe ich hier nur noch kurz auf die grundlegende Funktionsweise ein. Die Abbildung 1 zeigt schematisch, was bei einem JNI-Aufruf passiert. Aufrufe einer in der Klassendefinition als nativ gekennzeichneten Methode werden durch die virtuelle Maschine an eine Funktion innerhalb einer Ladebibliothek weitergeleitet.

Der Prototyp dieser Funktion wird durch ein Hilfsprogramm (Javah) aus dem JDK automatisch erzeugt. Diese Funktionen erhalten alle Argumente der Java-Methode und zusätzlich einen so genannten Environment-Pointer, mit dessen Hilfe die vordefinierten APIs der virtuellen Maschine aufgerufen werden können, um beispielsweise Zugriff auf Klassen oder Methoden zu bekommen.

Trotz dieser einfachen Struktur ist es angebracht, mit dem JNI sehr vorsichtig umzugehen. Memory-Leaks und Threading-Probleme schleichen sich damit unbemerkt in sonst saubere Programme ein. Auch das Debuggen wird komplexer. Daher sollte der JNI-Code nur den absolut notwendigen Wrapper-Code enthalten, die eigentlichen Funktionen dagegen sollten außerhalb liegen und über normale C- oder C++-Programme verifiziert werden. Meist reicht es tatsächlich, nur die Umsetzung der Java-Parametertypen in normale C-Typen zu kodieren, etwa von einem jstring zu einem char*.

Abbildung 1: Funktionsweise des JNI.

Abbildung 1: Funktionsweise des JNI.

Kopieren geht über Programmieren

Zum Glück ist es in vielen Fällen nicht notwendig, selbst C-Code zu schreiben, obwohl gerade die Auseinandersetzung mit dem JNI nützliche Einblicke in die Funktionsweise von Java gewährt. Im Internet gibt es eine Reihe von Paketen, die gewissermaßen ready to run in eigene Programme einbindbar sind. Ich stelle eine Auswahl hier vor. Für Hinweise über weitere nützliche Pakete bin ich wie immer dankbar, das Internet ist inzwischen einfach zu groß, um den Überblick zu behalten.

Selbst wenn eines der verfügbaren Pakete nicht die eigenen Bedürfnisse deckt, kann es doch über Copy & Paste als Vorlage für eigene Implementationen dienen und damit die Entwicklung deutlich beschleunigen. Das ist im Sinne des Open-Source-Gedankens ausdrücklich erwünscht.

Diesen Artikel als PDF kaufen

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook