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