Java-Tipp 127: Siehe JAR-Ausführung
Sie können problemlos den gesamten Satz von Klassen und Ressourcen einer Anwendung in ein Java-Archiv (JAR) packen. In der Tat ist das ein Ziel von JAR-Dateien. Zum anderen können Benutzer die im Archiv gespeicherte Anwendung problemlos ausführen. Warum sind JAR-Dateien dann Bürger zweiter Klasse im Java-Universum, die nur als Archive fungieren, wenn sie neben nativen ausführbaren Dateien erstklassig sein können?
Um eine JAR-Datei auszuführen, können Sie die verwenden
java
Befehl
-jar
Möglichkeit. Angenommen, Sie haben eine ausführbare JAR-Datei mit dem Namen
myjar.jar
. Da die Datei ausführbar ist, können Sie sie folgendermaßen ausführen:
java -jar myjar.jar
.
Alternativ ordnet die Java Runtime Environment (JRE) bei der Installation auf einem Betriebssystem wie Microsoft Windows JAR-Dateien der JVM zu, sodass Sie darauf doppelklicken können, um die Anwendung auszuführen. Diese JARs müssen ausführbar sein.
Die Frage ist: Wie macht man eine JAR lauffähig?
Die Manifestdatei und der Hauptklasseneintrag
In den meisten JARs wird eine Datei aufgerufen
MANIFEST.MF
wird in einem Verzeichnis namens gespeichert
META-INF
. In dieser Datei wird ein spezieller Eintrag aufgerufen
Main-Class
erzählt der
java -jar
Befehl, welche Klasse ausgeführt werden soll.
Das Problem ist, dass Sie diesen speziellen Eintrag ordnungsgemäß selbst zur Manifestdatei hinzufügen müssen - er muss sich an einer bestimmten Stelle befinden und ein bestimmtes Format haben. Einige von uns bearbeiten jedoch keine Konfigurationsdateien.
Lassen Sie die API dies für Sie tun
Seit Java 1.2 können Sie mit einem Paket namens java.util.jar
mit JAR-Dateien arbeiten. (Hinweis: Es baut auf dem java.util.zip
Paket auf.) Insbesondere mit dem JAR-Paket können Sie diese spezielle Manifestdatei einfach über die Manifest
Klasse bearbeiten.
Schreiben wir ein Programm, das diese API verwendet. Erstens muss dieses Programm drei Dinge wissen:
- Das JAR möchten wir lauffähig machen
- Die Hauptklasse, die wir ausführen möchten (diese Klasse muss in der JAR vorhanden sein)
- Der Name einer neuen JAR für unsere Ausgabe, da wir Dateien nicht einfach überschreiben sollten
Schreiben Sie das Programm
Die obige Liste wird die Argumente unseres Programms darstellen. An dieser Stelle wählen wir einen geeigneten Namen für diese Anwendung. Wie MakeJarRunnable
klingt das?
Überprüfen Sie die Argumente für main
Angenommen, unser Haupteinstiegspunkt ist eine Standardmethode main(String[])
. Wir sollten zuerst die Programmargumente hier überprüfen:
if (args.length! = 3) {System.out.println ("Verwendung: MakeJarRunnable" + ""); System.exit (0); }}
Bitte achten Sie darauf, wie die Argumentliste interpretiert wird, da dies für den folgenden Code wichtig ist. Die Argumentationsreihenfolge und der Inhalt sind nicht in Stein gemeißelt. Denken Sie jedoch daran, den anderen Code entsprechend zu ändern, wenn Sie ihn ändern.
Greifen Sie auf die JAR und ihre Manifestdatei zu
Zuerst müssen wir einige Objekte erstellen, die sich mit JAR- und Manifestdateien auskennen:
// Erstelle das JarInputStream-Objekt und erhalte sein Manifest JarInputStream jarIn = new JarInputStream (neuer FileInputStream (args [0])); Manifest manifest = jarIn.getManifest (); if (manifest == null) {// Dies geschieht, wenn kein Manifest existiert manifest = new Manifest (); }}
Legen Sie das Hauptklassenattribut fest
Wir fügen den Main-Class
Eintrag in den Abschnitt mit den Hauptattributen der Manifestdatei ein. Sobald wir diesen Attributsatz vom Manifestobjekt erhalten haben, können wir die entsprechende Hauptklasse festlegen. Was ist jedoch, wenn Main-Class
in der ursprünglichen JAR bereits ein Attribut vorhanden ist? Dieses Programm druckt einfach eine Warnung und wird beendet. Vielleicht könnten wir ein Befehlszeilenargument hinzufügen, das das Programm anweist, den neuen Wert anstelle des bereits vorhandenen zu verwenden:
Attribute a = manifest.getMainAttributes (); String oldMainClass = a.putValue ("Hauptklasse", args [1]); // Wenn ein alter Wert vorhanden ist, teilen Sie dies dem Benutzer mit und beenden Sie if (oldMainClass! = Null) {System.out.println ("Warnung: Der alte Wert der Hauptklasse lautet:" + oldMainClass); System.exit (1); }}
Geben Sie das neue JAR aus
Wir müssen eine neue JAR-Datei erstellen, also müssen wir die JarOutputStream
Klasse verwenden. Hinweis: Wir müssen sicherstellen, dass wir nicht dieselbe Datei für die Ausgabe verwenden wie für die Eingabe. Alternativ sollte das Programm möglicherweise den Fall berücksichtigen, in dem die beiden JAR-Dateien identisch sind, und den Benutzer auffordern, das Original zu überschreiben. Ich behalte mir dies jedoch als Übung für den Leser vor. Weiter mit dem Code!
System.out.println ("Schreiben in" + args [2] + "..."); JarOutputStream jarOut = neuer JarOutputStream (neuer FileOutputStream (args [2]), Manifest);
Wir müssen jeden Eintrag von der Eingabe-JAR in die Ausgabe-JAR schreiben, also iterieren Sie über die Einträge:
// Erstelle einen Lesepuffer, um Daten vom Eingabebyte zu übertragen [] buf = new byte [4096]; // Iteriere die Einträge JarEntry entry; while ((entry = jarIn.getNextJarEntry ())! = null) {// Die Manifestdatei von der alten JAR ausschließen, wenn ("META-INF / MANIFEST.MF" .equals (entry.getName ())) continue; // Schreibe den Eintrag in die Ausgabe JAR jarOut.putNextEntry (entry); int read; while ((read = jarIn.read (buf))! = -1) {jarOut.write (buf, 0, read); } jarOut.closeEntry (); } // Alle Streams leeren und schließen jarOut.flush (); jarOut.close (); jarIn.close ();
Komplettes Programm
Natürlich müssen wir diesen Code innerhalb einer main
Methode, innerhalb einer Klasse und mit einem geeigneten Satz von Importanweisungen platzieren. Der Abschnitt Ressourcen enthält das vollständige Programm.
Anwendungsbeispiel
Lassen Sie uns dieses Programm anhand eines Beispiels verwenden. Angenommen, Sie haben eine Anwendung, deren Haupteinstiegspunkt in einer Klasse namens liegt HelloRunnableWorld
. (Dies ist der vollständige Klassenname.) Nehmen Sie außerdem an, dass Sie eine aufgerufene JAR erstellt haben myjar.jar
, die die gesamte Anwendung enthält. Führen Sie MakeJarRunnable
diese JAR-Datei folgendermaßen aus:
java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar
Beachten Sie, wie bereits erwähnt, wie ich die Argumentliste ordne. Wenn Sie die Reihenfolge vergessen haben, führen Sie dieses Programm einfach ohne Argumente aus und es antwortet mit einer Verwendungsnachricht.
Versuchen Sie, das auszuführen
java -jar
Befehl ein
myjar.jar
und dann weiter
myjar_r.jar
. Note the difference! After you've done that, explore the manifest files (
META-INF/MANIFEST.MF
) in each JAR. (You can find both JARs in the
source code
.)
Here's a suggestion: Try to make the MakeJarRunnable
program into a runnable JAR!
Run with it
Running a JAR by double-clicking it or using a simple command is always more convenient than having to include it in your classpath and running a specific main class. To help you do this, the JAR specification provides a Main-Class
attribute for the JAR's manifest file. The program I present here lets you utilize Java's JAR API to easily manipulate this attribute and make your JARs runnable.
Erfahren Sie mehr über dieses Thema
- Laden Sie den Quellcode und die JARs für diesen Tipp herunter
//images.techhive.com/downloads/idge/imported/article/jvw/2002/05/makejarrunnable.zip
- "Java Tip 120Execute Self-Extracting JARs", Z. Steve Jin und John D. Mitchell ( JavaWorld, November 2001)
//www.javaworld.com/javaworld/javatips/jw-javatip120.html
- JAR File Specification
//java.sun.com/j2se/1.3/docs/guide/jar/jar.html
- jar—The Java Archive Tool
//java.sun.com/j2se/1.3/docs/tooldocs/win32/jar.html
- View all previous Java Tips and submit your own
//www.javaworld.com/javatips/jw-javatips.index.html
- Learn Java from the ground up in JavaWorld's Java 101 column
//www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html
- Java experts answer your toughest Java questions in JavaWorld's Java Q&A column
//www.javaworld.com/javaworld/javaqa/javaqa-index.html
- Browse the Core Java section of JavaWorld's Topical Index
//www.javaworld.com/channel_content/jw-core-index.shtml
- Bleiben Sie auf unsere Tipps ‚N Tricks durch zu abonnieren Javaworld‘ kostenlos s wöchentlichen E - Mail - Newsletter
//www.javaworld.com/subscribe
- Lernen Sie die Grundlagen der clientseitige Java in Javaworld‘ s Java Anfänger Diskussion. Zu den Kernthemen gehören die Java-Sprache, die Java Virtual Machine, APIs und Entwicklungstools
//forums.idg.net/[email protected]@.ee6b804
- Unter .net finden Sie eine Fülle von IT-Artikeln aus unseren Schwesterpublikationen
Diese Geschichte "Java-Tipp 127: Siehe JAR-Ausführung" wurde ursprünglich von JavaWorld veröffentlicht.