Galileo Computing < openbook >
Galileo Computing - Professionelle Buecher. Auch fuer Einsteiger.
Galileo Computing - Professionelle Buecher. Auch fuer Einsteiger.


Java ist auch eine Insel von Christian Ullenboom
Buch: Java ist auch eine Insel (Galileo Computing)
gp Kapitel 25 Dienstprogramme für die Java-Umgebung
gp 25.1 Die Werkzeuge im Überblick
gp 25.2 Der Compiler javac
gp 25.2.1 Der Java-Interpreter java
gp 25.2.2 Der Unterschied zwischen java.exe und javaw.exe
gp 25.3 Das Archivformat Jar
gp 25.3.1 Das Dienstprogramm Jar benutzen
gp 25.3.2 Das Manifest
gp 25.3.3 Jar-Archive für Applets und Applikationen
gp 25.4 Mit JavaDoc und Doclets dokumentieren
gp 25.4.1 Mit JavaDoc Dokumentationen erstellen
gp 25.4.2 Wie JavaDoc benutzt wird
gp 25.4.3 Eine Dokumentation erstellen
gp 25.4.4 JavaDoc und Doclets
gp 25.5 Konvertierung von Java-Bytecode in ein Windows-Exe mit JET
gp 25.6 Manteln von Java-Klassen in ein Windows-Exe mit JexePack
gp 25.7 Decompiler
gp 25.7.1 Jad, ein schneller Decompiler
gp 25.7.2 SourceAgain
gp 25.7.3 Decompilieren erschweren
gp 25.8 Obfuscate Programm RetroGuard
gp 25.9 Sourcecode Beautifier
gp 25.10 Ant
gp 25.10.1 Bezug und Installation von Ant
gp 25.10.2 Properties
gp 25.10.3 Externe und vordefinierte Properties
gp 25.10.4 Weitere Leistungen


Galileo Computing

25.3 Das Archivformat Jardowntop

Sun Microsystems hat in der Version 1.1 ein Archivformat eingeführt, welches Zip ähnelt und durch das Dienstprogramm jar beim JDK unterstützt wird. Verbinden wir Java und Archiv, so ergibt sich schnell Suns Wortschöpfung JAR (Java-Archive). Zusätzlich zum Dienstprogramm gibt es auch eine API im Paket java.util.jar. Unter 1.2 hat das Jar-Dateiformat einige Erweiterungen erfahren.

Wie für ein Archivformat üblich, werden bei Jar mehrere Dateien zusammengepackt. »Gepackt« heißt aber nicht zwingend, dass die Dateien auch komprimiert werden. Jar-Dateien werden oft nicht komprimiert, sondern bündeln nur einfach die einzelnen Dateien. Ein Auspackprogramm wie Winzip kann jedoch auch Jar-Archive auspacken. Hier bleibt zu überlegen, ob ein Programm wie Winzip bei .jar geöffnet werden soll oder ob das Standardverhalten bei installiertem Jre beibehalten wird. Unter Windows ist mit der Dateiendung .jar das Programm Jre verbunden, welches die Hauptklasse des Archivs startet.

Dass ein Archiv gegenüber einzelnen Dateien Vorteile bringt, sehen wir etwa bei kleinen Applets mit zusätzlichen Ressourcen. Erinnern wir uns, dass der Applet-Klassenlader für jede zu übertragende Datei eine neue Verbindung aufbaut. Der Browser muss anstatt vieler kleiner Server-Verbindungen für jede einzelne Klassendatei und jede Ressource bei einem Archiv nur eine HTTP-Verbindung aufbauen. Auch wenn ein unkomprimiertes Archiv etwas größer ist als die vielen kleinen Dateien zusammen, ist die Übertragungszeit des Archivs kürzer, da jeder Verbindungsaufbau überproportional viel Zeit kostet. Da sich das Archiv darüber hinaus komprimieren lässt, sparen wir noch mehr Übertragungszeit und Bandbreite. Wir dürfen jedoch nicht vergessen, dass ein Archiv mitunter auch Nachteile mit sich bringen kann. Dann nämlich, wenn wir nur wenige Klassen des Archivs benötigen. Normalerweise lädt der Applet-Klassenlader die Klassen nur dann, wenn sie gebraucht werden. In einem Archiv sind aber alle Klassen enthalten, die während der gesamten Sitzung verwendet werden.

Microsoft vertraut bei seinem ActiveX-Controls vollständig auf Zertifikate. Es wird angenommen, dass kein Bösewicht ein Control anbietet, da dieser sich ja vorher ein Zertifikat geholt haben müsste, über das der Übeltäter verfolgt werden könnte. Haha! Leider ist in dieser Kette ein Denkfehler, denn Zertifikate kann sich jeder ausstellen lassen, auch unter dem Namen Micky Mouse1.

Mit Bedacht angewendet, ist das Konzept jedoch gut zu verwenden. Sun hat daher das gleiche Konzept bei Jar-Archiven eingeführt. Sie lassen sich durch eine Signatur schützen. Eine Laufzeitumgebung kann nun den Java-Programmen anhand der Signatur Extrarechte einräumen, die ein normales Programm sonst nicht hätte. Dies ist bei Programmen aus dem Intranet interessant.

Einige Eigenschaften sind beim Jar-Archiv ab der Version 1.2 hinzugekommen. So etwa, dass Hersteller Informationen über Version und Kennung hinzufügen können und ebenso eine Versionskontrolle, dass nur Klassen eines Archivs verwendet werden, um innerhalb der gleichen Version zu bleiben. Ferner kam ein Archivformat hinzu, so dass Pakete zur Core-Plattform API hinzugenommen werden können. Ein Beispiel ist etwa die 3D- und Java-Mail-API. Eigene Pakete sehen also so aus, als gehörten sie zum Standard.


Galileo Computing

25.3.1 Das Dienstprogramm Jar benutzendowntop

Jar besitzt verschiedene Optionen, um Archive zu erzeugen, sie auszupacken und anzusehen. Wenn wir Jar-Archive konstruiert haben, werden wir uns auch damit beschäftigen, wie sie aus Applets genutzt werden können. Das allgemeine Format für Jar ist:

$ jar Optionen Jar-Datei [Eingabedatei(en)]

Jar-Dateien anlegen

Die notwendige Option für das Anlegen eines neuen Archivs ist c (für engl. create). Da wir häufig die Ausgabe (das neue Archiv) in einer Datei haben wollen, geben wir zusätzlich noch f (für engl. file) an. Somit können wir schon unser erstes Archiv erstellen. Nehmen wir dazu an, es gibt ein Verzeichnis images für Bilder und die Klasse Slider.class. Dann packt folgende Zeile die Klasse und alle Bilder in das Archiv Slider.jar:

$ jar cvf Slider.jar Slider.class images

Während des Komprimierens geht Jar alle angegebenen Verzeichnisse und Unterverzeichnisse durch und gibt, da zusätzlich zu cf der Schalter v gesetzt ist, auf dem Bildschirm die Dateien mit einem Kompressionsfaktor an.

adding: Slider.class (in=2790) (out=1506) (deflated 46%)
adding: images/ (in=0) (out=0) (stored 0%)
adding: images/darkwing.gif (in=1065) (out=801) (deflated 24%)
adding: images/volti.gif (in=173) (out=154) (deflated 10%)
adding: images/superschurke.gif (in=1076)(out=926)(deflated 13%)
adding: images/aqua.gif (in=884) (out=568) (deflated 35%)

Anstatt der Dateinamen können wir auch * oder andere Wildcards angeben. Diese Expansionsfähigkeit ist ohnehin Aufgabe der Shell.

Möchten wir die Dateien nicht komprimiert haben, sollten wir den Schalter 0 angeben.

Jar behält bei den zusammengefassten Dateien die Verzeichnisstruktur. Wir sehen in der Ausgabe, dass für images ein eigenes Verzeichnis im Archiv erstellt wird und die Bilder dort hineinkopiert werden. Seit dem Java-SDK 1.2 bildet der Schalter C (genau wie -C beim Kompressionsprogramm Gzip) diese hierarchische Struktur flach ohne Verzeichnisstruktur ab. Wenn wir mehrere Verzeichnisse zusammenpacken, lässt sich für jedes Verzeichnis bestimmen, ob die Struktur erhalten bleiben soll oder nicht. Nehmen wir zu unserem Sliders-Archiv noch ein weiteres Verzeichnis mit Sound-Dateien hinzu und beobachten die Ausgabe bei

$ jar cfv0 Slider.jar Slider.class images -C sounds

Zwei Sachen sind neu. Zum einen komprimieren wir nicht mehr (Schalter 0 ist gesetzt), und wir haben mit C erreicht, dass Jar in das sound-Verzeichnis geht und dort alle Sound-Dateien in das Basisverzeichnis setzt.

Einer angelegten Archiv-Datei lassen sich später mit u (für engl. update) noch Dateien hinzufügen. Nehmen wir an, es kommt noch eine Bilddatei hinzu, so schreiben wir:

$ jar vuf Slider.jar images/buchsbaum.gif

Jar-Dateien betrachten

Um die zusammengepackten Dateien anzuzeigen, nutzen wir die Option tf.

$ jar tf Slider.jar
META-INF/MANIFEST.MF
Slider.class
images/volti.gif

Zusätzlich zu unseren Dateien sehen wir noch eine von Jar eigenständig hinzugefügte Manifest-Datei, die wir etwas später besprechen wollen.

Fehlt die Endung oder wird ein falscher Dateiname angegeben, so folgt eine etwas ungewöhnliche Fehlermeldung: java.io.FileNotFoundException: Dateiname und dann ein Stacktrace. Dies wirkt etwas unprofessionell.

Zum Anzeigen der Archive muss auf jeden Fall der Schalter t (für engl. table of contents) benutzt werden. Wir geben f nur deshalb an, weil wir den Dateinamen auf der Kommandozeile eintragen und nicht von der Standardeingabe etwa über eine Pipe lesen. Zusätzlich dazu gibt uns der Schalter v (für engl. verbose) noch den Zeitpunkt der letzten Änderung und die Dateigröße aus.

291 Fri Dec 17 14:51:08 GMT 1999 META-INF/MANIFEST.MF
  2790 Thu Dec 16 14:54:06 GMT 1999 Slider.class
   173 Mon Oct 14 00:38:00 GMT 1996 images/volti.gif

Dateien aus dem Archiv extrahieren

Der wichtigste Schalter beim Entpacken ist x (für engl. extract). Zusätzlich gilt für den Schalter f (file) das Gleiche wie beim Anzeigen: ohne den Schalter wird die Archiv-Datei in der Standardeingabe erwartet. Als Parameter ist zusätzlich das Archiv erforderlich. Sind optional Dateien oder Verzeichnisse angegeben, werden nur diese ausgepackt. Verzeichnisse werden automatisch erzeugt. Hier ist Vorsicht geboten, denn Jar überschreibt alle Dateien, die schon mit dem gleichen Namen auf dem Datenträger existieren. Das Archiv bleibt nach dem Auspacken erhalten. Wir wollen jetzt nur die Grafiken aus unserem Archiv Slider.jar auspacken. Dazu schreiben wir:

$ jar vxf Slider.jar images\*
 extracted: images\volti.gif

Die Option v haben wir eingesetzt, damit wir sehen, was genau entpackt wird. Sonst erfolgt keine Ausgabe auf der Konsole.


Galileo Computing

25.3.2 Das Manifestdowntop

Ohne dass die Ausgabe es zeigt, fügt Jar beim Erzeugen eines Archivs automatisch eine Manifest-Datei mit dem Namen META-INF/MANIFEST.MF ein. Ein Manifest enthält für ein Archiv wichtige Zusatzinformationen, wie die Signatur, die für jede Datei aufgeführt ist. Sehen wir uns einmal die Manifest-Datei an, die sich für

$ jar cfv Slider.jar Slider.class images/volti.gif

ergibt. Die Einträge im Manifest erinnern an eine Property-Datei, denn auch hier gibt es immer Schlüssel und Werte, die durch einen Doppelpunkt getrennt sind. Da sich das Manifest zwischen 1.1 und 1.2 geändert hat, listen wir beide Dateien auf. Für das JDK 1.1 sieht das Manifest dann wie folgt aus:

Manifest-Version: 1.0
Name: Slider.class
Digest-Algorithms: SHA MD5
SHA-Digest: /RD8BF1mwd3bYXcaYYkqLjCkYdw=
MD5-Digest: WcnCNJbo08PH/ATqMHqZDw==
Name: images/volti.gif
Digest-Algorithms: SHA MD5
SHA-Digest: 9zeehlViDy0fpfvOKkPECiMYvH0=
MD5-Digest: qv913KlZFi5tdPr2BjatIg==

Galileo Computing

25.3.3 Jar-Archive für Applets und Applikationentoptop

Wir haben gesehen, dass Jar-Archive für Applets in der Regel ein Vorteil sind, da gleich alle Dateien zusammen übertragen werden und der Klassenlader nicht immer Netzwerkverbindungen aufbauen muss. Dass die Dateien zusammen in einem Archiv sind, hat für Entwickler den Vorteil, dass sie dem Kunden nur eine einzige Datei ausliefern müssen und nicht ein ganzes Bündel von Klassen- und Ressourcen-Dateien. Zudem sind Bibliotheken eleganter getrennt. Unter Windows ist mit der Endung .jar gleich die JRE (Java Runtime Evironment) verbunden, so dass Programme direkt gestartet werden können: ein schöner Vorteil, denn vorher war das Ausführen nach einem Doppelklick schon etwas umständlicher.

Applikationen in Jar-Archiven

Bei Applikationen müssen wir zwischen Jar-Archiven für die Versionen 1.1 und 1.2 unterscheiden. Ab Java 1.2 lässt sich der normale Interpreter java mit der Option -jar verwenden. (Dieser wurde erst ab 1.2 eingeführt.)

$ java -jar JarDatei.jar             // >= JDK 1.2

Unter Java 1.1 müssen wir Java Runtime Environment mit dem Schalter -cp nutzen. Als Parameter ist zusätzlich zum Archivnamen auch der Name der Hauptdatei mit der statischen main()-Methode anzugeben.

$ jre -cp JarDatei.jar MainKlasse    // JDK 1.1

Wenn wir uns unter 1.1 befinden, haben wir bei einem fremden Programm das Problem, dass wir nicht unbedingt wissen, wie die Main-Klasse heißt. Das ist für den Benutzer auch nicht nötig und erschwert das Benutzen des Jar-Archivs. Doch irgendwo muss auch unter 1.2 die Main-Klasse stecken. Damit der Interpreter weiß, wo er seine Arbeit beginnen kann, sieht er in die Manifest-Datei und sucht nach dem Schlüssel Main-Class:

Main-Class: Klassenname_vom_main

Dies ist sehr elegant für den Benutzer eines Archivs, denn nun ist der Hersteller für den Eintrag des Einstiegspunkts im Manifest verantwortlich.

Damit dem Jar-Archiv die Main-Klasse mitgeteilt werden kann, lässt sich das m-Flag (für engl. merge) beim Dienstprogramm Jar nutzen, um Einträge zum Manifest hinzuzufügen. Bevor ein Archiv erzeugt wird, erstellen wir eine beliebige Textdatei, die wir hier MainfestMain.txt nennen wollen, mit dem Eintrag Main-Class. Wenn unser Slider-Programm etwa die Hauptklasse Main.class besitzt, schreiben wir

Main-Class: Main

Nun lässt sich die Datei MainfestMain.txt mit der Manifest-Datei zusammenbinden und anschließend benutzen:

$ jar cmf MainfestMain.txt Slider.jar Main.class
$ java -jar Slider.jar
$ java -jar Slider.jar Main

Applets in Jar-Archiven

Ebenso wie eine normale Klasse in der HTML-Datei innerhalb eines Applet-Tags gesetzt wird, erscheint zusätzlich auch die Jar-Datei:

<applet
  code=Main.class archive="Slider.jar"
  width=320 height=200>
</applet>

Wie bei Applets erwarten wir hier das Archiv zusammen mit der Klasse und der HTML-Datei in einem Verzeichnis. Ist etwa das Jar-Archiv in einem speziellen Unterverzeichnis applets, so schreiben wir stattdessen:

<applet
  code=Main.class archive="applets/Slider.jar"
  width=320 height=200>
</applet>





1 Obwohl dieser schon vergeben ist, doch vielleicht ist Darkwin Duck ja noch frei.





Copyright (c) Galileo Press GmbH 2004
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de