Quelle est la difference entre NoClassDefFoundError
et 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:
- packages non inclus dans
build.xml
le côté client du code - chemin de classe d'exécution manquant pour les nouveaux pots que nous utilisons
- 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.
-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 :(Réponses:
La différence par rapport aux spécifications de l'API Java est la suivante.
Pour
ClassNotFoundException
:Pour
NoClassDefFoundError
:Il apparaît donc que cela
NoClassDefFoundError
se produit lorsque la source a été compilée avec succès, mais au moment de l'exécution, lesclass
fichiers requis sont introuvables. Cela peut se produire dans la distribution ou la production de fichiers JAR, où tous lesclass
fichiers 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
Error
et l'autre est unException
. AvecNoClassDefFoundError
est unError
et 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 declass
fichiers 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é,
ClassNotFoundException
c'est unException
, 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) .la source
NoClassDefFoundError
se 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.Error
et l'autre est unException
. :)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.NoClassDefFoundError
avecjava.lang.ClassNotFoundException
mais il existe une distinction importante. Par exemple, une exception (une erreur étant vraimentjava.lang.NoClassDefFoundError
une sous-classe de java.lang.Error) commene 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.
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.
la source
NoClassDefFoundError
est 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.ClassNotFoundException
est 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 deloadClass()
ouClass.forName()
.la source
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:
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 appelantjava -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:
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.
la source
-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.-verbose:class
ni-verbose:jni
sortie supplémentaire pertinente pour la classe manquante.-verbose:class:jni
c'est faux: il faut spécifier deux options distinctes-verbose:class -verbose:jni
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 :
Maintenant, après avoir compilé les deux classes, si vous supprimez le fichier Test1.class et exécutez la classe Test, il lancera
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.la source
-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.-verbose:class:jni
est faux, mais vous pouvez passer deux options distinctes:-verbose:class -verbose:jni
.Ils sont étroitement liés. Un
ClassNotFoundException
est levé lorsque Java a recherché une classe particulière par son nom et n'a pas pu la charger avec succès. UnNoClassDefFoundError
est 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.la source
Exemple 1:
Si
com/example/Class1
n'existe dans aucun des chemins de classe, alors il lanceClassNotFoundException
.Exemple # 2:
Si
com/example/Class2
existé lors de la compilation de B, mais non trouvé lors de l'exécution, il lanceNoClassDefFoundError
.Les deux sont des exceptions d'exécution.
la source
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
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.
la source
Différence entre ClassNotFoundException et NoClassDefFoundError
la source
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.
source d'image
Différence:
ClassNotFoundException:
ClassNotFoundException
.ClassNotFoundException
est une exception vérifiée dérivée directement de lajava.lang.Exception
classe et vous devez en fournir une gestion expliciteClassNotFoundException
s'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:
NoClassDefFoundError
.NoClassDefFoundError
est une erreur dérivée de laLinkageError
classe, 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.NoClassDefFoundError
est 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:
NoClassDefFoundError
etClassNotFoundException
sont liés à l'indisponibilité d'une classe au moment de l'exécution.ClassNotFoundException
etNoClassDefFoundError
sont liés au chemin de classe Java.la source
Étant donné les actions du système de chargement de classe:
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
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 .
la source
Ajoutez une raison possible dans la pratique:
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.
la source
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
Vous pouvez lire tout sur ClassNotFoundException Vs NoClassDefFoundError pour plus de détails.
la source
Je me rappelle ce qui suit encore et encore quand j'ai besoin de me rafraîchir
ClassNotFoundException
Hiérarchie des classes
Pendant le débogage
NoClassDefFoundError
Hiérarchie des classes
Pendant le débogage
la source
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.
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.
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:
la source