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