11.4 Packen mit jar

Einführung jar: Java Archive Tool

Javaprogramme können aus sehr vielen Klassen und externen Bibliotheken bestehen. "jar" Dateien erlauben das Bündeln von Klassendateien und anderer Dateien um Installation und die Verteilung von Javaprogrammen zu vereinfachen. Mit jar Dateien werden die folgenden Ziele verfolgt:

  • Bessere Wartbarkeit: Bündelung von zusammengehörigen Klassen und Dateien um Fehler bei der Anwendung zu vermeiden
  • Schnellerer download von Applet der Java Web Start Anwendungen durch Kompression und Begrenzung des Downloads auf eine einzelne Datei
  • Gewährleistung der Integrität und Authentizität  von Anwendungen: jar Dateien können signiert werden
  • Vereinfachte Softwaredistribution und Installation durch Beschränkung auf eine einzige Datei

jar Dateien werden mit dem gleichnamigen Kommando jar des JDK manipuliert. jar steht für Java ARchive.

Das jar Format ist plattformunabhängig und ist daher auf allen Javaplattformen verfügbar.

Hinweis: Das jar Format basiert auf dem zip Dateiformat. Das heißt, dass man auch mit zip,unzip Inhalte von jar Dateien inspizieren kann! Zum Erzeugen von jar Dateien ist zip jedoch nicht geeignet da jar zusätzliche Informationen wie Manifestinformationen etc. erzeugt.

Die wichtigsten jar Operationen
Operation Befehl
Erzeugen einer jar Datei jar cf jar-Datei liste-Dateien
Auflisten des Inhalts einer jar Datei jar tvf jar-Datei
Auslesen einer jar Datei jar xf jar-Datei 
Auslesen bestimmter Dateien einer jar Datei jar xf jar-Datei auszupackende-Datei
Starten einer Javaanwendung mit Hilfe einer jar Datei java -jar anwendung.jar

 

Erzeugen einer jar Datei

Das allgemeine Format zum Erzeugen einer Datei mit einem jar-Archiv ist:

jar cf jar-Datei Eingabedatei(en)

Die hier verwendeten Optionen und Argumente bedeuten

  • c Option: Erzeugen (c = create) einer Datei
  • f Option: Erzeugen einer Datei (anstatt Ausgabe des Ergebnis auf der Standardausgabe bzw. Konsole)
  • jar-Datei: Name der zu erzeugenden Datei. Die Extension *.jar ist nicht zwingend, sie ist jedoch üblich.
  • Eingabedatei(en): Eine oder mehrere Dateien die in das Archiv aufgenommen werden sollen.
    • Bei mehr als einer Datei werden die Dateien durch Leerstellen getrennt
    • Werden Verzeichnisse angegeben so wird der vollständige Inhalt der Verzeichnisse rekursiv in das Archiv aufgenommen
    • Es können mit dem "Wildcard"-Operator mehrere Dateien aufgenommen werden. Beispiel *.class um alle Javabytecodedateien eines Verzeichnisses aufzunehmen.

Beim Erzeugen einer jar Datei legt das Kommando jar immer eine Manifest Datei MANIFEST.MF im folgenden Verzeichnis des Archivs an:

META-INF/MANIFEST.MF

Der Inhalt dieser Datei ist im einfachsten Fall:

Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)

Im Manifest des Archivs werden Metadaten wie zum Beispiel Signaturen, das gewählte Hauptprogramm zum Starten, oder Urheberansprüche verwaltet.

Weitere Optionen:

  • v (verbose) detaillierte Informationen während der Ausführung des Kommandos
  • 0 keine Kompression verwenden
  • M kein Standardmanifest generieren
  • m Einfügen einer eigenen Manifestdatei

Beispiel

Gegeben sei eine Anwendung bei der drei Klassen Database.classMain.class und GUI.class und alle Bilddateien im Verzeichnis bilder in das jar Archiv gepackt werden sollen:

Dies geschieht mit dem Befehl:

$ jar cvf appl.jar *.class bilder
Manifest wurde hinzugefügt.
Hinzufügen von: Database.class (ein = 10240) (aus = 27) (komprimiert 99 %)
Hinzufügen von: GUI.class (ein = 10240) (aus = 27) (komprimiert 99 %)
Hinzufügen von: Main.class (ein = 10240) (aus = 27) (komprimiert 99 %)
Hinzufügen von: bilder/ (ein = 0) (aus = 0) (gespeichert 0 %)
Hinzufügen von: bilder/Bild1.jpg (ein = 10240) (aus = 27) (komprimiert 99 %)
Hinzufügen von: bilder/Bild2.jpg (ein = 10240) (aus = 27) (komprimiert 99 %)
Hinzufügen von: bilder/Bild3.jpg (ein = 10240) (aus = 27) (komprimiert 99 %)

Inspektion eines jar Archivs

jar Archive können mit der der jar Option t inspiziert werden:

jar tvf jar-Datei

Die hier verwendeten Optionen und Argumente bedeuten:

  • t Option: Ausgabe des Inhaltsverzeichnis ( t = table of contents)
  • f Option: Das zu inspizierende Archiv ist eine Datei
  • jar-Datei: Die zu inspizierende Datei falls die Option t gewählt wurde
  • v Option: (verbose) zusätzliche Informationen wie Dateigrößen und Änderungsdatum der Archivdateien

Beispiel

Für das oben angeführte Beispiel ergibt sich der folgende Befehl

$ jar tf appl.jar
META-INF/
META-INF/MANIFEST.MF
Database.class\r\nGUI.class
nMain.class
bilder/
bilder/Bild1.jpg
bilder/Bild2.jpg
bilder/Bild3.jpg

Einen detaillierten Überblick kann man mit der v Option (v: verbose, engl. "ausführlich") gewinnen

$ jar tvf appl.jar
     0 Sun Dec 12 16:27:56 CET 2010 META-INF/
    60 Sun Dec 12 16:27:56 CET 2010 META-INF/MANIFEST.MF
 10240 Sun Dec 12 16:26:10 CET 2010 Database.class
 10240 Sun Dec 12 16:26:00 CET 2010 GUI.class
 10240 Sun Dec 12 16:25:50 CET 2010 Main.class
     0 Sun Dec 12 16:27:12 CET 2010 bilder/
 10240 Sun Dec 12 16:27:02 CET 2010 bilder/Bild1.jpg
 10240 Sun Dec 12 16:27:04 CET 2010 bilder/Bild2.jpg
 10240 Sun Dec 12 16:27:12 CET 2010 bilder/Bild3.jpg

Extrahieren eines jar Archivs

jar Archive werden mit dem folgenden Befehl ausgepackt (ausgelesen);

$ jar xvf jar-Datei [archivierte-Datei(en)]

Die hier verwendeten Optionen und Argumente bedeuten:

  • x Option: Extrahiere Dateien aus einem jar Archiv
  • f Option: Extrahiere Dateien aus einer Datei (und nicht von der Standardeingabe)
  • jar-Datei: die Datei mit dem zu extrahierenden jar Archiv
  • archivierte-Datei(en): eine optionale, mit Leerzeichen separierte Liste von Dateien die extrahiert werden sollen. jar wird alle Dateien des Archivs extrahieren falls diese Liste nicht angegeben wird.

Der jar Befehl wird beim Extrahieren

  • existierende Dateien überschreiben
  • bei Bedarf neue Unterverzeichnisse anlegen
  • die ursprüngliche Archivdatei nicht verändern.

Beispiel

Auspacken des jar Archivs mit ausführlicher Protokollierung:

$ jar xvf appl.jar
     erstellt: META-INF/
dekomprimiert: META-INF/MANIFEST.MF
dekomprimiert: Database.class
dekomprimiert: GUI.class
dekomprimiert: Main.class
     erstellt: bilder/
dekomprimiert: bilder/Bild1.jpg
dekomprimiert: bilder/Bild2.jpg
dekomprimiert: bilder/Bild3.jpg

Hinzufügen von Dateien zu jar Archiven

Die Option u (update) erlaubt das Hinzufügen von Dateien zu Archiven mit der folgenden Syntax

$ jar uf jar-Archiv Datei(en)

Benutzen von jar Archiven beim Ausführen von Programmen

Das Javalaufzeitsystem sucht beim Aufruf mit Hilfe des "Classpath" (Pfad zu den Klassen) nach ausführbaren Dateien mit der Endung .class .

Wird kein expliziter "Classpath" angegeben, so wird  im aktuellen Verzeichnis und den darunterliegenden Verzeichnissen gesucht. Unterverzeichnisse können Pakete mit deren Klassen enthalten.

Mit Hilfe der Option -cp oder -classpath kann man die Suche nach Klassendateien steuern. Man kann hier eine Liste der folgenden Dinge angeben:

  • Verzeichnisse
  • jar Dateien
  • zip Dateien

Die Elementeliste der jar Archive und Suchverzeichnisse mit mit dem Zeichen ":" getrennt. Hiermit kann man ein Javaprogramm mit einem jar Archiv starten:

$ java -cp appl.jar Main

Starten von Programmen aus jar Archiven

jar Archive können benutzt werden um direkt Programme aus ihnen heraus anzustarten. Dies geschieht mit der Option -jar im Kommando java:

$ java -jar jar-Datei

Hierzu muss in der Manifestdatei des Archivs ein einzeiliger Eintrag mit der Klasse stehen deren Methode main() aufgerufen werden soll. Dieser Eintrag muss im folgenden Format geschehen:

Main-Class: klassenname

Der obige Eintrag muß mit einem "Carriage return" (Zeilenumbruch) abgeschlossen werden, da er sonst nicht korrekt ausgelesen wird (Siehe Oracle Tutorial).

Zum Erzeugen des Manifesteintrags gibt es eine Reihe von Möglichkeiten

Option m (Manifest): Übergabe einer Manifestdatei mit Startklasse

Eine Manifestdatei mit den gewünschten Einträgen wird selbst erstellt und dann beim Erzeugen des Archivs mit Hilfe der m-Option mit angegeben.

Beispiel:

$ jar cfm appl.jar Manifest.txt *.class bilder

Option e (Entrypoint): Angabe der zu startenden Klasse

Die Klasse mit der main() Methode wird direkt angegeben.

Beispiel:

$ jar cfe appl.jar Main *.class bilder

Referenzen