Wo die JVM die Klassen findet muss ihr mitgeteilt werden, und das ist in der Praxis elementar für die Auslieferung, auch englisch Deloyment genannt. Java wartet mit dem Laden der Klassen so lange, bis sie benötigt werden. Es gibt zum Beispiel Programmabläufe nur zu besonderen Bedingungen und wenn dann erst spät ein neuer Typ referenziert wird, der nicht vorhanden ist, fällt dieser Fehler erst sehr spät auf. Der JVM müssen folglich nicht nur die Quellen für Klassen und Ressourcen der eigenen Applikation mitgeteilt werden, sondern alle vom Programm referenzierten Typen aus zum Beispiel quelloffenen und kommerziellen Bibliotheken.
Sollen in einem Java-Projekt Dateien aus einem Verzeichnis oder einem externen Java-Archiv geholt werden, so ist der übliche Weg, diese Verzeichnisse oder Archive in einem Klassenpfad anzugeben. Diese Angabe ist für alle SDK-Werkzeuge notwendig – am Häufigsten ist sie beim Compiler und bei der Laufzeitumgebung zu sehen.
Schalter -classpath
Die Suchorte lassen sich flexibel angeben, wobei die erste Variante einem SDK-Werkzeug über den Schalter -classpath (kurz -cp) die Klassendateien bzw. Archive liefert:
$ java -classpath classpath1;classpath2 MainClass
Der Klassenpfad enthält Wurzelverzeichnisse der Pakete und JAR-Dateien, also Archive von Klassendateien und Ressourcen.
Beispiel: Nimm ein Java-Archiv library.jar im aktuellen Verzeichnis, die Ressourcen unter dem bin-Verzeichnis und alle JAR-Dateien im Verzeichnis lib in den Klassenpfad mit auf:
$ java -cp "library.jar;bin/.;lib/*" com.tutego.MainClass
Unter Windows ist der Trenner ein Semikolon, unter Unix ein Doppelpunkt! Das Sternchen steht für alle JAR-Dateien, es ist kein üblicher Wildcard, wie z.B. parser*.jar.[1] Sehen Kommandozeilen der Betriebssysteme ein *, beginnen sie in der Regel eine eigenen Verarbeitung; daher muss die gesamte Pfadangabe in doppelten Anführungszeichen stehen.
Umgebungsvariable CLASSPATH
Eine Alternative zum Schalter -cp ist das Setzen der Umgebungsvariablen CLASSPATH mit einer Zeichenfolge, die Pfadangaben spezifiziert:
$ SET CLASSPATH=classpath1;classpath2 $ java MainClass
Problematisch ist der globale Charakter der Variablen, sodass lokale -cp-Angaben besser sind. Außerdem „überschreiben“ die -cp-Optionen die Einträge in CLASSPATH. Zu guter Letzt: ist weder CLASSPATH noch eine -cp-Option gesetzt, besteht der Klassenpfad für die JVM nur aus dem aktuellen Verzeichnis, also „.“.
[1] Weitere Details unter https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html.
Danke für einen anschaulichen Artikel. Vielleicht ist es etwas zu viel des Guten, die Fachbegriffe alle zu übersetzen. Klassenpfad klingt schon etwas seltsam.
Naja, wenn es selbst schon ein Wikipedia-Betrag dazu existiert, ist das zumindest nicht so weit hergeholt: https://de.wikipedia.org/wiki/Klassenpfad.