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.jarmit JAR-Dateien arbeiten. (Hinweis: Es baut auf dem java.util.zipPaket auf.) Insbesondere mit dem JAR-Paket können Sie diese spezielle Manifestdatei einfach über die ManifestKlasse bearbeiten.

Schreiben wir ein Programm, das diese API verwendet. Erstens muss dieses Programm drei Dinge wissen:

  1. Das JAR möchten wir lauffähig machen
  2. Die Hauptklasse, die wir ausführen möchten (diese Klasse muss in der JAR vorhanden sein)
  3. 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 MakeJarRunnableklingt 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-ClassEintrag 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-Classin 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 JarOutputStreamKlasse 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 mainMethode, 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 MakeJarRunnablediese 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.

Shawn Silverman ist derzeit ein Doktorand in der Abteilung für Elektro- und Computertechnik an der Universität von Manitoba in Kanada. Er begann Mitte 1996 mit Java zu arbeiten und verwendet es seitdem fast ausschließlich. Zu seinen aktuellen Interessen gehören die Simulation elektrischer Felder und Flüssigkeiten, Fehlerkorrekturcodes und die Implementierung von raffinierten GUI-Tricks (Graphical User Interface). Shawn unterrichtet auch einen Software-Design-Kurs im dritten Jahr in der Abteilung für Computertechnik an seiner Universität.

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.