• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Was gibt es Schöneres als den Mai draußen in der Natur mit allen Sinnen zu genießen? Lasst uns teilhaben an Euren Erlebnissen und macht mit beim Thema des Monats Da blüht uns was! ---> Klick

Kommandozeile java und javac - Exception in thread "main" java.lang.NoClassDefFoundEr

rilight

Alkmene
Registriert
11.04.12
Beiträge
35
Hallo liebes Forum !


Ich habe für die Uni wieder mit Java angefangen und wollte auch gern die Kommandozeile nutzen, denn da bauen wir kleine Tools, die ich danach auch verwenden will. Daher habe ich mich gestern durch das Galileo OpenBook gelesen.
Leider bin ich beim ersten Programm schon gescheitert.

Erstes Programm:
Code:
package javaprogeins;

/**
 *
 * @author ben
 */

public class JavaProgEins {

    // Methode zum quadrieren von Zahlen
    static void square(int from, int to)
    {
        for(int i = from; i <= to; ++i)
        {
            int result = i * i;
            System.out.println(i + " zum Qudadrat: " + result);
        }
    }
    
    
    // Main
    public static void main(String[] args)
    {
        int start   = 5;
        int end     = 7;
        square(start, end);
    }
}

Wenn ich in Netbeans auf den "Play" Button klicke, dann läuft alles ohne Probleme durch.

Jetzt wollte ich auch auf der Kommandozeile den Bitcode erzeugen und das Java Programm ausführen.
Dazu habe ich folgendes gemacht:

- mit "cd /Pfad/zum/Ordner/der/Datei" in den Ordner der JavaProgEins.java gewechselt
- mit "javac JavaProgEins.java" den Bitcode erzeugt
- mit "java JavaProgEins" das Programm ausführen

Da kam die Fehlermeldung:
Exception in thread "main" java.lang.NoClassDefFoundError: javaprogeins/JavaProgEins
Caused by: java.lang.ClassNotFoundException: javaprogeins.JavaProgEins
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

Daraufhin habe ich mich bei google versucht schlau zu machen. Ich hab herausgefunden, sobald man die Anweisung "package javaprogeins;" im Programm stehen hat, wird der folgende Befehl benötigt:

- "java javaprogeins.JavaProgEins"

... nur leider kommt dann immer noch die gleiche Fehlermeldung.
Ich habe dann noch weitergesucht und etwas zum "CLASSPATH" gefunden.
Leider waren die vielen Themen widersprüchlich. Die einen Sagen auf dem Mac muss man nix einstellen, die anderen sagen man muss.
Ich konnte auch trotz Suche nicht verstehen für was der Classpath gebraucht wird.

Daher meine Frage, was mache ich falsch?
Muss ich am CLASSPATH etwas ändern?


liebe Grüße
rilight
 

fyysh

Schweizer Glockenapfel
Registriert
25.01.10
Beiträge
1.386
Code:
fyysh@Perseus: ~/TMP/javafirlefanz
$> pbpaste > JavaProgEins.java

fyysh@Perseus: ~/TMP/javafirlefanz
$> cat JavaProgEins.java 
package javaprogeins;

/**
 *
 * @author ben
 */

public class JavaProgEins {

    // Methode zum quadrieren von Zahlen
    static void square(int from, int to)
    {
        for(int i = from; i <= to; ++i)
        {
            int result = i * i;
            System.out.println(i + " zum Qudadrat: " + result);
        }
    }   
    
    // Main
    public static void main(String[] args)
    {
        int start   = 5;
        int end     = 7;
        square(start, end);
    }
}

fyysh@Perseus: ~/TMP/javafirlefanz
$> javac JavaProgEins.java 

fyysh@Perseus: ~/TMP/javafirlefanz
$> java JavaProgEins 
Exception in thread "main" java.lang.NoClassDefFoundError: JavaProgEins (wrong name: javaprogeins/JavaProgEins)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

fyysh@Perseus: ~/TMP/javafirlefanz ret:1
$> export CLASSPATH="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar"

fyysh@Perseus: ~/TMP/javafirlefanz
$> java -cp ./ JavaProgEins Exception in thread "main" java.lang.NoClassDefFoundError: JavaProgEins (wrong name: javaprogeins/JavaProgEins)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

fyysh@Perseus: ~/TMP/javafirlefanz ret:1
$> pbpaste >HelloWorld.java

fyysh@Perseus: ~/TMP/javafirlefanz
$> cat HelloWorld.java
public class HelloWorld {
    // A program to display the message
    // "Hello World!" on standard output
    
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

fyysh@Perseus: ~/TMP/javafirlefanz
$> javac HelloWorld.java 

fyysh@Perseus: ~/TMP/javafirlefanz
$> java HelloWorld
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld
Caused by: java.lang.ClassNotFoundException: HelloWorld
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

fyysh@Perseus: ~/TMP/javafirlefanz ret:1
$> java -cp ./ HelloWorld
Hello World!

fyysh@Perseus: ~/TMP/javafirlefanz
$> java -cp ./ 
HelloWorld    JavaProgEins  

fyysh@Perseus: ~/TMP/javafirlefanz
$> java -cp ./ JavaProgEins 
5 zum Qudadrat: 25
6 zum Qudadrat: 36
7 zum Qudadrat: 49

fyysh@Perseus: ~/TMP/javafirlefanz
$> unset CLASSPATH 

fyysh@Perseus: ~/TMP/javafirlefanz
$> java -cp ./ HelloWorld
Hello World!

fyysh@Perseus: ~/TMP/javafirlefanz
$> java -cp ./ JavaProgEins 
5 zum Qudadrat: 25
6 zum Qudadrat: 36
7 zum Qudadrat: 49

fyysh@Perseus: ~/TMP/javafirlefanz
$> java JavaProgEins
5 zum Qudadrat: 25
6 zum Qudadrat: 36
7 zum Qudadrat: 49

DAFUQ!?!?
 

gKar

Maunzenapfel
Registriert
25.06.08
Beiträge
5.362
Das Stichwort ist: „Package“

Wenn Du die Klasse einem Paket zuordnest, muss die Soruce- sowie die kompilierte Class-Datei in einem entsprechenden Ordner liegen und der Aufruf erfolgt standardmäßig aus dem Ordner, in dem der Paket-Ordner liegt (nicht dem, in dem die class-Datei selbst liegt). Außerdem ist beim Aufruf der Klasse der Paketname voranzustellen.
 

fyysh

Schweizer Glockenapfel
Registriert
25.01.10
Beiträge
1.386
@gKar: Weißt du auch wie der shice mit HelloWorld bei mir zustande kam? Da war nix Package.

BTW: Ich hatte das Package auskommentiert... vergessen zu posten. Der Fehler blieb der selbe, wie man oben sieht.
 

rilight

Alkmene
Registriert
11.04.12
Beiträge
35
Danke für eure schnelle Hilfe.
Ich war leider die letzten 2 Tage nicht in reichweite eines Computers, daher schreibe ich erst jetzt.

Habe ich das richtig verstandenen, dass der CLASSPATH erst exportiert werden muss (zur aktuellen java Installation ->
/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar)

und

wenn package verwendet wird (ist das dann eine *.jar -Datei ?), dann müssen *.class und *.java im gleichen Ordner liegen?

liebe Grüße
rilight
 

gKar

Maunzenapfel
Registriert
25.06.08
Beiträge
5.362
@gKar: Weißt du auch wie der shice mit HelloWorld bei mir zustande kam?

Nein, weiß ich nicht. Normalerweise sollte Java im Verzeichnis ‚.‘ nach Klassen bzw. Paketpfaden suchen, ohne dass man ‚.‘ explizit in den Classpath aufnimmt. Bei mir funktioniert's problemlos:
Code:
gKar:~ gKar$ mkdir javatest
gKar:~ gKar$ cd javatest
gKar:javatest gKar$ ls
gKar:javatest gKar$ pbpaste > HelloWorld.java
gKar:javatest gKar$ cat HelloWorld.java 
public class HelloWorld {
    // A program to display the message
    // "Hello World!" on standard output
    
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
gKar:javatest gKar$ javac HelloWorld.java 
gKar:javatest gKar$ java HelloWorld
Hello World!
gKar:javatest gKar$

UPDATE: Sobald ich jedoch, wie Du oben, die CLASSPATH-Variable setze, funktioniert's nicht mehr, genau wie bei Dir. In dem Fall sollte man . direkt mit zur CLASSPATH-Variable hinzufügen:

Code:
immo:gKartest immo$ export CLASSPATH="/System/Library/Frameworks/gKarVM.framework/Versions/CurrentJDK/Classes/classes.jar" 
immo:gKartest immo$ gKar HelloWorld
Exception in thread "main" gKar.lang.NoClassDefFoundError: HelloWorld
Caused by: gKar.lang.ClassNotFoundException: HelloWorld
    at gKar.net.URLClassLoader$1.run(URLClassLoader.gKar:202)
    at gKar.security.AccessController.doPrivileged(Native Method)
    at gKar.net.URLClassLoader.findClass(URLClassLoader.gKar:190)
    at gKar.lang.ClassLoader.loadClass(ClassLoader.gKar:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.gKar:301)
    at gKar.lang.ClassLoader.loadClass(ClassLoader.gKar:247)
immo:gKartest immo$ export CLASSPATH=$CLASSPATH:.
immo:gKartest immo$ gKar HelloWorld
Hello World!
immo:gKartest immo$


rilight schrieb:
Habe ich das richtig verstandenen, dass der CLASSPATH erst exportiert werden muss (zur aktuellen java Installation ->
/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar)

und

wenn package verwendet wird (ist das dann eine *.jar -Datei ?), dann müssen *.class und *.java im gleichen Ordner liegen?

Nein. Normalerweise muss man weder die classes.jar noch das aktuelle Verzeichnis (.) manuell in einen Classpath aufnehmen. Eigentlich sollte Java vernünftig eingerichtet sein.
Ein Package hat nichts mit JARs zu tun. Packages strukturieren die Klassen, genau wie Verzeichnisse Dateien auf einer Festplatte strukturieren. Und sowohl die Java-Sourcedateien als auch die Class-Dateien müssen in einer exakt der Paketstruktur entsprechenden Ordnerstruktur auf der Festplatte liegen. Das heißt aber nicht, dass Quellen und Classes im selben Ordner liegen müssen. Üblich ist z.B. ein Sourcen-Ordner mit einem Unterordner pro Paket und separat dazu ein build-Ordner mit den kompilierten Klassen in einer identischen Unterordner-Struktur. Letzteren kann man dann auch zu einem Jar zippen, wenn man will.

UPDATE2:
Hier nochmal 'ne saubere Vorführung Deiner Beispieldatei:
Code:
gKar:javatest gKar$ mkdir javaprogeins
gKar:javatest gKar$ pbpaste > javaprogeins/JavaProgEins.java
gKar:javatest gKar$ cat javaprogeins/JavaProgEins.java 
package javaprogeins;


/**
 *
 * @author ben
 */


public class JavaProgEins {


    // Methode zum quadrieren von Zahlen
    static void square(int from, int to)
    {
        for(int i = from; i <= to; ++i)
        {
            int result = i * i;
            System.out.println(i + " zum Qudadrat: " + result);
        }
    }
    
    
    // Main
    public static void main(String[] args)
    {
        int start   = 5;
        int end     = 7;
        square(start, end);
    }
}gKar:javatest gKar$ javac javaprogeins/JavaProgEins.java 
gKar:javatest gKar$ java javaprogeins.JavaProgEins
5 zum Qudadrat: 25
6 zum Qudadrat: 36
7 zum Qudadrat: 49
gKar:javatest gKar$
 

rilight

Alkmene
Registriert
11.04.12
Beiträge
35
Super es funktioniert!
Danke an alle, die hier zur Lösung beigetragen haben.


Besonderer Danke geht an gKar, der mir den Anstoß mit dem guten Beispiel gegeben hat.

Ich halte nocheinmal fest:
- wenn "package" im Programm enthalten ist, muss auch der Ordner (und Unterodner) vorhanden sein
- ohne package funktioniert normal "javac" und "java"

Hier nochmal meine Konsole:
Code:
noname:Documents ben$ cd tmp
noname:tmp ben$ ls
javaprogeins
noname:tmp ben$ javac javaprogeins/JavaProgEins.java
noname:tmp ben$ java javaprogeins/JavaProgEins
5 zum Qudadrat: 25
6 zum Qudadrat: 36
7 zum Qudadrat: 49