jar-Bibliotheken

**This is an old revision of the document!**

jar-Bibliotheken

Ausgangslage

 Mode                 LastWriteTime         Length Name


----
-a---l        19.01.2025     13:24            216 Greeter.java -a---l        19.01.2025     13:24            283 Main.java -a---l        19.01.2025     13:38            370 Pythagoras.java 

Kompilieren wir einfach mal Pythagoras.java.

>>javac Pythagoras.java
>>
>

Mode                 LastWriteTime         Length Name


----
-a---l        19.01.2025     13:24            216 Greeter.java -a---l        19.01.2025     13:24            283 Main.java -a---l        19.01.2025     13:38            453 Pythagoras.class -a---l        19.01.2025     13:38            370 Pythagoras.java 

Man sieht, dass ohne Probleme Pythagoras.class entsteht. Da kann man auch mal reinschaun - obwohl es erstmal nicht so super hilfreich ist.

>>cat Pythogoras.class javap -c Pythagoras 

Was nicht klappt: Das Ausführen der class-Datei:

>>java Pythagoras
>>
>

Fehler: Hauptmethode in Klasse Pythagoras nicht gefunden. Definieren Sie die Hauptmethode als: public static void main(String[] args): oder eine JavaFX-Anwendung muss javafx.application.Application erweitern 

Kompilieren der main

Es fehlt eine main - also schnell Main.java kompilieren

>>javac Main.java
>>
>

Mode                 LastWriteTime         Length Name


----
-a---l        19.01.2025     13:48            915 Greeter.class -a---l        19.01.2025     13:24            216 Greeter.java -a---l        19.01.2025     13:48            643 Main.class -a---l        19.01.2025     13:48            285 Main.java -a---l        19.01.2025     13:38            453 Pythagoras.class -a---l        19.01.2025     13:38            370 Pythagoras.java 

Spannend

  • Auch Greeeter.class ist mitkompiliert worden!
  • Aber Pythagoras.class ist NICHT nochmal kompiliert worden (s. Zeitstempel)

Kompilieren von java und class-Files

Was, wenn einige Dateien nicht als .java vorliegen?

Um das zu simulieren, verschieben wir ein paar java-files in den Ordner temp

>>>>>>mkdir temp mv Pythagoras.java temp mv Greeter.java temp rm Main.class 

… und kompilieren dann Main.java.

>>javac Main.java
>>
>

Mode                 LastWriteTime         Length Name


----
dar--l        19.01.2025     13:58                temp -a---l        19.01.2025     13:48            915 Greeter.class -a---l        19.01.2025     13:48            285 Main.java -a---l        19.01.2025     13:38            453 Pythagoras.class 

Kompilieren ist trotzdem möglich!

Compiler ist sogar happy über bereits fertig kompilierte Klassen.

>>javac Main.java
>>
>

Mode                 LastWriteTime         Length Name


----
dar--l        19.01.2025     13:58                temp -a---l        19.01.2025     13:48            915 Greeter.class -a---l        19.01.2025     13:59            643 Main.class -a---l        19.01.2025     13:48            285 Main.java -a---l        19.01.2025     13:38            453 Pythagoras.class 

Das ist sogar der Klassiker: Man schreibt eigenen Java-Code, der von bereits fertig kompilierten Klassen abhängig ist

Meist liegen diese fertigen Dateien irgendwo, bsp im Ordner classes

>>rm Main.class mkdir classes mv *.class classes 

ClassPath angeben mit -cp

Aber jetzt funktioniert das kompilieren von Main.java nicht mehr, weil die Klassen nicht gefunden werden.

>>javac Main.java 

Deshalb muss ich dem Compiler erstmal sagen, wo sich die Klassendateien befinden. Hierfür benutzt man die -cp Option (**Class Path).

>>javac -cp classes Main.java 

Aber man kann es immer noch nicht ausführen!

>>java Main 

Es muss auch hier wieder der classPath angegeben werden…

>>java -cp classes Main Fehler: Hauptklasse Main konnte nicht gefunden oder geladen werden Ursache: java.lang.ClassNotFoundException: Main 

… und der classPath muss angepasst werden und durch ; (Windows) um das aktülle Verzeichnis erweitert werden.

Vorsicht\ Die Erweiterung wird je nach Betriebssystem und Terminal unterschiedlich angegeben. Im Fall von PowerShell verwenden wir das ;. Auch muss der Pfad von Hochkommata " umschlossen werden.\ Unter Linux ist es schlicht ein Punkt .

>>java -cp ".;classes" Main 5.0 4.76837158203125 Donald says: Hello World 

Classfiles im Archiv .jar (java archive)

Classfiles werden meist nicht einzeln verteilt, sondern gepackt als Archiv.

>>cd classes ... jar cvf library.jar *.class Manifest wurde hinzugefügt Greeter.class wird hinzugefügt(ein = 915) (aus = 498)(45 % verkleinert) Pythagoras.class wird hinzugefügt(ein = 453) (aus = 323)(28 % verkleinert) ... Mode                 LastWriteTime         Length Name
>>
>


----
-a---l        19.01.2025     13:48            915 Greeter.class -a---l        19.01.2025     14:28           1386 library.jar -a---l        19.01.2025     13:38            453 Pythagoras.class 

Mit jar tvf kann man auch in ein .jar hineingucken.

>>jar tvf .\library.jar 0 Sun Jan 19 14:28:38 CET 2025 META-INF/ 66 Sun Jan 19 14:28:38 CET 2025 META-INF/MANIFEST.MF 915 Sun Jan 19 13:48:16 CET 2025 Greeter.class 453 Sun Jan 19 13:38:28 CET 2025 Pythagoras.class 

Wir knnen jetzt auch alle .class-files löschen und trotzdem wird der Compiler funktionieren:

>>rm *.class cd .. rm *.class 

>>javac -cp classes\library.jar Main.java java -cp ".;classes\library.jar" Main
>>
>

5.0 4.76837158203125 Donald says: Hello World 

jar-Bibliothek für gesamtes Programm

Wie wäre es aber nun, wenn wir das fertige Produkt inklusive der main in solch einer jar-Bibliothek verpacken? So hätten wir doch nur 1 File, das wir problemlos weitergeben könnten?\ Antwort lautet: Genau - so machen wir es auch!

Also, hier nochmal die Ausgangslage: Alle java-Files liegen in einem Ordner

 Mode                 LastWriteTime         Length Name


----
-a---l        19.01.2025     13:24            216 Greeter.java -a---l        19.01.2025     13:24            283 Main.java -a---l        19.01.2025     13:38            370 Pythagoras.java 

Mit javac Main.java wird alles kompiliert - als Ergebnis haben wir alle class-Files.

 Mode                 LastWriteTime         Length Name


----
-a---l        19.01.2025     19:39            915 Greeter.class -a---l        19.01.2025     13:24            216 Greeter.java -a---l        19.01.2025     19:39            643 Main.class -a---l        19.01.2025     13:48            285 Main.java -a---l        19.01.2025     19:43             18 manifest.txt -a---l        19.01.2025     19:39            453 Pythagoras.class -a---l        19.01.2025     13:38            370 Pythagoras.java 

Was hat es mit dieser manifest.txt auf sich?

Werfen wir einen kurzen Blick hinein:

>>cat manifest.txt Main-Class: Main 

In diesem File ist einfach nur definiert, in welcher Klasse sich die main-Methode des gesamten Programms befindet.

Tipp: Am Ende der Zeile muss ein Zeilenumbruch stehen. Ist er nicht da, suchst du dich dumm und dämlich…

Erstellung eines jar-Files

Jetz erstellen wir daraus ein jar-File. Nennen wir es super.jar

>>jar cvfm super.jar manifest.txt *.class
>>
>

Manifest wurde hinzugefügt Greeter.class wird hinzugefügt(ein = 915) (aus = 498)(45 % verkleinert) Main.class wird hinzugefügt(ein = 643) (aus = 442)(31 % verkleinert) Pythagoras.class wird hinzugefügt(ein = 453) (aus = 323)(28 % verkleinert) 

Ausführen der jar

>>java -jar super.jar 5.0 4.76837158203125 Donald says: Hello World 

Und am Ende nochmal einen Blick ins jar:

>>jar tvf super.jar
>>
>


   0 Sun Jan 19 19:53:40 CET 2025 META-INF/
  66 Sun Jan 19 19:53:40 CET 2025 META-INF/MANIFEST.MF
  
915 Sun Jan 19 19:39:56 CET 2025 Greeter.class 643 Sun Jan 19 19:39:56 CET 2025 Main.class 453 Sun Jan 19 19:39:56 CET 2025 Pythagoras.class