Ein häufiges Problem, mit dem neue Java-Entwickler konfrontiert werden, besteht darin, dass ihre Programme mit der Fehlermeldung nicht ausgeführt werden können: Konnte die Hauptklasse nicht finden oder laden ...
Was bedeutet das, was ist die Ursache und wie kann man das Problem beheben?
java <class-name>
Zunächst müssen Sie verstehen, wie man ein Programm mit dem Befehl java
(oder javaw
) korrekt startet.
Die normale Syntax1 ist diese:
java [ <option> ... ] <class-name> [<argument> ...]
wobei <option>
eine Kommandozeilenoption ist (beginnend mit einem "-" Zeichen), <class-name>
ein voll qualifizierter Java-Klassenname ist und <argument>
ein beliebiges Kommandozeilenargument ist, das an Ihre Anwendung übergeben wird.
1 - Es gibt eine zweite Syntax für "ausführbare" JAR-Dateien, die ich unten beschreiben werde.
Der vollqualifizierte Name (FQN) für die Klasse wird üblicherweise so geschrieben, wie man es im Java-Quellcode tun würde; z.B.
packagename.packagename2.packagename3.ClassName
Einige Versionen des java
-Befehls erlauben jedoch die Verwendung von Schrägstrichen anstelle von Punkten, z.B.
packagename/packagename2/packagename3/ClassName
was (verwirrenderweise) wie ein Dateipfadname aussieht, aber keiner ist. Beachten Sie, dass der Begriff voll qualifizierter Name Standard-Java-Terminologie ist ... nicht etwas, das ich mir nur ausgedacht habe, um Sie zu verwirren :-)
Hier ist ein Beispiel dafür, wie ein java
-Befehl aussehen sollte:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Der obige Befehl veranlasst den java
-Befehl, folgendes zu tun:
main
Methode mit Signatur, Rückgabetyp und Modifikatoren hat, die durch public static void main(String[])
angegeben werden. (Beachten Sie, dass der Name des Methodenarguments NICHT Teil der Signatur ist).String[]
.
Gründe, warum Java die Klasse nicht finden kannjava
war nicht in der Lage, die Klasse zu finden. Und tatsächlich ist das "..." in der Meldung der voll qualifizierte Klassenname, nach dem java
sucht.
Warum also kann die Klasse nicht gefunden werden?Die erste wahrscheinliche Ursache ist, dass Sie den falschen Klassennamen angegeben haben. (Oder ... den richtigen Klassennamen, aber in der falschen Form.) In Anbetracht des obigen Beispiels gibt es eine Reihe von falschen Möglichkeiten, den Klassennamen anzugeben:
Beispiel #1 - ein einfacher Klassenname:
java ListUser
Wenn die Klasse in einem Paket wie com.acme.example
deklariert ist, dann müssen Sie den vollständigen Klassennamen einschließlich des Paketnamens im java
-Befehl verwenden; z.B.
java com.acme.example.ListUser
Beispiel #2 - ein Dateiname oder Pfadname anstelle eines Klassennamens: java ListUser.class java com/acme/example/ListUser.class
Beispiel Nr. 3 - ein Klassenname mit falscher Schreibweise: java com.acme.example.listuser
Beispiel #4 - ein Tippfehler java com.acme.example.mistuser
Beispiel #5 - ein Quelldateiname java ListUser.java
Die zweite wahrscheinliche Ursache ist, dass der Klassenname korrekt ist, aber der Befehl java
die Klasse nicht finden kann. Um dies zu verstehen, müssen Sie das Konzept des "Klassenpfads" verstehen. Dies wird in der Oracle-Dokumentation gut erklärt:
Das Java-Tutorial - PATH und CLASSPATH Also ... wenn Sie den Klassennamen korrekt angegeben haben, müssen Sie als Nächstes prüfen, ob Sie den Klassenpfad korrekt angegeben haben:
java
ausführen. Überprüfen Sie, ob die Namen der Verzeichnisse und JAR-Dateien korrekt sind.java
-Befehls in Kraft ist.;
unter Windows und :
unter den anderen. Wenn Sie das falsche Trennzeichen für Ihre Plattform verwenden, werden Sie keine explizite Fehlermeldung erhalten. Stattdessen erhalten Sie eine nicht existierende Datei oder ein nicht existierendes Verzeichnis im Pfad, das stillschweigend ignoriert wird).
Grund #2a - das falsche Verzeichnis befindet sich auf dem KlassenpfadWenn Sie ein Verzeichnis auf den Klassenpfad setzen, entspricht es fiktiv der Wurzel des qualifizierten Namensraums. Die Klassen befinden sich in der Verzeichnisstruktur unterhalb dieser Wurzel, durch Abbildung des voll qualifizierten Namens auf einen Pfadnamen. Wenn beispielsweise "/usr/local/acme/classes" im Klassenpfad liegt, sucht die JVM bei der Suche nach einer Klasse namens com.acme.example.Foon
nach einer ".class" Datei mit diesem Pfadnamen:
/usr/local/acme/classes/com/acme/example/Foon.class
Wenn der FQN Ihrer Klasse com.acme.example.Foon
lautet, dann sucht die JVM nach "Foon.class" im Verzeichnis "com/acme/example":
/usr/local/acme/classes/com/acme/example/Foon.class
,/usr/local/acme/classes/com/acme/example/
,
dann:# wrong, FQN is needed
java Foon
# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon
# wrong, similar to above
java -classpath . com.acme.example.Foon
# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
Hinweise:
Die Option -classpath
kann in den meisten Java-Versionen zu -cp
abgekürzt werden. Prüfen Sie die entsprechenden Handbucheinträge für java
, javac
und so weiter.
Der Klassenpfad muss alle anderen (Nicht-System) Klassen enthalten, von denen Ihre Anwendung abhängt. (Die Systemklassen werden automatisch gefunden, und Sie müssen sich selten darum kümmern). Damit die Hauptklasse korrekt geladen werden kann, muss die JVM diese finden:
die Klasse selbst.
alle Klassen und Schnittstellen in der Oberklassenhierarchie (siehe z.B. https://stackoverflow.com/questions/42880748)
Paket
-Deklaration auslässt. Wenn Sie dies in einer IDE tun, wird der IDE-Compiler Sie sofort darauf hinweisen. Wenn Sie ein anständiges Java-Build-Tool verwenden, wird das Tool javac
so ausführen, dass das Problem erkannt wird. Wenn Sie jedoch Ihren Java-Code von Hand erstellen, können Sie dies so tun, dass der Compiler das Problem nicht bemerkt und die resultierende ".class" Datei nicht an der Stelle ist, an der Sie sie erwarten.
Sie können das Problem immer noch nicht finden?-Xdiag
in die java
-Befehlszeile einzufügen (als erstes nach java
). Sie gibt verschiedene Informationen über das Laden von Klassen aus, die Ihnen Hinweise auf das eigentliche Problem geben können.
Ziehen Sie auch mögliche Probleme in Betracht, die durch Kopieren und Einfügen von unsichtbaren oder Nicht-ASCII-Zeichen aus Websites, Dokumenten usw. verursacht werden. Und denken Sie an "Homoglyphen", wo zwei Buchstaben oder Symbole gleich aussehen ... aber es nicht sind'.Die alternative Syntax, die für "ausführbare" JAR-Dateien verwendet wird, lautet wie folgt:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
z.B..
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
com.acme.example.ListUser
) und der Klassenpfad im MANIFEST der JAR-Datei angegeben.java
-Befehlszeile zu erstellen.
Es ist jedoch immer noch möglich, dass diese Ausnahme auftritt, wenn Sie Dinge hinter dem Rücken der IDE tun. Wenn Sie beispielsweise zuvor einen Application Launcher für Ihre Java-Anwendung in Eclipse eingerichtet haben und dann die JAR-Datei mit der Klasse "main" an einen anderen Ort im Dateisystem verschoben haben, ohne dies Eclipse mitzuteilen, würde Eclipse unwissentlich die JVM mit einem falschen Klassenpfad starten.
Kurz gesagt, wenn Sie dieses Problem in einer IDE haben, suchen Sie nach Dingen wie einem veralteten IDE-Status, fehlerhaften Projektreferenzen oder fehlerhaften Konfigurationen des Launchers.
Es ist auch möglich, dass eine IDE einfach durcheinander kommt. IDE's sind äußerst komplizierte Software, die aus vielen interagierenden Teilen besteht. Viele dieser Teile verwenden verschiedene Caching-Strategien, um die IDE als Ganzes reaktionsfähig zu machen. Diese können manchmal schief gehen, und ein mögliches Symptom sind Probleme beim Starten von Anwendungen. Wenn Sie vermuten, dass dies der Fall sein könnte, lohnt es sich, die IDE neu zu starten und das Projekt neu zu erstellen.Manchmal hat die Ursache des Problems nichts mit der Hauptklasse zu tun, und das musste ich auf die harte Tour herausfinden. Es war eine referenzierte Bibliothek, die ich verschoben habe, und es gab mir die:
Konnte die Hauptklasse xxx Linux nicht finden oder laden
Ich löschte den Verweis, fügte ihn wieder hinzu, und es funktionierte wieder.
Legen Sie zunächst den Pfad mit diesem Befehl fest;
set path="paste the set path address"
Dann müssen Sie das Programm laden. Geben Sie "cd (Ordnername)" in das gespeicherte Laufwerk ein und kompilieren Sie es. Zum Beispiel, wenn mein Programm auf dem Laufwerk D gespeichert ist, geben Sie "D:" ein; drücken Sie die Eingabetaste und geben Sie " cd (Ordnername)" ein.