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.classist mitkompiliert worden! - Aber
Pythagoras.classist 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