Suche…


Einführung

Der Klassenpfad listet die Bereiche auf, an denen die Java-Laufzeitumgebung nach Klassen und Ressourcen suchen soll. Der Klassenpfad wird auch vom Java-Compiler verwendet, um zuvor kompilierte und externe Abhängigkeiten zu finden.

Bemerkungen

Java-Klasse wird geladen

Die JVM (Java Virtual Machine) lädt Klassen, sobald die Klassen erforderlich sind (dies wird als Lazy-Loading bezeichnet). Die Standorte der zu verwendenden Klassen sind an drei Stellen angegeben: -

  1. Die von der Java-Plattform benötigten werden zuerst geladen, z. B. diejenigen in der Java-Klassenbibliothek und ihre Abhängigkeiten.
  2. Als nächstes werden Erweiterungsklassen geladen (dh die in jre/lib/ext/ )
  3. Benutzerdefinierte Klassen über den Klassenpfad werden dann geladen

Klassen werden mit Klassen geladen, die Untertypen von java.lang.ClassLoader . Dies wurde in diesem Thema ausführlicher beschrieben: Classloader .

Klassenpfad

Der Klassenpfad ist ein Parameter, der von der JVM oder dem Compiler verwendet wird und die Speicherorte benutzerdefinierter Klassen und Pakete angibt. Dies kann wie in den meisten dieser Beispiele in der Befehlszeile oder über eine Umgebungsvariable ( CLASSPATH ) festgelegt werden.

Es gibt verschiedene Möglichkeiten, den Klassenpfad anzugeben

Es gibt drei Möglichkeiten, den Klassenpfad festzulegen.

  1. Es kann mit der Umgebungsvariable CLASSPATH werden:

     set CLASSPATH=...         # Windows and csh
     export CLASSPATH=...      # Unix ksh/bash
    
  2. Sie kann in der Befehlszeile wie folgt festgelegt werden

     java -classpath ...
     javac -classpath ...
    

    Beachten Sie, dass die Option -classpath (oder -cp ) Vorrang vor der Umgebungsvariable CLASSPATH .

  3. Der Klassenpfad für eine ausführbare JAR-Datei wird mit dem Class-Path Element in MANIFEST.MF :

     Class-Path: jar1-name jar2-name directory-name/jar3-name
    

    Beachten Sie, dass dies nur gilt, wenn die JAR-Datei folgendermaßen ausgeführt wird:

     java -jar some.jar ...
    

    In diesem Ausführungsmodus werden die Option -classpath und die Umgebungsvariable CLASSPATH ignoriert, auch wenn die JAR-Datei kein Class-Path Element enthält.

Wenn kein Klassenpfad angegeben ist, ist der Standardklassenpfad bei Verwendung von java -jar die ausgewählte JAR-Datei oder ansonsten das aktuelle Verzeichnis.

Verbunden:

Hinzufügen aller JARs in einem Verzeichnis zum Klassenpfad

Wenn Sie alle JARs im Verzeichnis zum Klassenpfad hinzufügen möchten, können Sie dies mit der Klassenpfad-Platzhaltersyntax auf einfache Weise tun. zum Beispiel:

 someFolder/*

Dadurch wird die JVM someFolder , alle JAR- und ZIP-Dateien im Verzeichnis someFolder zum Klassenpfad hinzuzufügen. Diese Syntax kann in verwendet wird -cp Argument, ein CLASSPATH - Umgebungsvariable oder ein Class-Path - Attribut in einer ausführbaren JAR - Datei Manifest file.See Class Path Wild Cards: Einstellen des Klassenpfades für Beispiele und Einsprüche.

Anmerkungen:

  1. Klassenpfad-Platzhalter wurden erstmals in Java 6 eingeführt. Frühere Versionen von Java behandeln "*" nicht als Platzhalter.
  2. Sie können keine anderen Zeichen vor oder nach dem " " setzen; zB "someFolder / .jar" ist kein Platzhalter.
  3. Ein Platzhalter entspricht nur Dateien mit dem Suffix ".jar" oder ".JAR". ZIP-Dateien werden ignoriert, ebenso wie JAR-Dateien mit anderen Suffixen.
  4. Ein Platzhalter entspricht nur JAR-Dateien im Verzeichnis selbst, nicht in seinen Unterverzeichnissen.
  5. Wenn eine Gruppe von JAR-Dateien mit einem Platzhaltereintrag übereinstimmt, wird ihre relative Reihenfolge im Klassenpfad nicht angegeben.

Klassenpfadpfad-Syntax

Der Klassenpfad ist eine Folge von Einträgen, die Verzeichnispfadnamen, JAR- oder ZIP-Dateipfadnamen oder JAR / ZIP-Platzhalterspezifikationen sind.

  • Für einen in der Befehlszeile angegebenen Klassenpfad (z. B. -classpath ) oder als Umgebungsvariable müssen die Einträge mit ; getrennt werden ; (Semikolon) Zeichen unter Windows oder : (Doppelpunkt) Zeichen auf anderen Plattformen (Linux, UNIX, MacOSX usw.).

  • Verwenden Sie für das Class-Path Element in MANIFEST.MF einer JAR-Datei ein einzelnes Leerzeichen, um die Einträge zu trennen.

Manchmal ist es notwendig, ein Leerzeichen in einen Klassenpfadeintrag einzubetten

  • Wenn der Klassenpfad in der Befehlszeile angegeben wird, müssen Sie lediglich die entsprechenden Shell-Anführungszeichen verwenden. Zum Beispiel:

    export CLASSPATH="/home/user/My JAR Files/foo.jar:second.jar"
    

    (Die Details können von der von Ihnen verwendeten Befehlsshell abhängen.)

  • Wenn der Klassenpfad in einer "MANIFEST.MF" -Datei einer JAR-Datei angegeben ist, muss die URL-Codierung verwendet werden.

     Class-Path: /home/user/My%20JAR%20Files/foo.jar second.jar
    

Dynamischer Klassenpfad

Manchmal reicht es nicht aus, nur alle JARs aus einem Ordner hinzuzufügen, beispielsweise wenn Sie über systemeigenen Code verfügen und eine Untermenge von JARs auswählen müssen. In diesem Fall benötigen Sie zwei main() -Methoden. Die erste erstellt einen Classloader und verwendet dann diesen Classloader, um das zweite main() aufzurufen.

Hier ein Beispiel, in dem Sie die richtige SWT-native JAR für Ihre Plattform auswählen, alle JARs Ihrer Anwendung hinzufügen und dann die echte main() Methode aufrufen: Erstellen Sie plattformübergreifende Java-SWT-Anwendung

Laden Sie eine Ressource aus dem Klassenpfad

Es kann nützlich sein, eine Ressource (Bild, Textdatei, Eigenschaften, KeyStore, ...) zu laden, die sich in einem JAR befindet. Zu diesem Zweck können wir die Class und ClassLoader .

Angenommen, wir haben die folgende Projektstruktur:

program.jar
|
\-com
  \-project
    |
    |-file.txt
    \-Test.class  

Und wir möchten über die Klasse Test auf den Inhalt von file.txt zugreifen. Wir können dies tun, indem wir den Klassenlader fragen:

InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");

Durch die Verwendung des Klassenladers müssen wir den vollständig qualifizierten Pfad unserer Ressource (jedes Paket) angeben.

Alternativ können wir das Klassenobjekt Test direkt abfragen

InputStream is = Test.class.getResourceAsStream("file.txt");

Bei Verwendung des Klassenobjekts ist der Pfad relativ zur Klasse selbst. Test.class unsere Test.class sich im Paket com.project und mit file.txt identisch ist, müssen wir überhaupt keinen Pfad angeben.

Wir können jedoch absolute Pfade aus dem Klassenobjekt verwenden:

 is = Test.class.getResourceAsStream("/com/project/file.txt");

Zuordnung von Klassennamen zu Pfadnamen

Die Standard-Java-Toolchain (und von Drittanbietern für die Interaktion mit ihnen entwickelte Tools) enthält spezielle Regeln für die Zuordnung der Namen von Klassen zu den Pfadnamen von Dateien und anderen Ressourcen, die diese repräsentieren.

Die Zuordnungen sind wie folgt

  • Für Klassen im Standardpaket sind die Pfadnamen einfache Dateinamen.
  • Bei Klassen in einem benannten Paket werden die Komponenten der Paketnamen den Verzeichnissen zugeordnet.
  • Bei benannten verschachtelten und inneren Klassen wird die Dateinamenkomponente gebildet, indem die Klassennamen mit einem $ -Zeichen verbunden werden.
  • Bei anonymen inneren Klassen werden anstelle von Namen Zahlen verwendet.

Dies ist in der folgenden Tabelle dargestellt:

Klassenname Quellpfadname Pfadname der Klassendatei
SomeClass SomeClass.java SomeClass.class
com.example.SomeClass com/example/SomeClass.java com/example/SomeClass.class
SomeClass.Inner (in SomeClass.java ) SomeClass$Inner.class
SomeClass innere Klassen (in SomeClass.java ) SomeClass$1.class , SomeClass$2.class usw

Was der Klassenpfad bedeutet: Wie Suchvorgänge funktionieren

Der Klassenpfad dient dazu, einer JVM mitzuteilen, wo Klassen und andere Ressourcen zu finden sind. Die Bedeutung des Klassenpfads und des Suchprozesses sind miteinander verknüpft.

Der Klassenpfad ist eine Form eines Suchpfads, der eine Abfolge von Positionen angibt, in denen nach Ressourcen gesucht werden soll. In einem Standardklassenpfad sind diese Bereiche entweder ein Verzeichnis im Host-Dateisystem, eine JAR-Datei oder eine ZIP-Datei. In jedem Fall ist der Speicherort der Stamm eines Namespaces , der durchsucht wird.

Das Standardverfahren für die Suche nach einer Klasse im Klassenpfad lautet wie folgt:

  1. Ordnen Sie den Klassennamen einem relativen Klassendateipfad RP . Die Zuordnung von Klassennamen zu Klassendateinamen wird an anderer Stelle beschrieben.

  2. Für jeden Eintrag E im Klassenpfad:

    • Wenn der Eintrag ein Dateisystemverzeichnis ist:
      • Löse RP relativ zu E , um einen absoluten Pfadnamen AP .
      • Testen Sie, ob AP ein Pfad für eine vorhandene Datei ist.
      • Wenn ja, laden Sie die Klasse aus dieser Datei
    • Wenn der Eintrag eine JAR- oder ZIP-Datei ist:
      • Nachschlagen von RP im JAR / ZIP-Dateiindex.
      • Wenn der entsprechende JAR / ZIP-Dateieintrag vorhanden ist, laden Sie die Klasse aus diesem Eintrag.

Das Verfahren zum Suchen einer Ressource im Klassenpfad hängt davon ab, ob der Ressourcenpfad absolut oder relativ ist. Für einen absoluten Ressourcenpfad ist das Verfahren wie oben beschrieben. Bei einem relativen Ressourcenpfad, der mit Class.getResource oder Class.getResourceAsStream , wird der Pfad für das Klassenpaket vor der Suche vorangestellt.

(Beachten Sie, dass dies die Prozeduren sind, die von den standardmäßigen Java-Klassenladern implementiert werden. Ein benutzerdefinierter Klassenlader führt die Suche möglicherweise anders aus.)

Der Bootstrap-Klassenpfad

Die normalen Java-Klassenladeprogramme suchen zuerst im Bootstrap-Klassenpfad nach Klassen, bevor sie nach Erweiterungen und dem Klassenpfad der Anwendung suchen. Der Bootstrap-Klassenpfad besteht standardmäßig aus der Datei "rt.jar" und einigen anderen wichtigen JAR-Dateien, die von der JRE-Installation bereitgestellt werden. Diese enthalten alle Klassen in der Standard-Java SE-Klassenbibliothek sowie verschiedene "interne" Implementierungsklassen.

Unter normalen Umständen müssen Sie sich nicht darum kümmern. Standardmäßig verwenden Befehle wie java , javac usw. die entsprechenden Versionen der Laufzeitbibliotheken.

In bestimmten Fällen ist es erforderlich, das normale Verhalten der Java-Laufzeitumgebung zu überschreiben, indem eine alternative Version einer Klasse in den Standardbibliotheken verwendet wird. Beispielsweise kann es in den Laufzeitbibliotheken zu einem "show stopper" -Fehler kommen, den Sie mit normalen Mitteln nicht umgehen können. In einer solchen Situation ist es möglich, eine JAR-Datei zu erstellen, die die geänderte Klasse enthält, und sie dem Bootstrap-Klassenpfad hinzuzufügen, der die JVM startet.

Der Befehl java bietet die folgenden -X Optionen zum Ändern des Bootstrap-Klassenpfads:

  • -Xbootclasspath:<path> ersetzt den aktuellen Startklassenpfad durch den angegebenen Pfad.
  • -Xbootclasspath/a:<path> hängt den angegebenen Pfad an den aktuellen Startklassenpfad an.
  • -Xbootclasspath/p:<path> fügt den angegebenen Pfad dem aktuellen Startklassenpfad hinzu.

Beachten Sie, dass Sie bei Verwendung der Bootclasspath-Optionen zum Ersetzen oder Überschreiben einer Java-Klasse (usw.) Java technisch modifizieren. Wenn Sie Ihren Code dann verteilen, kann dies Auswirkungen auf die Lizenzierung haben. (Beachten Sie die Bedingungen der Java Binary License ... und wenden Sie sich an einen Anwalt.)



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow