Vorlesung „Programmieren“ Java: Packages, Classpath, JARs Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer Packages Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer Probleme großer Projekte • Programme können aus vielen Klassen bestehen – Verschiedene logische Funktionskomponenten – Müssen nicht von einem Hersteller bzw. Programmierer stammen – Normalerweise besteht ein Programm aus Teilen vieler Programmierer (externe Bibliotheken, Teams, ...) • Probleme – Klassennamen doppelt vergeben Eindeutigkeit – Unklare Zuordnung Funktionseinheit ↔ Klasse Beispiel: Zwei „Punkt“-Klassen Security - 04 Cryptology #4 Beispiel: Zwei „Punkt“-Klassen • Wie unterscheidet man die beiden Klassen im gleichen Programm? • Eine Möglichkeit: umbenennen – „PunktRGB“ und „PunktKoordinate“ – Macht Programme oft schlechter lesbar (lange Namen) • Beispiele (Windows API, Ungarische Notation) – RtlWriteDecodedUcsDataIntoSmartLBlobUcsWritingContext – ConvertSecurityDescriptorToStringSecurityDescriptor – EapHostPeerQueryUIBlobFromInteractiveUIInputFields – AccessCheckByTypeResultListAndAuditAlarmByHandle – SetupRemoveInstallSectionFromDiskSpaceList Security - 04 Cryptology #5 Namensräume • Alternative zu langen Namen • Eingruppieren von Klassen in verschiedene Namensräumen – Unterscheidung von Klassen durch Angabe des Namensraums – Beispiel: Punkt aus „Farbe“ vs. Punkt aus „Mathe“ • Namensräume in Java: sog. „packages“ Namensraum „Farbe“ Namensraum „Mathe“ Punkt Punkt Attribute: int rot; int gruen; int blau Attribute: double x; double y; Methoden: void setze(double x, double y); void verschiebe(double dx, double dy); void rotiere(double radians); Methoden: Security - 04 Cryptology #6 Packages • Es ist üblich, Klassen in Packages zu gruppieren – Bessere Übersichtlichkeit – Vorbeugung von Namenskonflikten – Zusammengehörige Klassen kennzeichnen • Analogie – Klassennamen sind vergleichbar mit einem Vornamen – Package-Name entspräche dann dem Familiennamen • Package-Namen: Gleiche Einschränkungen wie Identifier – z.B. kein „-“ erlaubt – Konvention: Kleinschreibung (also „mathe“ statt „Mathe“) Packages: Beispiel Security - 04 Cryptology #8 Nested Namespaces • Namespaces können auch ineinander geschachtelt werden • Beispiel – – – – Punkt in „Farbe“ Punkt in „rgb“ in „Farbe“ Punkt in „version1“ in „rgb“ in „Farbe“ Punkt in „cmyk“ in „Farbe“ Namensraum „Farbe“ Punkt Namensraum „rgb“ Namensraum „cmyk“ Namensraum „version1“ Punkt Punkt Punkt Security - 04 Cryptology #9 Nested Namespaces: Java Beispiel • Einzelne Bestandteile werden durch „.“ getrennt • Beginnt bei der höchsten Hierarchiestufe – Ähnlich wie im Dateisystem – Packages müssen immer „absolut“ angegeben werden (d.h. alle Namensteile müssen vorhanden sein) Security - 04 Cryptology Packages: Namenswahl • Sinnvoll: Weltweit eindeutige Namen – Üblich sind Internet-Domainnamen in umgekehrter Schreibweise – Damit man Klassen aus verschiedenen Quellen ohne Namenskonflikte nutzen kann • Beispiel: Klassen aus dem ITM – Domainname: itm.uni-luebeck.de – Package de.uni_luebeck.itm (Verwendung von „_“ statt „-“) – Sinnvoll: Anhängen des Projektnames (z.B. „programmieren.ws1213.uebung1.aufgabe2“) – Gesamt: de.uni_luebeck.itm.programmieren.ws1213.uebung1.aufgabe2; Packages: Dateisystem und Packages • Java-Dateien müssen im Dateisystem so abgelegt sein, dass deren Pfade die Package-Namen widerspiegeln • Beispiele für verschiedene Punkt-Klassen (alle jeweils in „Punkt.java“) – Im folgenden angenommen: Projektverzeichnis ist ~/coding/aufgabe2 – package farbe; – package farbe.rgb; – package farbe.rgb.version1; – package farbe.cmyk; – package mathe; – package de.uni_luebeck.itm. programmieren.ws1213.uebung1.aufgabe2; • • • • • • ~/coding/aufgabe2/farbe/Punkt.java ~/coding/aufgabe2/farbe/rgb/Punkt.java ~/coding/aufgabe2/farbe/rgb/version1/Punkt.java ~/coding/aufgabe2/farbe/cmyk/Punkt.java ~/coding/aufgabe2/mathe/Punkt.java ~/coding/aufgabe2/de/uni_luebeck/itm/programmieren/ws1213/uebung1/aufgabe2/Punkt.java #10 Packages: Verwendung • Zwei Varianten zur Verwendung von Klassen aus anderen Packages • Angabe des voll-qualifizierten Namens (Klasse + Package) – package test; ... farbe.rgb.Punkt p = new farbe.rgb.Punkt(); • Importieren bestimmter Klassennamen – Um die Angabe des voll-qualifizierten zu ersparen (Lesbarkeit) – Schlüsselwort: import – import farbe.rgb.Punkt; ... Punkt p = new Punkt(); 5-3-13 Packages: Verwendung • Kann natürlich auch gemischt verwendet werden • Beispiel – package test; import farbe.rgb.Punkt; ... Punkt p1 = new Punkt(); farbe.cmyk.Punkt p2 = new farbe.cmyk.Punkt(); farbe.rgb.version1.Punkt p3 = new farbe.rgb.version1.Punkt(); • Es sind nach wie vor verschiedene Klassen – Punkt p1 = new farbe.cmyk.Punkt(); //Fehler!!! 5-3-14 Packages: Verwendung • Alternative Variante von import – Importieren ganzer Packages (z.B. import java.util.*;) – Alle Namen aus java.util können ohne Angabe des Packages verwendet werden – Gilt nicht für eventuelle Unterpackages von java.util • Wo/wann benutzt man Packages? – In allen größeren Java-Projekten – Intensiv in der Java-API: http://download.oracle.com/javase/7/docs/api/ (hier sollten sich Java-Programmierer gut auskennen) • In Java ist java.lang.*; implizit immer importiert – Daher kann man auch System.out.println(...); statt java.lang.System.out.println(...); schreiben Klassen ohne Package • In welchem Package waren eigentlich unsere bisherigen Klassen? • Kein Package: sog. default Package – Quasi ein Package ohne Namen – Daher liegen diese auch im Wurzelverzeichnis des Projekts – Sollte man nur bei ganz kleinen Projekten nutzen Security - 04 Cryptology Classpath Motivation • Programme können aus vielen Klassen bestehen – Eigene Klassen im Projektverzeichnis – Von Java mitgelieferte Klassen (z.B. System, String, ...) – Klassen von Drittanbietern – ... • Woher wissen Compiler und VM, wo die Klassen sind? – Standard: Suche nur im Java-Installationsverzeichnis und im aktuellen Verzeichnis • Wie funktioniert das mit Packages und wenn nicht alle Klassen im selben Verzeichnis liegen? – Es müssen ggf. auch andere Verzeichnisse in die Suche einbezogen werden #16 Lösung: Java Classpath • Über den Classpath kann man dem Compiler verschiedene „Startpunkte“ für die Suche mitteilen – Von diesen aus sucht Java nach Klassen in verschiedenen Packages – Das heißt, dass das Programm über viele Orte „zerstreut“ sein kann • Verschiedene Möglichkeiten – Standardverhalten – Umgebungsvariable CLASSPATH – Kommandozeilenparameter Security - 04 Cryptology Die Umgebungsvariable CLASSPATH • Angabe aller Suchpfade in der Umgebungsvariablen CLASSPATH • Windows – Start | Einstellungen | Systemsteuerung | System | Erweitert | Umgebungsvariablen – Mehrere Pfade mit ; getrennt auflisten – Wert der Variablen: .;C:\pfad1\javafiles;D:\pfad2\irgendwo;… • Linux/Unix – Mehrere Pfade mit : getrennt auflisten – export CLASSPATH=.:/pfad1/javafiles:/pfad2/irgendwo:... (in ~/.bashrc, ~/.profile, ~/bash_profile oder sonstwo) Angabe des Classpath als Argument • Classpath als Kommandozeilenargument übergeben – Die Umgebungsvariable CLASSPATH wird dann ignoriert • Auch javac unterstützt „-cp“ und $CLASSPATH – javac übersetzt die angegebenen .java-Dateien – Classpath wird lediglich zum Einbinden von bereits compilierten Klassen genutzt Windows: C:>java –cp .;C:\pfad1\javafiles;D:\pfad2\irgendwo;… PKWTest Linux: nutzer@itm:~$ java –cp .:/pfad1/javafiles:/pfad2/irgendwo:… PKWTest #19 Beispiel • Angenommen, wir haben 3 Teams – • • • Eins für die farbigen Punkte, eins für die math. Punkte, eins für das Hauptprogramm Jedes Team entwickelt in eigenem Ordner – Team 1: Punkt (Package „mathe“, Ordner „team1“) – Team 2: Punkt (Package „farbe“, Ordner „team2“) – Team 1: Main (Package „hauptprogramm“, Ordner „team3“) Wie übersetzt man das Programm? – Angabe aller Java-Dateien des Programms: javac team1\mathe\Punkt.java team2\farbe\Punkt.java team3\hauptprogramm\Main.java – Funktioniert, weil wir nicht andere, bereits compilierte Klassen verwenden Wie startet man das Programm? – Nächste Folie Wie es nicht geht... Security - 04 Cryptology #23 Besser: Angabe des korrekten Classpath • Startpunkt der Suchpfade: team1, team2 und team3 – Angabe entweder relativ zum aktuellen Verzeichnis oder absolut – Hier: relativ Security - 04 Cryptology #24 Informationen zum Classloading • Mit dem Parameter „-verbose:class“ gibt Java beim Starten aus, welche Klassen er von wo lädt • Beispiel: java -verbose:class -cp team1;team2;team3 hauptprogramm.Main Security - 04 Cryptology #25 Exkurs: „Classloading“ in C • Auch in anderen Programmiersprachen ist das Nachladen normal – Zentrale Updates, Speicherplatzeffizienz, etc. • Beispiel: Einfaches C Programm Exkurs: „Classloading“ in C Compilieren und linken in ausführbare Datei Abhängigkeiten anzeigen Ausführen • Zeigt zur Laufzeit in den Addressbereich des Programms „gemappte“ Libraries – Unter Windows: „.dll“, unter Linux/Unix: „.so“ JAR Dateien JAR Dateien - Motivation • Java-Programme bestehen aus vielen Klassen – Jede Klasse hat ein eigenes „.class“-File – Programme bestehen aus vielen Ordnern und Dateien – Ausliefern: Zippen, versenden, dort wieder entpacken und starten • Einfacher: Class-Dateien in JAR-Archiv zusammenfassen – JAR: Java Archive – Im JDK enthalten ist ein Programm namens „jar“ zum Anzeigen, Packen und Entpacken von Jar-Dateien • JAR-Dateien können direkt in den Classpath eingebunden werden – Keine Notwendigkeit, JAR-Dateien vor Verwendung auszupacken „jar“-Tool: Verwendung JAR Dateien - Erzeugen • Angabe aller .class Dateien – jar cvf jarfilename.jar Datei1.class ... DateiN.class • Beispiel: 3 Jars erzeugen (1 pro Team) JAR Dateien - Erzeugen • Anstelle einzelner Dateien können Verzeichnisse angegeben werden – jar cvf jarfile.jar verzeichnis • Vorsicht: Alle Dateien (auch .java Dateien werden hinzugefügt) – Nicht sinnvoll, wenn der Source-Code geheim bleiben soll – Häufig werden getrennte Jar-Dateien ausgeliefert (Source-Jar, Binary-Jar) JAR Dateien – Inhalt anzeigen • Mittels jar: jar tf jarfile.jar • JAR-Dateien sind normale Zip-Dateien – Können mit allen Zip-Tools bearbeitet werden JAR Dateien mit ZIP-Tool anzeigen JAR-Dateien verwenden • Können in Classpath aufgenommen werden – java –cp team1.jar;team2.jar;team3.jar hauptprogramm.Main • Müssen dazu nicht entpackt werden Wie bekommt man alle Klassen in ein Jar? • Problem: Man muss die Klassen mit dem richtigen Pfad ins JAR-File bekommen • Möglichkeit: jar cvf programm.jar team1 team2 team3 – Funktioniert nicht team1, team2, team3 sind nicht Teil der Packagenamen Security - 04 Cryptology #36 Wie bekommt man alle Klassen in ein Jar? • Alternative: Erzeugen und subsequentes Aktualisieren eines Jar-Files • Erzeugen des Jar-Files – jar cvf programm.jar -C team1 mathe/Punkt.class • „-C team1“ wechselt in das Verzeichnis vor dem Suche und Hinzufügen – jar uvf programm.jar -C team2 farbe/Punkt.class • „u“ statt „c“: Update des Files anstelle von Create – jar uvf programm.jar -C team3 hauptprogramm/Main.class Security - 04 Cryptology JAR-Dateien verwenden • Zum Starten von JavaAnwendungen muss man den Namen der Hauptklasse kennen – Also der mit der main-Methode – Sehr unschön für Anwender • In Jar-Dateien kann diese Angabe direkt integriert werden – Über die sogenannte Manifest Datei (MANIFEST.MF) – Damit wird die JAR-Datei direkt ausführbar JAR-Dateien verwenden: Manifest • Manifest-Datei mit folgendem Inhalt erstellen: – Main-Class: voller.name.der.Klasse • Beispiel – Main-Class: hauptprogramm.Main • Dazu legt man eine Datei an, die das Manifest enthält – Beispiel: manifest.txt – Inhalt: „Main-Class: hauptprogramm.Main“ (Enter danach nicht vergessen) • Als Jar verpacken: – jar cvmf manifest.txt jardatei.jar <klassen> Reihenfolge von m und f ist wichtig! #37 Manifest: Beispiel • jar cvmf manifest.txt programm.jar -C team1 mathe/Punkt.class • jar uvf programm.jar -C team2 farbe/Punkt.class • jar uvf programm.jar -C team3 hauptprogramm/Main.class „Ausführen“ einer Jar-Datei Security - 04 Cryptology #41 Manifest • Die Manifest-Datei kann noch einiges mehr – z.B. den Classpath der Anwendung setzen – ... • Weitere Informationen zum Manifest – http://docs.oracle.com/javase/tutorial/deployment /jar/manifestindex.html Security - 04 Cryptology #42 Zusammenfassung • Mit Packages kann man die Anwendung besser strukturieren – Vermeidet Namenskonflikte – Erlaubt prägnantere Namen – Gruppiert zusammengehörige Klassen • Classpath bestimmt Suchpfad für Java – Mehrere Möglichkeiten (Default, Umgebungsvariable, Kommandozeilenparameter, Manifest-Datei) • Jar-Dateien – Erlaubt zusammenfassen einer Anwendung oder eines Teils (z.B. Library) zu einer Datei – Können Teil des Classpath sein – Können über Manifest-Datei weitere Angaben zum Programm enthalten (z.B. die Hauptklasse) Security - 04 Cryptology #43