Quelles sont les causes et quelles sont les différences entre NoClassDefFoundError et ClassNotFoundException?

371

Quelle est la difference entre NoClassDefFoundErroret ClassNotFoundException?

Qu'est-ce qui les fait se jeter? Comment peuvent-ils être résolus?

Je rencontre souvent ces objets jetables lors de la modification du code existant pour inclure de nouveaux fichiers jar. Je les ai touchés à la fois côté client et côté serveur pour une application java distribuée via Webstart.

Les raisons possibles que j'ai rencontrées:

  1. packages non inclus dans build.xmlle côté client du code
  2. chemin de classe d'exécution manquant pour les nouveaux pots que nous utilisons
  3. la version est en conflit avec le pot précédent

Quand je les rencontre aujourd'hui, j'adopte une approche par traînée et erreur pour faire fonctionner les choses. J'ai besoin de plus de clarté et de compréhension.

krisp
la source
Je trouve souvent que l'exécution de la JVM avec -verbose(par exemple -verbose:class -verbose:jni) aide - mais mogsie rapporte en dessous de sa réponse que cela ne fournit aucune information supplémentaire utile :(
PJTraill

Réponses:

388

La différence par rapport aux spécifications de l'API Java est la suivante.

Pour ClassNotFoundException:

Lancé lorsqu'une application tente de se charger dans une classe via son nom de chaîne en utilisant:

  • La forNameméthode en classe Class.
  • La findSystemClassméthode en classe ClassLoader.
  • La loadClassméthode en classe ClassLoader.

mais aucune définition de la classe portant le nom spécifié n'a pu être trouvée.

Pour NoClassDefFoundError:

Lancé si la machine virtuelle Java ou une ClassLoaderinstance tente de charger dans la définition d'une classe (dans le cadre d'un appel de méthode normal ou dans le cadre de la création d'une nouvelle instance à l'aide de la nouvelle expression) et qu'aucune définition de la classe n'a pu être trouvée.

La définition de classe recherchée existait lorsque la classe en cours d'exécution a été compilée, mais la définition ne peut plus être trouvée.

Il apparaît donc que cela NoClassDefFoundErrorse produit lorsque la source a été compilée avec succès, mais au moment de l'exécution, les classfichiers requis sont introuvables. Cela peut se produire dans la distribution ou la production de fichiers JAR, où tous les classfichiers requis n'étaient pas inclus.

En ce qui concerne ClassNotFoundException, il semble que cela puisse provenir de la tentative d'appels réfléchis aux classes lors de l'exécution, mais les classes que le programme tente d'appeler n'existe pas.

La différence entre les deux est que l'un est un Erroret l'autre est un Exception. Avec NoClassDefFoundErrorest un Erroret il découle de la machine virtuelle Java ayant des problèmes pour trouver une classe qu'il s'attendait à trouver. Un programme qui devait fonctionner au moment de la compilation ne peut pas s'exécuter en raison de classfichiers non trouvés ou n'est pas le même que celui qui a été produit ou rencontré au moment de la compilation. Il s'agit d'une erreur assez critique, car le programme ne peut pas être lancé par la JVM.

D'un autre côté, ClassNotFoundExceptionc'est un Exception, donc c'est quelque peu attendu, et c'est quelque chose qui est récupérable. L'utilisation de la réflexion peut être source d'erreurs (car il y a des attentes que les choses ne se passent pas comme prévu. Il n'y a pas de vérification à la compilation pour voir que toutes les classes requises existent, donc tout problème avec la recherche des classes souhaitées apparaîtra au moment de l'exécution) .

coobird
la source
53
NoClassDefFoundErrorse produit généralement en cas de problème (exception levée) avec l'initialisation du bloc statique ou des champs statiques de la classe, de sorte que la classe ne peut pas être initialisée avec succès.
Dagang
7
upvote. l'un est un Erroret l'autre est un Exception. :)
Ravi
83

Une exception ClassNotFoundException est levée lorsque la classe signalée n'est pas trouvée par ClassLoader. Cela signifie généralement que la classe est absente du CLASSPATH. Cela pourrait également signifier que la classe en question essaie d'être chargée à partir d'une autre classe qui a été chargée dans un chargeur de classe parent et donc la classe du chargeur de classe enfant n'est pas visible. C'est parfois le cas lorsque vous travaillez dans des environnements plus complexes comme un serveur d'applications (WebSphere est tristement célèbre pour ces problèmes de chargeur de classe).

Les gens ont souvent tendance à confondre java.lang.NoClassDefFoundErroravec java.lang.ClassNotFoundExceptionmais il existe une distinction importante. Par exemple, une exception (une erreur étant vraiment java.lang.NoClassDefFoundErrorune sous-classe de java.lang.Error) comme

java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory

ne signifie pas que la classe ActiveMQConnectionFactory n'est pas dans le CLASSPATH. En fait, c'est tout le contraire. Cela signifie que la classe ActiveMQConnectionFactory a été trouvée par le ClassLoader mais lors de la tentative de chargement de la classe, une erreur s'est produite lors de la lecture de la définition de classe. Cela se produit généralement lorsque la classe en question a des blocs statiques ou des membres qui utilisent une classe qui n'est pas trouvée par le ClassLoader. Donc, pour trouver le coupable, affichez la source de la classe en question (ActiveMQConnectionFactory dans ce cas) et recherchez du code à l'aide de blocs statiques ou de membres statiques. Si vous n'avez pas accès à la source, décompilez-la simplement à l'aide de JAD.

En examinant le code, disons que vous trouvez une ligne de code comme ci-dessous, assurez-vous que la classe SomeClass est dans votre CLASSPATH.

private static SomeClass foo = new SomeClass();

Conseil: Pour savoir à quel pot appartient une classe, vous pouvez utiliser le site Web jarFinder. Cela vous permet de spécifier un nom de classe à l'aide de caractères génériques et il recherche la classe dans sa base de données de pots. jarhoo vous permet de faire la même chose mais ce n'est plus gratuit à utiliser.

Si vous souhaitez localiser le fichier auquel appartient une classe dans un chemin local, vous pouvez utiliser un utilitaire comme jarscan ( http://www.inetfeedback.com/jarscan/ ). Vous spécifiez simplement la classe que vous souhaitez localiser et le chemin du répertoire racine où vous souhaitez qu'il commence à rechercher la classe dans des fichiers jars et zip.

Sanjiv Jivan
la source
9
C'est drôle que ce soit exactement la bonne réponse qui a été votée la dernière. (Même -1 avant de voter). ClassNotFoundException signifie que le CL ne voit pas le fichier .class. NoClassDefFoundError signifie que le fichier .class est là, il n'est pas chargeable (peut-être une erreur JNI).
user43685
1
Cette réponse n'est-elle pas en contradiction avec le formulaire de réponse coobird?
zardosht
J'ai essayé un exemple similaire de bloc statique. Ma classe Class1 a la variable statique "private static B foo = new B ();" Après la compilation, j'ai supprimé le fichier B.class du dossier bin. Maintenant de la méthode principale de la troisième classe lorsque je crée un objet de Class1. La rror est identifiée comme suit: -------- "Exception dans le thread" main "java.lang.NoClassDefFoundError: spring / B" ........ Donc, elle mentionne exactement quelle classe elle n'a pas trouvée ieclass fait référence dans un bloc statique et non dans la classe externe, ce qui est contraire à cette réponse.
Kaushik Lele
+1 pour la clarification concernant "ne signifie pas que la classe ActiveMQConnectionFactory n'est pas dans le CLASSPATH"
akila
35

NoClassDefFoundErrorest une erreur de liaison essentiellement. Cela se produit lorsque vous essayez d'instancier un objet (statiquement avec "nouveau") et il n'est pas trouvé lorsqu'il était lors de la compilation.

ClassNotFoundExceptionest plus général et constitue une exception d'exécution lorsque vous essayez d'utiliser une classe qui n'existe pas. Par exemple, vous avez un paramètre dans une fonction accepte une interface et quelqu'un passe dans une classe qui implémente cette interface mais vous n'avez pas accès à la classe. Il couvre également le cas de chargement de classe dynamique, comme l'utilisation de loadClass()ou Class.forName().

cletus
la source
29

Une NoClassDefFoundError (NCDFE) se produit lorsque votre code exécute "new Y ()" et qu'il ne trouve pas la classe Y.

Il se peut simplement que Y manque dans votre chargeur de classe comme le suggèrent les autres commentaires, mais il se peut que la classe Y ne soit pas signée ou ait une signature invalide, ou que Y soit chargé par un autre chargeur de classe non visible par votre code , ou même que Y dépend de Z qui n'a pas pu être chargé pour l'une des raisons ci-dessus.

Si cela se produit, la JVM se souviendra du résultat du chargement de X (NCDFE) et lancera simplement un nouveau NCDFE à chaque fois que vous demanderez Y sans vous dire pourquoi:

Classe A {
  classe statique b {}
  public static void main (String args []) {
    System.out.println ("Première tentative de nouveau b ():");
    essayez {new b (); } catch (Throwable t) {t.printStackTrace ();}
    System.out.println ("\ nDeuxième tentative de nouveau b ():");
    essayez {new b (); } catch (Throwable t) {t.printStackTrace ();}
  }
}

enregistrez-le quelque part sous a.java

Le code essaie simplement d'instancier deux fois une nouvelle classe "b", à part cela, il n'a pas de bogues et il ne fait rien.

Compilez le code avec javac a.java, puis exécutez un en appelant java -cp . a- il devrait simplement imprimer deux lignes de texte, et il devrait fonctionner correctement sans erreur.

Supprimez ensuite le fichier "a $ b.class" (ou remplissez-le avec des ordures ou copiez a.class dessus) pour simuler la classe manquante ou corrompue. Voici ce qui se passe:

Première tentative de nouveau b ():
java.lang.NoClassDefFoundError: a $ b
    à a.main (a.java:5)
Provoqué par: java.lang.ClassNotFoundException: a $ b
    sur java.net.URLClassLoader $ 1.run (URLClassLoader.java:200)
    à java.security.AccessController.doPrivileged (méthode native)
    sur java.net.URLClassLoader.findClass (URLClassLoader.java:188)
    à java.lang.ClassLoader.loadClass (ClassLoader.java:307)
    à sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:301)
    à java.lang.ClassLoader.loadClass (ClassLoader.java:252)
    à java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320)
    ... 1 de plus

Deuxième tentative de nouveau b ():
java.lang.NoClassDefFoundError: a $ b
    à a.main (a.java:7)

La première invocation entraîne une exception ClassNotFoundException (levée par le chargeur de classe lorsqu'il ne trouve pas la classe), qui doit être encapsulée dans un NoClassDefFoundError non contrôlé, car le code en question ( new b()) devrait simplement fonctionner.

La deuxième tentative échouera bien sûr également, mais comme vous pouvez le voir, l'exception encapsulée n'est plus, car le ClassLoader semble se souvenir des chargeurs de classe défaillants. Vous ne voyez que le NCDFE sans aucune idée de ce qui s'est réellement passé.

Donc, si vous voyez un NCDFE sans cause racine, vous devez voir si vous pouvez remonter à la toute première fois que la classe a été chargée pour trouver la cause de l'erreur.

mogsie
la source
Qu'en est-il de l'exécution de la JVM avec -verbose, ou d'une option similaire selon la JVM spécifique? Probablement -verbose:class, peut -verbose:class:jni- être si j'utilise JNI, mais je ne suis pas sûr de la syntaxe. Si cela est utile, vous pourriez peut-être afficher les résultats.
PJTraill
Ni donner -verbose:classni -verbose:jnisortie supplémentaire pertinente pour la classe manquante.
mogsie
1
Merci de l'avoir essayé, même si le résultat est décevant. (PS, j'ai découvert depuis que -verbose:class:jnic'est faux: il faut spécifier deux options distinctes -verbose:class -verbose:jni
:.
2
La dernière phrase * 1 000 000: Donc, si vous voyez un NCDFE sans cause racine, vous devez voir si vous pouvez remonter à la toute première fois que la classe a été chargée pour trouver la cause de l'erreur.
batwad
20

Sur http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :

ClassNotFoundException: se produit lorsque le chargeur de classe n'a pas pu trouver la classe requise dans le chemin de classe. Donc, fondamentalement, vous devez vérifier votre chemin de classe et ajouter la classe dans le chemin de classe.

NoClassDefFoundError: c'est plus difficile à déboguer et à trouver la raison. Ceci est levé lorsqu'au moment de la compilation les classes requises sont présentes, mais au moment de l'exécution, les classes sont modifiées ou supprimées ou la statique de la classe initialise des exceptions levées. Cela signifie que la classe qui est chargée est présente dans classpath, mais l'une des classes requises par cette classe est supprimée ou n'a pas pu être chargée par le compilateur. Vous devriez donc voir les classes qui dépendent de cette classe.

Exemple :

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

Maintenant, après avoir compilé les deux classes, si vous supprimez le fichier Test1.class et exécutez la classe Test, il lancera

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    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)
    ... 1 more

ClassNotFoundException: levée lorsqu'une application tente de charger dans une classe via son nom, mais aucune définition de la classe avec le nom spécifié n'a pu être trouvée.

NoClassDefFoundError: levée si la machine virtuelle Java tente de se charger dans la définition d'une classe et qu'aucune définition de la classe n'a pu être trouvée.

KingFeming
la source
Qu'en est-il de l'exécution de la JVM avec -verbose, ou d'une option similaire selon la JVM spécifique? Probablement -verbose:class, peut -verbose:class:jni- être si j'utilise JNI, mais je ne suis pas sûr de la syntaxe.
PJTraill
-verbose:class:jniest faux, mais vous pouvez passer deux options distinctes: -verbose:class -verbose:jni.
PJTraill
15

Quelle est la raison d'avoir chacun d'eux et tout processus de réflexion sur la façon de traiter ces erreurs?

Ils sont étroitement liés. Un ClassNotFoundExceptionest levé lorsque Java a recherché une classe particulière par son nom et n'a pas pu la charger avec succès. Un NoClassDefFoundErrorest levé lorsque Java est allé chercher une classe qui était liée à du code existant, mais n'a pas pu le trouver pour une raison ou une autre (par exemple, mauvais chemin de classe, mauvaise version de Java, mauvaise version d'une bibliothèque) et est complètement fatale car cela indique que quelque chose a mal tourné.

Si vous avez un fond C, un CNFE est comme un échec de dlopen()/ dlsym()et un NCDFE est un problème avec l'éditeur de liens; dans le second cas, les fichiers de classe concernés n'auraient jamais dû être réellement compilés dans la configuration que vous essayez de les utiliser.

Associés Donal
la source
11

Exemple 1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

Si com/example/Class1n'existe dans aucun des chemins de classe, alors il lance ClassNotFoundException.

Exemple # 2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

Si com/example/Class2existé lors de la compilation de B, mais non trouvé lors de l'exécution, il lance NoClassDefFoundError.

Les deux sont des exceptions d'exécution.

Dinesh
la source
9

ClassNotFoundException est levée lors d'une tentative de chargement de la classe en la référençant via une chaîne. Par exemple, le paramètre à dans Class.forName () est une chaîne, ce qui augmente le potentiel de noms binaires non valides transmis au chargeur de classe.

L'exception ClassNotFoundException est levée lorsqu'un nom binaire potentiellement invalide est rencontré; par exemple, si le nom de classe a le caractère «/», vous êtes lié pour obtenir une exception ClassNotFoundException. Elle est également levée lorsque la classe directement référencée n'est pas disponible sur le chemin de classe.

D'un autre côté, NoClassDefFoundError est levée

  • lorsque la représentation physique réelle de la classe - le fichier .class n'est pas disponible,
  • ou la classe a déjà été chargée dans un chargeur de classe différent (généralement un chargeur de classe parent aurait chargé la classe et donc la classe ne peut pas être chargée à nouveau),
  • ou si une définition de classe incompatible a été trouvée - le nom dans le fichier de classe ne correspond pas au nom demandé,
  • ou (le plus important) si une classe dépendante ne peut pas être localisée et chargée. Dans ce cas, la classe directement référencée peut avoir été localisée et chargée, mais la classe dépendante n'est pas disponible ou ne peut pas être chargée. Il s'agit d'un scénario dans lequel la classe directement référencée peut être chargée via un Class.forName ou des méthodes équivalentes. Cela indique une défaillance de la liaison.

En bref, une NoClassDefFoundError est généralement lancée sur de nouvelles instructions () ou des appels de méthode qui chargent une classe précédemment absente (par opposition au chargement basé sur des chaînes de classes pour ClassNotFoundException), lorsque le chargeur de classe n'est pas en mesure de trouver ou de charger la définition de classe ( s).

Finalement, il appartient à l'implémentation ClassLoader de lever une instance de ClassNotFoundException lorsqu'elle est incapable de charger une classe. La plupart des implémentations de chargeur de classe personnalisées effectuent cela car elles étendent URLClassLoader. Habituellement, les chargeurs de classe ne lancent pas explicitement une NoClassDefFoundError sur l'une des implémentations de méthode - cette exception est généralement levée à partir de la JVM dans le compilateur HotSpot, et non par le chargeur de classe lui-même.

Vineet Reynolds
la source
Vote positif pour avoir mentionné «le nom dans le fichier de classe ne correspond pas au nom demandé». C'est une cause assez courante.
Marquis de Lorne
8

Différence entre ClassNotFoundException et NoClassDefFoundError

entrez la description de l'image ici

Lawakush Kurmi
la source
Pas limpide. "Non mis à jour dans le chemin de classe" est vague / imprécis. Cela concerne soit le JAR qui n'est pas présent dans le chemin de classe, soit la mauvaise version du JAR qui est sur le chemin de classe. Et des fautes d'orthographe. Et (soupir) puisque vous avez publié vos informations sous forme de graphisme génial, nous ne pouvons pas résoudre ce problème.
Stephen C
8

Avec les noms eux-mêmes, nous pouvons facilement identifier l'un Exceptionet l'autre Error.

Exception: des exceptions se produisent pendant l'exécution du programme. Un programmeur peut gérer ces exceptions en essayant le bloc catch. Nous avons deux types d'exceptions. Exception vérifiée qui se déclenche au moment de la compilation. Exceptions d'exécution qui sont levées au moment de l'exécution, ces exceptions se produisent généralement en raison d'une mauvaise programmation.

Erreur: ce ne sont pas du tout des exceptions, cela dépasse la portée du programmeur. Ces erreurs sont généralement générées par JVM.


entrez la description de l'image ici source d'image

Différence:

ClassNotFoundException:

  • Le chargeur de classe ne parvient pas à vérifier un code d'octet de classe que nous mentionnons dans la phase de liaison du sous-système de chargement de classe que nous obtenons ClassNotFoundException.
  • ClassNotFoundExceptionest une exception vérifiée dérivée directement de la java.lang.Exceptionclasse et vous devez en fournir une gestion explicite
  • ClassNotFoundExceptions'affiche lorsqu'un chargement explicite de classe est impliqué en fournissant le nom de la classe lors de l'exécution à l'aide de ClassLoader.loadClass (), Class.forName () et ClassLoader.findSystemClass ().

NoClassDefFoundError:

  • Le chargeur de classe ne parvient pas à résoudre les références d'une classe dans la phase de liaison du sous-système de chargement de classe que nous obtenons NoClassDefFoundError.
  • NoClassDefFoundErrorest une erreur dérivée de la LinkageErrorclasse, qui est utilisée pour indiquer les cas d'erreur, où une classe a une dépendance à l'égard d'une autre classe et que cette classe a changé de manière incompatiable après la compilation.
  • NoClassDefFoundErrorest le résultat d'un chargement implicite de classe en raison d'un appel de méthode à partir de cette classe ou de tout accès variable.

Similitudes:

  • Les deux NoClassDefFoundErroret ClassNotFoundExceptionsont liés à l'indisponibilité d'une classe au moment de l'exécution.
  • Les deux ClassNotFoundExceptionet NoClassDefFoundErrorsont liés au chemin de classe Java.
Premraj
la source
3

Étant donné les actions du système de chargement de classe:

http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

Ceci est un article qui m'a beaucoup aidé à comprendre la différence: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

Si une erreur se produit pendant le chargement de la classe, une instance d'une sous-classe de LinkageError doit être levée à un point du programme qui (directement ou indirectement) utilise la classe ou l'interface en cours de chargement.

Si la machine virtuelle Java tente de charger une classe C pendant la vérification (§5.4.1) ou la résolution (§5.4.3) (mais pas l'initialisation (§5.5)), et le chargeur de classe utilisé pour lancer le chargement de C lève une instance de ClassNotFoundException , puis la machine virtuelle Java doit lever une instance de NoClassDefFoundError dont la cause est l'instance de ClassNotFoundException .

Une exception ClassNotFoundException est donc une cause première de NoClassDefFoundError .
Et une NoClassDefFoundError est un cas particulier d'erreur de chargement de type, qui se produit à l' étape de liaison .

Anton Shchastnyi
la source
2

Ajoutez une raison possible dans la pratique:

  • ClassNotFoundException: comme l'a dit cletus, vous utilisez l'interface alors que la classe héritée d'interface n'est pas dans le chemin de classe. Par exemple, le modèle de fournisseur de services (ou le localisateur de services ) essaie de localiser une classe non existante
  • NoClassDefFoundError: la classe donnée est trouvée tandis que la dépendance de la classe donnée est introuvable

Dans la pratique, une erreur peut être levée en silence , par exemple, vous soumettez une tâche de minuterie et dans la tâche de minuterie, elle génère une erreur , alors que dans la plupart des cas, votre programme ne capture que l' exception . Ensuite, la boucle principale du minuteur se termine sans aucune information. Une erreur similaire à NoClassDefFoundError est ExceptionInInitializerError , lorsque votre initialiseur statique ou l'initialiseur d'une variable statique lève une exception.

leef
la source
1

ClassNotFoundException est une exception vérifiée qui se produit lorsque nous demandons à JVM de charger une classe par son nom de chaîne à l'aide des méthodes Class.forName () ou ClassLoader.findSystemClass () ou ClassLoader.loadClass () et que la classe mentionnée ne se trouve pas dans le chemin de classe.

La plupart du temps, cette exception se produit lorsque vous essayez d'exécuter une application sans mettre à jour le chemin de classe avec les fichiers JAR requis. Par exemple, vous avez peut-être vu cette exception lors de l'exécution du code JDBC pour vous connecter à votre base de données ieMySQL, mais votre chemin de classe n'a pas de fichier JAR pour cela.

L' erreur NoClassDefFoundError se produit lorsque la machine virtuelle Java tente de charger une classe particulière qui fait partie de l'exécution de votre code (dans le cadre d'un appel de méthode normal ou dans le cadre de la création d'une instance à l'aide du nouveau mot clé) et que cette classe n'est pas présente dans votre chemin de classe mais était présent au moment de la compilation, car pour exécuter votre programme, vous devez le compiler et si vous essayez d'utiliser une classe qui n'est pas présente, le compilateur provoquera une erreur de compilation.

Voici la brève description

entrez la description de l'image ici

Vous pouvez lire tout sur ClassNotFoundException Vs NoClassDefFoundError pour plus de détails.

Naresh Joshi
la source
0

Je me rappelle ce qui suit encore et encore quand j'ai besoin de me rafraîchir

ClassNotFoundException

Hiérarchie des classes

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

Pendant le débogage

  1. Bocal requis, la classe est manquante dans le chemin de classe.
  2. Vérifiez que tous les fichiers JAR requis se trouvent dans le chemin d'accès aux classes de jvm.

NoClassDefFoundError

Hiérarchie des classes

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

Pendant le débogage

  1. Problème de chargement dynamique d'une classe, qui a été compilée correctement
  2. Problème avec les blocs statiques, les constructeurs, les méthodes init () de la classe dépendante et l'erreur réelle est enveloppée par plusieurs couches [surtout lorsque vous utilisez spring, hibernate l'exception réelle est enveloppée et vous obtiendrez NoClassDefError]
  3. Lorsque vous faites face à "ClassNotFoundException" sous un bloc statique de classe dépendante
  4. Problème avec les versions de classe. Cela se produit lorsque vous avez deux versions v1, v2 de la même classe sous différents jar / packages, qui ont été compilées avec succès en utilisant v1 et v2 sont chargées à l'exécution qui n'a pas les méthodes / vars pertinentes et vous verrez cette exception. [J'ai résolu ce problème une fois en supprimant le doublon de la classe liée à log4j sous plusieurs pots qui apparaissaient dans le chemin de classe]
Sankarganesh Eswaran
la source
-1

ClassNotFoundException et NoClassDefFoundError se produisent lorsqu'une classe particulière n'est pas trouvée au moment de l'exécution, mais elles se produisent dans différents scénarios.

ClassNotFoundException est une exception qui se produit lorsque vous essayez de charger une classe au moment de l'exécution à l'aide des méthodes Class.forName () ou loadClass () et que les classes mentionnées ne se trouvent pas dans le chemin de classe.

    public class MainClass
    {
        public static void main(String[] args)
        {
            try
            {
                Class.forName("oracle.jdbc.driver.OracleDriver");
            }catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
    }



    java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    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 java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pack1.MainClass.main(MainClass.java:17)

NoClassDefFoundError est une erreur qui se produit lorsqu'une classe particulière est présente au moment de la compilation, mais était manquante au moment de l'exécution.

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

Lorsque vous compilez le programme ci-dessus, deux fichiers .class seront générés. L'un est A.class et un autre est B.class. Si vous supprimez le fichier A.class et exécutez le fichier B.class, Java Runtime System lancera NoClassDefFoundError comme ci-dessous:

    Exception in thread "main" java.lang.NoClassDefFoundError: A
    at MainClass.main(MainClass.java:10)
    Caused by: java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Neeraj Gahlawat
la source