382 votes

Quelle est la différence entre NoClassDefFoundError et ClassNotFoundException ?

Je veux savoir la différence entre l'erreur spécifiée et l'exception.

Quelle est la raison pour obtenir chacun d'eux et de tout processus de pensée sur la façon de traiter avec de telles erreurs?

Tout en travaillant sur un projet. Si nous sommes en train de modifier le code existant pour inclure le nouveau fichier jar-je obtenir pour faire face à ces exceptions. Parfois, ils vont venir à côté client ou côté serveur pour une application java distribué par webstart.

Les raisons possibles que j'ai rencontré:

  1. paquets qui ne sont pas inclus dans build.xml pour le côté client de code
  2. runtime classpath manquer pour les nouveaux pots de nous à l'aide de
  3. des conflits de version précédente avec jar

Mais comme de maintenant, je m'occupe de frapper et d'essai méthode pour obtenir des choses de travail.

Besoin de plus de clarté et de compréhension à ce sujet.

392voto

coobird Points 70356

La différence de l'API Java cahier des charges est comme suit.

Pour ClassNotFoundException:

Levée lorsqu'une application tente d' charge dans une classe par le biais de sa chaîne nom de l'aide:

  • L' forName méthode dans la classe Class.
  • L' findSystemClass méthode dans la classe ClassLoader.
  • L' loadClass méthode dans la classe ClassLoader.

mais pas de définition de la classe avec l' le nom spécifié peut être trouvé.

Pour NoClassDefFoundError:

Levée si la Machine Virtuelle Java ou un ClassLoader instance essaie de charger dans la définition d'une classe (dans le cadre d'un appel de méthode ou dans le cadre de la création d'une nouvelle instance à l'aide de la nouvelle d'expression) et de l'absence de définition de la la classe peut être trouvé.

L'objet d'une recherche de la définition de classe existait lorsque le cours d'exécution de classe a été établi, mais la définition ne peut plus être trouvé.

Ainsi, il apparaît que l' NoClassDefFoundError se produit lorsque la source a été compilé avec succès, mais au moment de l'exécution, l' class 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ù tous les requis class 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 un Exception. Avec NoClassDefFoundError est Error 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 en raison d' class 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, l' ClassNotFoundException est Exception, 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.

83voto

Sanjiv Jivan Points 725

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 chargeurs de classe).

Souvent, les gens ont tendance à confondre java.lang.NoClassDefFoundError avec java.lang.ClassNotFoundException toutefois, il y a une distinction importante. Par exemple, une exception (une erreur vraiment depuis java.lang.NoClassDefFoundError est une sous-classe de java.lang.D'erreur) comme

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

ne 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.

À 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.

private static SomeClass foo = new SomeClass();

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.

36voto

cletus Points 276888

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().

30voto

mogsie Points 1998

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:

class a {
 statique de la classe b {}
 public static void main(String args[]) {
 Système..println("Première tentative new b():");
 try {new b(); } catch(Throwable t) {t.printStackTrace();}
 Système..println("\ndeuxième tentative new b():");
 try {new b(); } catch(Throwable t) {t.printStackTrace();}
}
}

l'enregistrer comme a.java quelque part

Il suffit que 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 invoquant java -cp . a -- il faut juste imprimer deux lignes de texte, et il doit s'exécuter correctement et sans erreurs.

Ensuite, supprimer le "$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:

Première tentative new b():
java.lang.NoClassDefFoundError:$b
 à un.principal(un.java:5)
Causés par: java.lang.ClassNotFoundException:$b
 à java.net.URLClassLoader$1.exécuter(URLClassLoader.java:200)
 à java.de sécurité.AccessController.doPrivileged(Native method)
 à java.net.URLClassLoader.findClass(URLClassLoader.java:188)
 à java.lang.Chargeur de classe.loadClass(ClassLoader.java:307)
 au coucher du soleil.misc.Lanceur$AppClassLoader.loadClass(Lanceur.java:301)
 à java.lang.Chargeur de classe.loadClass(ClassLoader.java:252)
 à java.lang.Chargeur de classe.loadClassInternal(ClassLoader.java:320)
 ... 1 de plus

Deuxième tentative new b():
java.lang.NoClassDefFoundError:$b
 à un.principal(un.java:7)

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 seconde 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.

15voto

Donal Fellows Points 56559

Quelle est la raison pour obtenir chacun d'eux et de tout processus de pensée sur la façon de traiter avec de telles erreurs?

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. Un NoClassDefFoundError 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 manquement à l' 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.

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