267 votes

Comment puis-je résoudre le problème "java.lang.NoClassDefFoundError" ?

J'ai essayé les deux exemples dans le manuel d'Oracle. Tutoriels Java . Les deux compilent bien, mais au moment de l'exécution, ils affichent tous deux cette erreur :

Exception in thread "main" java.lang.NoClassDefFoundError: graphics/shapes/Square
    at Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: graphics.shapes.Square
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

Je pense que je pourrais avoir le Main.java dans le mauvais dossier.

Voici la hiérarchie des répertoires :

graphics
 Main.java
 shapes
|    Square.java
|    Triangle.java
 linepoint
|    Line.java
|    Point.java
 spaceobjects
|    Cube.java
|    RectPrism.java

Et voici Main.java :

import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;

public class Main {
    public static void main(String args[]) {
        Square s = new Square(2, 3, 15);
        Line l = new Line(1, 5, 2, 3);
        Cube c = new Cube(13, 32, 22);
    }
}

Qu'est-ce que je fais de mal ici ?

UPDATE

Après avoir mis le Main dans la classe graphics (j'ai ajouté package graphics; ), a défini le classpath à "_test" (dossier contenant les graphiques), l'a compilé et l'a exécuté à l'aide de la commande java graphics.Main (à partir de la ligne de commande), cela a fonctionné.

Très en retard UPDATE #2

Je n'utilisais pas Eclipse (juste Notepad++ et le JDK), et la mise à jour ci-dessus a résolu mon problème. Cependant, il semble que beaucoup de ces réponses concernent Eclipse et le JDK. IntelliJ IDEA mais ils ont des concepts similaires.

277voto

Samuel Points 5878

Après avoir compilé votre code, vous vous retrouvez avec .class pour chaque classe de votre programme. Ces fichiers binaires constituent le bytecode que Java interprète pour exécuter votre programme. Le site NoClassDefFoundError indique que le chargeur de classe (dans le cas présent java.net.URLClassLoader ), qui est responsable du chargement dynamique des classes, ne peut pas trouver la classe .class pour la classe que vous essayez d'utiliser.

Votre code ne serait pas compilé si les classes requises n'étaient pas présentes (à moins que les classes ne soient chargées avec la réflexion), donc généralement cette exception signifie que votre classpath n'inclut pas les classes requises. Rappelez-vous que le chargeur de classes (spécifiquement java.net.URLClassLoader ) recherchera les classes du paquet a.b.c dans le dossier a/b/c/ dans chaque entrée de votre classpath. NoClassDefFoundError peut également indiquer qu'il vous manque une dépendance transitive d'un fichier .jar que vous avez compilé et que vous essayez d'utiliser.

Par exemple, si vous aviez une classe com.example.Foo après la compilation, vous aurez un fichier de classe Foo.class . Disons par exemple que votre répertoire de travail est .../project/ . Ce fichier de classe doit être placé dans .../project/com/example et vous devez définir votre classpath comme suit .../project/ .

Remarque : je vous recommande de profiter de l'incroyable outillage qui existe pour les langages Java et JVM. Les IDE modernes comme Eclipse et IntelliJ IDEA et les outils de gestion de la construction comme Maven ou Gradle vous aideront à ne pas avoir à vous soucier des classpaths (autant que possible) et à vous concentrer sur le code ! Cela dit, ce lien explique comment définir le classpath lorsque vous exécutez en ligne de commande.

156voto

p1nkrock Points 196

J'aimerais corriger le point de vue des autres sur NoClassDefFoundError .

NoClassDefFoundError peut se produire pour de multiples raisons comme :

  1. ClassNotFoundException -- Classe non trouvée pour la classe référencée, qu'elle soit disponible ou non au moment de la compilation (c'est-à-dire classe de base/enfant).
  2. Fichier de classe localisé, mais Exception levée lors de l'initialisation des variables statiques
  3. Fichier de classe localisé, Exception levée lors de l'initialisation des blocs statiques

Dans la question initiale, il s'agissait du premier cas qui peut être corrigé en définissant CLASSPATH sur le fichier JAR des classes référencées ou sur son dossier de package.

Que veut-on dire par "disponible en temps de compilation" ?

  • La classe référencée est utilisée dans le code.
    Par exemple : Deux classes, A et B (extends A). Si B est référencée directement dans le code, elle est disponible au moment de la compilation, c'est-à-dire, A a = new B();

Que signifie la mention "non disponible au moment de la compilation" ?

  • La classe au moment de la compilation et la classe au moment de l'exécution sont différentes, c'est-à-dire que, par exemple, la classe de base est chargée en utilisant le nom de la classe enfant, par exemple Classe.forName("nom de classe") Ex : Deux classes, A et B (extends A). Le code a
    A a = Class.forName("B").newInstance();

18voto

kocko Points 18585

NoClassDefFoundError signifie que la classe est présente dans le classpath à l'adresse Compile time mais il n'existe pas dans le classpath à l'adresse suivante Runtime .

Si vous utilisez Eclipse, assurez-vous d'avoir l'option shapes , linepoints et le spaceobjects en tant qu'entrées dans le .classpath fichier.

17voto

sami Points 11

Si vous avez obtenu l'une de ces erreurs lors de la compilation et de l'exécution :

  • NoClassDefFoundError

  • Erreur : Impossible de trouver ou de charger la classe principale hello

  • Exception dans le thread "main" java.lang.NoClassDefFoundError:javaTest/test/hello (nom erroné : test/hello)

    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

-------------------------- Solution -----------------------

Le problème réside principalement dans l'organisation des paquets. Vous devez organiser vos classes dans des dossiers en tenant compte de la classification des paquets dans votre code source.

Lors du processus de compilation, utilisez cette commande :

javac -d . [FileName.java]

Pour exécuter la classe, veuillez utiliser cette commande :

java [Package].[ClassName]

10voto

SatelliteSD Points 2686
java.lang.NoClassDefFoundError

indique que quelque chose a été trouvé à temps de compilation mais pas à temps de fonctionnement . Il suffit peut-être de l'ajouter au classpath.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X