Quelles sont les causes et quelles sont les différences entre NoClassDefFoundError et ClassNotFoundException?
Quelle est la différence entre NoClassDefFoundError
et ClassNotFoundException
?
Ce qui les pousse à être jetés? Comment peuvent-ils être résolus?
Je rencontre souvent ces throwables lors de la modification du code existant pour inclure de nouveaux fichiers jar.
J'ai frappé sur le côté client et côté serveur pour une application java distribué par webstart.
Raisons que j'ai rencontré:
- paquets qui ne sont pas inclus dans
build.xml
pour le côté client de code - runtime classpath manquer pour les nouveaux pots de nous à l'aide de
- version conflits avec les précédentes pot
Quand je rencontre ces aujourd'hui, je prends un sentier-et-approche de l'erreur pour obtenir des choses de travail. J'ai besoin de plus de clarté et de compréhension.
- Je trouve souvent l'exécution de la JVM avec
-verbose
(par exemple-verbose:class -verbose:jni
) aide — mais mogsie rapports ci-dessous leur réponse que cette offre sans supplément de l'information utile 🙁
Vous devez vous connecter pour publier un commentaire.
La différence de l'API Java cahier des charges est comme suit.
Pour
ClassNotFoundException
:Pour
NoClassDefFoundError
:Ainsi, il apparaît que la
NoClassDefFoundError
se produit lorsque la source a été compilé avec succès, mais au moment de l'exécution, leclass
les fichiers n'ont pas été trouvés. Cela peut être quelque chose qui peut arriver dans la distribution ou la production de fichiers JAR, où pas tous lesclass
fichiers ont été inclus.Comme pour
ClassNotFoundException
, il semble que cela peut provenir d'essayer de faire réfléchissant appels à des classes au moment de l'exécution, mais les classes, le programme tente d'appel 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 se pose à partir de la Machine Virtuelle Java d'avoir des problèmes pour trouver une classe, il s'attendait à trouver. Un programme qui a été prévu pour fonctionner au moment de la compilation ne peut pas s'exécuter carclass
fichiers ne sont pas trouvés, ou n'est pas la même qu'a été produite ou rencontrés au moment de la compilation. C'est plutôt une erreur critique, comme le programme ne peut être lancé par la JVM.D'autre part, la
ClassNotFoundException
est unException
, donc c'est un peu attendu, et c'est quelque chose qui est récupérable. L'utilisation de la réflexion est peut être sujette à des erreurs (comme il existe des attentes que les choses ne peuvent pas aller comme prévu. Il n'existe pas au moment de la compilation vérifiez que toutes les classes existent, de sorte que tout problème avec trouver le désiré des classes apparaît lors de l'exécution.NoClassDefFoundError
se produit généralement lorsqu'il y a problème (à l'exception levée) avec le bloc statique ou les champs statiques de l'initialisation de la classe, la classe ne peut pas être initialisé correctement.Error
et l'autre est unException
. 🙂Une ClassNotFoundException est générée si la déclaration de la classe n'est pas trouvé par le chargeur de classe. Généralement, cela signifie que la classe est manquant dans le CLASSPATH. Il peut également signifier que la classe en question est d'essayer d'être chargé d'une autre classe qui a été chargé dans un chargeur de classe parent et donc la classe de l'enfant du chargeur de classe n'est pas visible. C'est parfois le cas lorsque l'on travaille dans des environnements plus complexes comme un Serveur d'Application (WebSphere est tristement célèbre pour ces classloader questions).
Souvent, les gens ont tendance à confondre
java.lang.NoClassDefFoundError
avecjava.lang.ClassNotFoundException
toutefois, il y a une distinction importante. Par exemple, une exception (une erreur vraiment depuisjava.lang.NoClassDefFoundError
est une sous-classe de java.lang.D'erreur) commene signifie pas que le ActiveMQConnectionFactory classe n'est pas dans le CLASSPATH. En effet son tout à fait le contraire. Cela signifie que la classe ActiveMQConnectionFactory a été trouvé par le chargeur de classe, cependant lorsque vous essayez de charger la classe, il a heurté une erreur de lecture de la définition de la classe. Cela se produit généralement lorsque la classe en question a des blocs statiques ou les membres qui utilisent une Classe qui n'est pas trouvé par le chargeur de classe. Afin de trouver le coupable, affichez le code source de la classe en question (ActiveMQConnectionFactory dans ce cas) et de regarder le code à l'aide de blocs statiques ou des membres statiques. Si vous n'avez pas accès à la source, puis il suffit de le décompiler l'aide de JAD.
Sur l'examen du code, disons que vous avez trouvé une ligne de code comme ci-dessous, assurez-vous que la classe SomeClass dans votre CLASSPATH.
Astuce : Pour trouver jar une classe appartient, 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 de recherche pour la classe dans sa base de données des jarres. jarhoo vous permet de faire la même chose, mais il n'est plus libre de l'utiliser.
Si vous souhaitez localiser le jar une classe appartient à un chemin d'accès local, vous pouvez utiliser un utilitaire comme jarscan ( http://www.inetfeedback.com/jarscan/ ). Vous venez de spécifier la classe que vous souhaitez localiser et à la racine du chemin d'accès au répertoire où vous souhaitez commencer la recherche de la classe dans les pots et les fichiers zip.
NoClassDefFoundError est un lien d'erreur en fait. Elle se produit lorsque vous essayez d'instancier un objet (de manière statique avec les "nouvelles") et il ne l'est pas quand il était lors de la compilation.
ClassNotFoundException est plus général, et est 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 que 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 la dynamique de chargement de classe, comme l'utilisation de loadClass() ou de la Classe.forName().
Un NoClassDefFoundError (NCDFE) se produit lorsque votre code s'exécute "nouveau" (Y)" et il ne peut pas trouver la classe y.
Il peut être tout simplement que Y est absent de votre chargeur de classe comme les autres commentaires le suggèrent, mais il se pourrait que la classe Y n'est pas signé ou une signature non valide, ou que Y est chargé par un chargeur de classe n'est pas visible de votre code, ou même que Y dépend de Z qui ne pouvaient pas être chargés pour l'une des raisons ci-dessus.
Si cela se produit, la JVM va mémoriser le résultat de chargement X (NCDFE) et il va tout simplement jeter un nouveau NCDFE chaque fois que vous demandez pour Y sans vous dire pourquoi:
l'enregistrer comme a.java quelque part
Le code tente d'instancier une nouvelle classe "b" à deux reprises, d'autres que cela, il n'a pas de bugs, et il ne faut pas faire n'importe quoi.
Compiler le code avec
javac a.java
, Puis exécutez un en invoquantjava -cp . a
-- il faut juste imprimer deux lignes de texte, et il doit s'exécuter correctement et sans erreurs.Puis supprimer le "un$b.class" fichier (ou le remplir avec des ordures, ou de les copier a.class sur celui-ci) pour simuler manquant ou endommagé de classe. Voici ce qui arrive:
La première invocation résultats dans une ClassNotFoundException (jeté par le chargeur de classe quand il ne peut pas trouver la classe), qui doit être enveloppé dans un décoché NoClassDefFoundError, depuis que le code en question (
new b()
) devrait fonctionner.La deuxième tentative sera bien sûr aussi échouer, mais comme vous pouvez le voir la enveloppé exception, pas plus, parce que le chargeur de classe semble se rappeler échec de la classe chargeurs. Vous ne voyez que le NCDFE avec absolument aucune idée de ce qui s'est réellement passé.
Donc si jamais vous voyez un NCDFE sans cause, vous devez voir si vous pouvez remonter à la première fois, la classe a été chargé de trouver la cause de l'erreur.
-verbose
, ou d'une même option en fonction de la spécificité de la JVM? Probablement-verbose:class
, peut-être-verbose:class:jni
si l'utilisation de JNI, mais je ne suis pas sûr de la syntaxe. Si cela est utile, peut-être que vous pourriez montrer les résultats.-verbose:class
ni-verbose:jni
donner toute sortie supplémentaires pertinentes à la catégorie manquante.-verbose:class:jni
est faux: on doit spécifier séparément les deux options:-verbose:class -verbose:jni
.)De http://www.javaroots.com/2013/02/classnotfoundexception-vs.html:
ClassNotFoundException
: se produit lorsque le chargeur de classe ne pouvait pas trouver la classe requise dans le chemin de classe. Donc, fondamentalement, vous devriez vérifier votre chemin de classe et ajouter la classe dans le classpath.NoClassDefFoundError
: c'est plus difficile à déboguer et de trouver la raison. C'est renvoyée lorsqu'au moment de la compilation les classes nécessaires sont présents, mais au moment de l'exécution, les classes sont modifiés ou supprimés, ou de la classe statique initialise jeté des exceptions. Cela signifie que la classe qui s'est chargé de présenter dans le classpath, mais l'une des classes qui sont requis par cette classe sont soit supprimé ou n'a pas de charge par le compilateur. Vous devriez donc voir les classes qui dépendent de cette classe.Exemple:
Maintenant, après la compilation de deux classes, si vous supprimez Test1.class fichier et de l'exécuter de la classe de Test, il va jeter
ClassNotFoundException
: levée lorsqu'une application tente de charger dans une classe par le biais de son nom, mais pas de définition de la classe avec le nom spécifié peut être trouvé.NoClassDefFoundError
: levée si la Machine Virtuelle Java essaie de charger dans la définition d'une classe et de l'absence de définition de la classe peut être trouvé.-verbose
, ou d'une même option en fonction de la spécificité de la JVM? Probablement-verbose:class
, peut-être-verbose:class:jni
si l'utilisation de JNI, mais je ne suis pas sûr de la syntaxe.-verbose:class:jni
est mauvais, mais vous pouvez passer deux options distinctes:-verbose:class -verbose:jni
.Ils sont étroitement liés. Un
ClassNotFoundException
est levée lorsque Java est allé à la recherche d'une classe par nom et n'a pas réussi à charger. UnNoClassDefFoundError
est levée lorsque Java est allé à la recherche pour une classe qui a été lié dans le code existant, mais ne le trouva pas, pour une raison ou une autre (par exemple, mauvais chemin de classe, d'une mauvaise version de Java, d'une mauvaise version de bibliothèque) et est complètement irrécupérable, car il indique que quelque chose a vraiment Mal tourné.Si vous avez un C en arrière-plan, un CNFE est comme un défaut 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 ne devraient jamais ont été compilés dans la configuration que vous tentez de les utiliser.Exemple #1:
Si
com/example/Class1
n'existe pas dans les chemins de classe, puis Il jetteClassNotFoundException
.Exemple #2:
Si
com/example/Class2
existé lors de la compilation de B, mais pas trouvé lors de l'exécution, puis Il jetteNoClassDefFoundError
.Les deux sont de l'exécution des exceptions.
ClassNotFoundException est levée lorsqu'il y a tentative de chargement de la classe par le référencement par l'intermédiaire d'une Chaîne. Par exemple le paramètre dans la Classe.forName() est une Chaîne de caractères, et cela soulève la possibilité d'invalide binaire noms passés à la classloader.
ClassNotFoundException est levée lorsqu'une potentiellement invalide nom binaire est rencontré; par exemple, si le nom de la classe a le caractère'/', vous êtes lié pour obtenir une ClassNotFoundException. Il est également levée lorsque les directement référencé classe n'est pas disponible dans le classpath.
D'autre part, NoClassDefFoundError est jeté
En bref, un NoClassDefFoundError est généralement jeté sur new() des déclarations ou des appels de méthode que de charger un auparavant absents de la classe (par opposition à la chaîne de chargement à base de classes pour ClassNotFoundException), lorsque le chargeur de classe est impossible de trouver ou charger la classe de définition(s).
Finalement, c'est jusqu'à le chargeur de classe de mise en œuvre de lancer une instance de ClassNotFoundException lorsqu'il est impossible de charger une classe. La plupart des classloader personnalisé implémentations effectuer cela, car ils étendent la URLClassLoader. Habituellement, les chargeurs de classe ne sont pas explicitement jeter un NoClassDefFoundError sur les implémentations de méthode - cette exception est généralement générée à partir de la JVM dans le HotSpot du compilateur, et non pas par le chargeur de classe elle-même.
Différence Entre ClassNotFoundException Vs NoClassDefFoundError
Exception: Exceptions se produit pendant l'exécution du programme. Un programmeur peut gérer ces exceptions par essayer bloc catch. Nous avons deux types d'exceptions. Vérifié exception qui déclenche au moment de la compilation. Des Exceptions d'exécution qui sont lancés au moment de l'exécution, ces exception se produisent généralement à cause d'une mauvaise programmation.
Erreur: ce ne sont pas des exceptions à tout, il est au-delà de la portée de programmeur. Ces erreurs sont généralement jeté par la JVM.
source de l'image
Différence:
ClassNotFoundException:
ClassNotFoundException
.ClassNotFoundException
est un checked Exception provenant directement dejava.lang.Exception
classe et vous devez fournir explicite pourClassNotFoundException
vient quand il y a un chargement explicite de classe est en cause en lui fournissant le nom de la classe au moment de l'exécution à l'aide du chargeur de classe.loadClass(), la Classe.forName() et le chargeur de classe.findSystemClass().NoClassDefFoundError:
NoClassDefFoundError
.NoClassDefFoundError
est une Erreur provenant deLinkageError
classe, qui est utilisé pour indiquer les cas d'erreur, où une classe a une dépendance sur une autre classe et que la classe a incompatibilité changé après la compilation.NoClassDefFoundError
est un résultat de chargement implicite de classe en raison d'un appel de méthode à partir de la classe ou de la variable d'accès.Similitudes:
NoClassDefFoundError
etClassNotFoundException
sont liés à une indisponibilité de la classe au moment de l'exécution.ClassNotFoundException
etNoClassDefFoundError
sont liés à Java classpath.Donné le chargeur de Classe sussystem actions:
C'est un article qui m'a beaucoup aidé à comprendre la différence: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
Donc un ClassNotFoundException est l'une des causes de NoClassDefFoundError.
Et un NoClassDefFoundError est un cas particulier de type erreur de chargement, qui se produit à Reliant étape.
Ajouter une raison possible dans la pratique:
Dans la pratique, Erreur peuvent être jetés silencieusement, e.g, vous pouvez envoyer un timer de la tâche et de la minuterie tâche il jette Erreur, alors que dans la plupart des cas, votre programme, les captures Exception. Puis le Minuterie boucle principale est terminée sans aucune information. Une Erreur similaire à NoClassDefFoundError est ExceptionInInitializerError, lorsque votre initialiseur statique ou l'initialiseur, pour une variable statique déclenche une exception.
Je me rappelle le suivant, encore et encore, quand j'en ai besoin pour actualiser
ClassNotFoundException
Hiérarchie De Classe
Pendant le débogage
NoClassDefFoundError
Hiérarchie De Classe
Pendant le débogage
Ce qui se passe quand vous avez deux versions v1, v2 de la même classe sous différentes jar/packages, qui a été compilé avec succès à l'aide de v1 et v2 est chargé de l'exécution qui n'est pas a la pertinence des méthodes/vars& vous verrez cette exception. [Une fois, j'ai résolu ce problème en supprimant le double de log4j liées à la classe sous plusieurs pots qui est apparu dans le chemin de classe]
ClassNotFoundException est un checked exception qui se produit quand nous disons à la JVM pour charger une classe par son nom de chaîne à l'aide de la Classe.forName() ou chargeur de classe.findSystemClass() ou chargeur de classe.loadClass() les méthodes et les cités de la classe n'est pas trouvé dans le classpath.
La plupart du temps, cette exception se produit lorsque vous essayez d'exécuter une application sans mise à jour du classpath avec les fichiers JAR requis. Par Exemple, Vous pouvez avoir vu cette exception lorsque vous faites le code JDBC pour se connecter à votre base de données que je.e.MySQL mais votre classpath n'a pas de POT pour elle.
NoClassDefFoundError erreur se produit lors de la JVM essaie de charger une classe particulière qui est la partie de votre code d'exécution (dans le cadre d'un appel de méthode ou dans le cadre de la création d'une instance à l'aide du mot clé new) et que la classe n'est pas présent dans votre classpath, mais était présent au moment de la compilation, car, pour l'exécution de votre programme, vous devez le compiler et si vous essayez d'utiliser une classe qui n'est pas présent compilateur va augmenter d'erreur de compilation.
Ci-dessous une brève description
Vous pouvez lire Tout À Propos De ClassNotFoundException Vs NoClassDefFoundError pour plus de détails.
ClassNotFoundException et NoClassDefFoundError se produire lorsqu'une classe particulière n'est pas trouvé lors de l'exécution.Cependant, ils se produisent à 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 de la Classe.forName() ou loadClass() les méthodes et mentionné les classes ne sont pas trouvés dans le classpath.
NoClassDefFoundError est une erreur qui se produit lorsqu'une classe est présent au moment de la compilation, mais était absent au moment de l'exécution.
Lorsque vous compilez le programme ci-dessus, deux .les fichiers de classe sera généré. L'un est A.class et un autre est B.class. Si vous supprimez le A.class fichier et exécutez l'B.class fichier, le Système d'Exécution de Java va jeter NoClassDefFoundError comme ci-dessous: