Was ist ein Klassenpfad und wie setze ich ihn?

324

Ich habe gerade diese Zeile gelesen:

Als erstes lädt die format () -Methode eine Velocity-Vorlage aus dem Klassenpfad output.vm

Bitte erläutern Sie, was in diesem Zusammenhang unter Klassenpfad zu verstehen war und wie ich den Klassenpfad festlegen sollte.

Blankman
quelle

Antworten:

530

Wenn Sie in Java programmieren, stellen Sie der Klasse, die Sie schreiben, andere Klassen zur Verfügung, indem Sie Folgendes in Ihre Quelldatei einfügen:

import org.javaguy.coolframework.MyClass;

Oder manchmal "importieren" Sie Sachen, indem Sie sagen:

import org.javaguy.coolframework.*;

Also später in Ihrem Programm, wenn Sie sagen:

MyClass mine = new MyClass();

Die Java Virtual Machine weiß, wo sich Ihre kompilierte Klasse befindet.

Es wäre unpraktisch, wenn die VM jeden Ordner auf Ihrem Computer durchsucht. Daher müssen Sie der VM eine Liste der zu durchsuchenden Stellen bereitstellen. Dazu legen Sie Ordner- und JAR-Dateien in Ihrem Klassenpfad ab.

Bevor wir darüber sprechen, wie der Klassenpfad festgelegt wird, wollen wir uns mit .class-Dateien, Paketen und .jar-Dateien befassen.

Nehmen wir zunächst an, MyClass ist etwas, das Sie als Teil Ihres Projekts erstellt haben, und befindet sich in einem Verzeichnis in Ihrem Projekt mit dem Namen output. Die .class-Datei befindet sich unter output/org/javaguy/coolframework/MyClass.class(zusammen mit jeder anderen Datei in diesem Paket). Um zu dieser Datei zu gelangen, muss Ihr Pfad lediglich den Ordner 'output' enthalten, nicht die gesamte Paketstruktur, da Ihre import-Anweisung alle diese Informationen für die VM bereitstellt.

Nehmen wir nun an, Sie bündeln CoolFramework in einer JAR-Datei und legen diese CoolFramework.jar in einem lib-Verzeichnis in Ihrem Projekt ab. Sie müssten jetzt lib/CoolFramework.jarin Ihren Klassenpfad setzen. Die VM sucht in der JAR-Datei nach dem org/javaguy/coolframeworkTeil und findet Ihre Klasse.

Klassenpfade enthalten also:

  • JAR-Dateien und
  • Pfade an die Spitze der Pakethierarchien.

Wie legen Sie Ihren Klassenpfad fest?

Der erste Weg, den jeder zu lernen scheint, sind Umgebungsvariablen. Auf einem Unix-Computer können Sie Folgendes sagen:

export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/

Auf einem Windows-Computer müssen Sie zu Ihren Umgebungseinstellungen gehen und den bereits vorhandenen Wert hinzufügen oder ändern.

Die zweite Möglichkeit besteht darin, den -cpParameter beim Starten von Java wie folgt zu verwenden :

java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/"  MyMainClass

Eine Variante davon ist der dritte Weg, der häufig mit einer .shoder .bat-Datei durchgeführt wird, die den Klassenpfad berechnet und über den -cpParameter an Java übergibt .

Es gibt ein "Gotcha" mit all dem oben genannten. Auf den meisten Systemen (Linux, Mac OS, UNIX usw.) ist das Doppelpunktzeichen (':') das Klassenpfadtrennzeichen. In WindowsM ist das Trennzeichen das Semikolon (';').

Was ist der beste Weg, dies zu tun?

Das globale Festlegen von Inhalten über Umgebungsvariablen ist schlecht, im Allgemeinen aus den gleichen Gründen, aus denen globale Variablen schlecht sind. Sie ändern die Umgebungsvariable CLASSPATH so, dass ein Programm funktioniert, und am Ende brechen Sie ein anderes Programm.

Das -cp ist der richtige Weg. Im Allgemeinen stelle ich sicher, dass meine CLASSPATH-Umgebungsvariable eine leere Zeichenfolge ist, die ich nach Möglichkeit entwickle, um globale Klassenpfadprobleme zu vermeiden (einige Tools sind jedoch nicht zufrieden, wenn der globale Klassenpfad leer ist - ich kenne zwei häufig vorkommende Mega-Tausend Dollar lizenzierte J2EE- und Java-Server, die solche Probleme mit ihren Befehlszeilentools haben).

Bokmann
quelle
12
Ein weiterer gut erklärter Blog über Was ist PATH und CLASSPATH in Java - Path vs ClassPath
KNU
In Python gibt es einen Ordner namens Lib, in dem Sie jedes Modul speichern können, das Sie jederzeit mit einer einfachen Importanweisung verwenden können. Unterscheidet sich dies vom Festlegen der Umgebungsvariablen CLASSPATH in einem Verzeichnis für Java-Pakete von Drittanbietern? Auch wenn es global wäre, müsste die Variable nicht geändert werden, außer dass weitere Pakete hinzugefügt werden.
Josie Thompson
Schöne Antwort, aber für die Dummies hier draußen: Warum müssen Sie den Befehl -cp nicht für jede neue Klasse verwenden, die Sie erstellen? Dies wird sicherlich automatisch von Ihrem System gelöst, oder? Aber wie? Ich stoße manchmal auf ein Problem, bei dem "etwas" nicht in meinem Klassenpfad gefunden werden kann - ich denke, es ist so, weil ich es nicht zum cp hinzugefügt habe, aber warum tritt ein solcher Fehler nur manchmal statt immer auf? Ich frage dies, weil ich, um ehrlich zu sein, nie etwas manuell in den Befehl -cp aufgenommen habe und nicht wissen würde, was ich mit einem
solchen
2
@Vic Der Klassenpfad muss das Verzeichnis über der Verzeichnishierarchie enthalten, das dem Paketnamen entspricht. Wenn ich also eine org.javaguy.coolfwentsprechende Verzeichnisstruktur hätte /path/to/org/javaguy/coolfw/, müsste der Klassenpfad enthalten /path/to/. Wenn ich org.javaguy.hotfwim selben Projekt ein neues Paket hinzufüge , endet die resultierende Klasse (normalerweise) bei /path/to/org/javaguy/hotfw/. Dies erfordert, dass der Klassenpfad enthält /path/to/, was bereits der Fall ist. Das neue Paket (und die darin enthaltenen Klassen) erfordern also keine neuen Ergänzungen zum Klassenpfad.
Tjalling
@Vic Ein konkreteres Beispiel und eine Erklärung finden Sie unter Beherrschen des Java CLASSPATH (gemäß dem ausgezeichneten Kommentar von KNU )
bis zum
67

Stellen Sie sich das als Javas Antwort auf die Umgebungsvariable PATH vor: Betriebssysteme suchen im PATH nach EXE-Dateien, Java sucht im Klassenpfad nach Klassen und Paketen.

Stephen C.
quelle
13

Der Klassenpfad ist der Pfad, in dem die Java Virtual Machine nach benutzerdefinierten Klassen, Paketen und Ressourcen in Java-Programmen sucht.

In diesem Zusammenhang format()lädt die Methode eine Vorlagendatei aus diesem Pfad.

Desintegr
quelle
5

Der Klassenpfad in diesem Kontext ist genau das, was er im allgemeinen Kontext ist: Überall dort, wo die VM weiß, dass sie zu ladende Klassen und Ressourcen finden kann (z. B. output.vm in Ihrem Fall).

Ich würde verstehen, dass Velocity erwartet, irgendwo in "no package" eine Datei mit dem Namen output.vm zu finden. Dies kann ein JAR, ein regulärer Ordner, ... sein. Das Stammverzeichnis eines der Speicherorte im Klassenpfad der Anwendung.

Romain
quelle
2

Festlegen der CLASSPATH-Systemvariablen

Verwenden Sie diese Befehle unter Windows und UNIX (Bourne-Shell), um die aktuelle CLASSPATH-Variable anzuzeigen: In Windows: C:\> set CLASSPATH In UNIX: % echo $CLASSPATH

Verwenden Sie die folgenden Befehle, um den aktuellen Inhalt der Variablen CLASSPATH zu löschen: Unter Windows: C:\> set CLASSPATH= Unter UNIX: % unset CLASSPATH; export CLASSPATH

Verwenden Sie zum Festlegen der CLASSPATH-Variablen die folgenden Befehle (z. B.): Unter Windows: C:\> set CLASSPATH=C:\users\george\java\classes Unter UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH

lft93ryt
quelle
1
Während diese Befehle für die Arbeit mit Umgebungsvariablen nützlich sein können, beantwortet dies nicht die Frage
Hulk
1

Klassenpfad ist eine Umgebungsvariable des Systems. Die Einstellung dieser Variablen wird verwendet, um dem Java-Compiler das Stammverzeichnis einer beliebigen Pakethierarchie bereitzustellen.

Bimalendu nath
quelle
1

CLASSPATH ist eine Umgebungsvariable (dh globale Variablen des Betriebssystems, die allen Prozessen zur Verfügung stehen), die der Java-Compiler und die Laufzeit zum Auffinden der in einem Java-Programm verwendeten Java-Pakete benötigen. (Warum nicht PACKAGEPATH aufrufen?) Dies ähnelt einer anderen Umgebungsvariablen PATH, die von der CMD-Shell zum Auffinden der ausführbaren Programme verwendet wird.

CLASSPATH kann auf eine der folgenden Arten eingestellt werden:

CLASSPATH can be set permanently in the environment: In Windows, choose control panel  System  Advanced  Environment Variables  choose "System Variables" (for all the users) or "User Variables" (only the currently login user)  choose "Edit" (if CLASSPATH already exists) or "New"  Enter "CLASSPATH" as the variable name  Enter the required directories and JAR files (separated by semicolons) as the value (e.g., ".;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar"). Take note that you need to include the current working directory (denoted by '.') in the CLASSPATH.

To check the current setting of the CLASSPATH, issue the following command:

> SET CLASSPATH

CLASSPATH can be set temporarily for that particular CMD shell session by issuing the following command:

> SET CLASSPATH=.;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar

Instead of using the CLASSPATH environment variable, you can also use the command-line option -classpath or -cp of the javac and java commands, for example,

> java classpath c:\javaproject\classes com.abc.project1.subproject2.MyClass3
Unnati Solanki
quelle
0

Statisches Mitglied einer Klasse kann direkt aufgerufen werden, ohne eine Objektinstanz zu erstellen. Da die Hauptmethode statisch ist, kann Java Virtual Machine sie aufrufen, ohne eine Instanz einer Klasse zu erstellen, die die Hauptmethode enthält, die der Startpunkt des Programms ist.


quelle
0

Für Linux-Benutzer und um zusammenzufassen und zu ergänzen, was andere hier gesagt haben, sollten Sie Folgendes wissen:

  1. $ CLASSPATH ist das, was Java verwendet, um mehrere Verzeichnisse zu durchsuchen, um alle verschiedenen Klassen zu finden, die es für Ihr Skript benötigt (es sei denn, Sie sagen es mit der Überschreibung -cp ausdrücklich anders). Für die Verwendung von -cp müssen Sie alle Verzeichnisse manuell verfolgen und diese Zeile bei jedem Ausführen des Programms kopieren und einfügen (nicht vorzuziehen, IMO).

  2. Das Doppelpunktzeichen (":") trennt die verschiedenen Verzeichnisse. Es gibt nur einen $ CLASSPATH und er enthält alle Verzeichnisse. Wenn Sie also "export CLASSPATH = ...." ausführen, möchten Sie den aktuellen Wert "$ CLASSPATH" einfügen, um ihn anzuhängen. Zum Beispiel:

    export CLASSPATH=.
    export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar

    In der ersten Zeile oben starten Sie CLASSPATH mit nur einem einfachen 'Punkt', der den Pfad zu Ihrem aktuellen Arbeitsverzeichnis darstellt. Wenn Sie Java ausführen, wird im aktuellen Arbeitsverzeichnis (in dem Sie sich befinden) nach Klassen gesucht. In der zweiten Zeile oben erfasst $ CLASSPATH den zuvor eingegebenen Wert (.) Und hängt den Pfad an ein MySQL-Verzeichnis an. Jetzt sucht Java nach dem Treiber UND nach Ihren Klassen.

  3. echo $CLASSPATH

    ist sehr praktisch, und was zurückgegeben wird, sollte wie eine durch Doppelpunkte getrennte Liste aller Verzeichnisse und JAR-Dateien gelesen werden. Sie möchten, dass Java nach den benötigten Klassen sucht.

  4. Tomcat verwendet CLASSPATH nicht. Lesen Sie hier, was Sie dagegen tun müssen: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Adam Winter
quelle