Anfänger der Programmiersprache Java stoßen immer wieder auf dieselben Probleme. Für einige davon sollen hier Erklärungen und Lösungen vorgetragen werden:

Hinweis: Diese Seite und die Fehler-Beschreibungen darauf sind noch unvollständig und bedürfen Erweiterung! Vermutlich bedarf die Thematik auch einer besseren Strukturierung.

Probleme beim Ausführen

Der Befehl 'javac' ist entweder falsch geschrieben oder konnte nicht gefunden werden.

Problem 1: Systempfad

(gilt auch für die gleiche Fehlermeldung mit java statt javac)

Kurzantwort: Das bin-Verzeichnis des JDKs muss in den Systempfad (PATH) aufgenommen werden.

Ausführliche Erklärung: In den meisten Betriebssystemen existiert eine Umgebungsvariable namens PATH, die Pfade enthält, in denen nach ausführbaren Dateien gesucht werden soll. Tippt man also javac HelloWorld.java, dann sucht die Shell in allen Pfaden aus PATH nach einer ausführbaren Datei namens javac (bzw. javac.exe unter Windows). Folglich muss das Verzeichnis des JDKs, das die ausführbaren Dateien enthält, in den PATH aufgenommen werden. Dies geschieht wie folgt:

Problem 2: JDK vs. JRE

Kurzantwort: Statt des JREs wird das JDK benötigt, wenn Programme nicht nur ausgeführt, sondern auch Quellcode kompiliert werden soll.

Ausführliche Erklärung: Zum Ausführen von Java-Programmen wird so gut wie immer eine Umgebung benötigt, die Virtual Machine, in der der kompilierte Bytecode ausgeführt wird. Da aber nicht alle Benutzer von Java-Programmen auch Entwickler sind, gibt es von den meisten Herstellern solcher VMs (insbesondere Sun) zwei unterschiedliche Pakete: ein JRE (Java Runtime Environment), das nur zum Ausführen von Java-Programmen dient, und ein JDK (Java Development Kit), welches zusätzliche Tools für Entwickler mitliefert, vor allem natürlich den Compiler.

Will man also Java-Programme nicht nur ausführen, sondern auch Java-Quellcode kompilieren, so braucht man ein JDK, da das JRE keinen Compiler mitliefert.

Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld

Diese Exception kann unterschiedliche Ursachen haben:

Problem 1: Classpath

Kurzantwort: Das aktuelle Verzeichnis muss in den Classpath aufgenommen werden.

Ausführliche Erklärung: Das Java-System verwendet ähnlich wie oben beim Systempfad einen Klassenpfad (Classpath), der eine Liste von Pfaden enthält, in denen die JVM (Java Virtual Machine) nach Klassen-Dateien sucht, die für die Ausführung benötigt werden. Dabei wird der Klassenpfad aus folgenden Quellen aufgebaut:

Existiert keine der drei Quellen, besteht der Classpath nur aus dem jeweils aktuellen Verzeichnis. Existiert die Umgebungsvariable CLASSPATH, enthält aber nicht das aktuelle Verzeichnis (dieses wird auf den meisten Betriebssystemen durch . (Punkt) symbolisiert), so wird dieses auch nicht automatisch in den Klassenpfad aufgenommen, und .class-Dateien im aktuellen Verzeichnis können von der JVM nicht gefunden werden.

Der Hauptzweck des Klassenpfades ist zwar die Verwendung von Bibliotheken, natürlich müssen aber auch die selbst erstellten Klassen-Dateien im Classpath sein.

Dies kann nun zum einen in der Befehlszeile erledigt werden, indem mit den Parametern -cp oder -classpath Verzeichnisse angegeben werden, in denen nach Klassen gesucht werden soll. Dabei steht ebenfalls . (Punkt) immer für das jeweils aktuelle Verzeichnis. Statt

java HelloWorld

schreibt man also

java -cp . HelloWorld

. Dies hat zur Folge, dass für die Ausführung das aktuelle Verzeichnis in den Classpath aufgenommen wurde, und Klassendateien darin gefunden werden können.

Alternativ kann man das aktuelle Verzeichnis (.) zu der Liste in der Umgebungsvariablen CLASSPATH hinzufügen. Wie dies funktioniert, wird weiter oben unter "Systempfad" beschrieben (nur dass natürlich statt PATH die Variable CLASSPATH bearbeitet bzw. angelegt werden muss).

Problem 2: Quelltext nicht kompiliert

Kurzantwort: .java-Dateien müssen vor dem Ausführen kompiliert werden.

Ausführliche Antwort: Bevor Programme ausgeführt werden können, müssen diese in der Regel erst kompiliert werden (sofern kein Interpreter verwendet wird). Dabei wird der Quellcode vom Compiler entweder in Maschinencode, oder bei Systemen wie Java in Bytecode übersetzt, der dann vom Prozessor (Maschinencode) oder von einer virtuellen Maschine (Bytecode) ausgeführt werden kann. Letzteres ist der Normalfall bei Java.

Zum Kompilieren von Java-Quellcode-Dateien ist ein Tool namens javac (kurz für Java-Compiler) erforderlich. Dieses ist in einem JDK (Java Development Kit) enthalten.

Der Compiler erstellt dann aus den Quellcode-Dateien (Endung .java) sog. Klassen-Dateien (Endung .class), die den erzeugten Bytecode enthalten und von der JVM (Java Virtual Machine) ausgeführt werden können. Existiert die Klassendatei zu der gestarteten Klasse nicht, so kann sie die JVM natürlich nicht im Classpath (s.o.) finden, und quittiert den Dienst mit der genannten Fehlermeldung.

Dem kann Abhilfe geschaffen werden, indem man die Quell-Dateien mit einem entsprechenden Aufruf von javac compiliert:

javac HelloWorld.java

zum Kompilieren einer bestimmten .java-Datei, oder etwa

javac *.java

zum Kompilieren aller .java-Dateien im aktuellen Verzeichnis.

Est danach kann man das Programm dann durch einen Aufruf wie

java HelloWorld

starten.

Problem 3: Dateiendung `.class`

(Die genaue Fehlermeldung lautet dann vermutlich: Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld/class)

Kurzantwort: Der Aufruf java HelloWorld muss ohne die Dateiendung .class erfolgen.

Ausführlich Erklärung: Java-Quelldateien tragen als Dateinamen den Namen der enthaltenen Klasse und die Endung .java. Bei der Kompilierung werden gleichnamige Klassen-Dateien mit der Endung .class erstellt. Will man diese kompilierten Programme starten, verwendet man den Befehl java. Dieser erwartet als Parameter allerdings keinen Datei-, sondern einen Klassennamen. Statt des inkorrekten Aufrufs

java HelloWorld.class

muss also

java HelloWorld 

ausgeführt werden. Java sucht dann selbstständig in den Pfaden des Classpaths (s. oben) nach der zugehörigen Klassendatei.

Hinzu kommt, dass Java-Klassen in sogenannte Packages gegliedert werden können; das zugehörige Trennzeichen ist dabei . (Punkt). Gibt man also HelloWorld.class als Parameter an, sucht Java also nach einer Klasse "class" im Package "HelloWorld", die sehr wahrscheinlich beide nicht existieren (schon allein weil nach der Namenskonvention von Java Package-Namen klein und Klassennamen im sog. CamelCase geschrieben werden).

JavaProbleme (last edited 2007-10-20 14:48:45 by BernhardFrauendienst)