ClassNotFoundException vs NoClassDefFoundError


J'ai parcouru ce fil Quelles sont les causes et quelles sont les différences entre NoClassDefFoundError et ClassNotFoundException? C'est ce que l'un des ans,qui a max ups, dans le fil est : NoClassDefFoundError :"Ainsi, il semble que la NoClassDefFoundError se produit lorsque la source a été compilée avec succès, mais lors de l'exécution, les fichiers de classe requis n'ont pas été trouvés . Cela peut être quelque chose qui peut se produire dans la distribution ou la production de fichiers JAR, où tous les fichiers de classe requis n'ont pas été inclus."

ClassNotFoundException : Quant à ClassNotFoundException, il semble que cela puisse provenir d'essayer de faire des appels réfléchissants aux classes lors de l'exécution, mais les classes que le programme essaie d'appeler n'existent pas.

J'ai fait une petite expérience . J'ai créé une classe principale, class A et j'ai essayé d'appeler une autre classe, class B à partir de celle-ci , compilée avec succès.

Ensuite, j'ai supprimé la classe B qui est en train d'être appelé en classe A. J'ai le java.lang.ClassNotFoundException {[5] } mais selon la réponse dans la bande de roulement, j'aurais dû obtenir NoClassDefFoundError (la source a été compilée avec succès mais au moment de l'exécution, les fichiers de classe n'ont pas été trouvés) Quelqu'un pourrait-il expliquer ce qui me manque dans l'interprétation du sna dans le fil ?

package com.random;

public class A {

    public static void main(String[] args) {
        B b= new B();

    }

}

 package com.random;

public class B {



}
Author: Community, 2015-02-04

10 answers

NoClassDefFoundError

Lancé si la machine virtuelle Java ou une instance de charge dans la définition d'une classe (dans le cadre d'un appel de méthode ou de dans le cadre de la création d'une nouvelle instance à l'aide de la nouvelle expression) et non définition de la classe peut être trouvé.

La définition de classe recherchée existait lors de l'exécution la classe a été compilée, mais la définition ne peut plus être trouver.


ClassNotFoundException

Lancé lorsqu'une application tente de charger dans une classe via sa chaîne nom en utilisant: La méthode forName dans la classe Class. Le findSystemClass méthode dans la classe ClassLoader . La méthode loadClass dans la classe Chargeur de classe.


Vous devez comprendre que le JVM ne peut pas réaliser la définition du class que vous avez supprimé ne peut pas être trouvé, car le class lui-même ne peut pas être trouvé automatiquement jetez le ClassNotFoundException.

Cette exception se produit à runtime donc peu importe s'il a compilé en premier ou non, vous avez supprimé le fichier, donc il ne peut pas être trouvé et lancer le exception.

Notez que NoClassDefFoundError n'est pas réellement une exception, c'est un Error dérivé de LinkageError tandis que ClassNotFoundException dérive directement de java.lang.Exception.

Pour reprendre, le NoClassDefFoundError globalement signifie simplement que le JVM a essayé d'accéder à runtime quelque chose qui, selon le compiled code devrait exister, mais ne le fait pas existe réellement (ou n'est pas dans le classpath).


Exemple pour reproduire ClassNotFoundException

public class ClassNotFoundExceptionExample {

    private static final String CLASS_TO_LOAD = "main.java.Utils";

    public static void main(String[] args) {
        try {
            Class loadedClass = Class.forName(CLASS_TO_LOAD);
            System.out.println("Class " + loadedClass + " found successfully!");
        }
        catch (ClassNotFoundException ex) {
            System.err.println("A ClassNotFoundException was caught: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

Exemple pour reproduire NoClassDefFoundError

Créer une classe simple Test

public class Test {
        public Test() {
                System.out.println("A new instance of the Test class was created!");
        }
}

, Et une classe NoClassDefFoundErrorExample

public class NoClassDefFoundErrorExample {
        private static Test test = new Test();

        public static void main(String[] args) {
                System.out.println("The definition of Test was found!");
        }
}

Créez maintenant un exécutable n .jar qui exécute la méthode main. Vous pouvez le spécifier dans le fichier Manifest.txt dans le .jar

Main-Class: NoClassDefFoundErrorExample

Exécutez maintenant ce qui suit commandes

javac Test.java
javac NoClassDefFoundErrorExample.java
jar cfm NoClassDefFoundErrorExample.jar Manifest.txt NoClassDefFoundErrorExample.class
java -jar NoClassDefFoundErrorExample.jar

Notez le NoClassDefFoundError

Exception in thread "main" java.lang.NoClassDefFoundError: TestClass
    at NoClassDefFoundErrorExample.(NoClassDefFoundErrorExample.java:2)
Caused by: java.lang.ClassNotFoundException: TestClass
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more
 9
Author: Jean-François Savard, 2015-02-04 14:09:01

Eh bien... ClassNotFoundException se produit lorsque le runtime essaie de trouver la classe nommée par certains String par exemple Class.forName(java.lang.String) la méthode prend un argument de chaîne et essaie de trouver la classe avec ce nom. Dans ce cas, le nom de classe est une piqûre et ne peut être vérifié au moment de l'exécution. ici, l'exception dit clairement... cette "classe" n'est pas trouvé. Si... il peut arriver pour deux raisons :

Raison 1. Class-name n'est pas une classe java valide (exemple - "java.Bang.le cerf-volant").

// Example    
Class cdef = Class.forName( "java.bang.kiting" );

Raison 2. Le nom de classe est était un valide de classe... mais de toute façon il n'a pas été emballé avec le pot ou n'est pas résolu dans le chemin de classe. Pour autant que l'exécution sait... il peut être un mauvais nom de la classe... de manière similaire au cas 1.

// Example    
Class cdef =Class.forName( "apache.some.SomeLegitClass" );

Où comme NoClassDefFoundError pour les cas où la référence de classe réelle a été utilisée,

// example
import apache.some.SomeLegitClass
SomeLegitClass i = (SomeLegitClass) instanceOfSomeLegitClass;

Donc, fondamentalement, tout était correct mais d'une manière ou d'une autre, la classe n'est pas emballée avec le jar ( ou plus généralement - n'est pas résolue dans le chemin de classe ). Dans ce cas, nous obtenons NoClassDefFoundError.

Ici runtime sait que le la classe est valide car elle a été compilée avec succès... mais il ne peut pas trouver la"définition de classe".

 9
Author: Sarvesh Kumar Singh, 2015-02-04 14:07:45

La différence dépend de qui a demandé à la classe d'être chargée :

  • ClassNotFoundException est lancé lorsque le code essaie directement de charger une classe , en passant l'argument String représentant un nom complet de la classe.
    • par exemple Class.forName(String), ou ClassLoader.loadClass(String).
  • NoClassDefFoundError est lancé lorsque la JVM est invitée à charger une classe indirectement .
    • par exemple, lorsque la classe A utilise la classe B et que la classe B n'est pas sur classpath, NoClassDefFoundError sera jetée.
 5
Author: Crazyjavahacking, 2015-02-04 14:00:22

NoClassDefFoundError est généralement appelé lorsque vous utilisez une bibliothèque(par exemple, Goyave, Gson, CommonsIO). Vous mettez la bibliothèque dans classpath de votre projet, mais vous ne l'avez pas exportée ensemble, vous obtiendrez un NoClassDefFoundError lorsque l'application est en cours d'exécution.

Comment obtenir NoClassDefFoundError:
Créez un nouveau projet, avec cette classe.

public class A
{
    public void do()
    {
        System.out.println("Do!");
    }
}  

Exportez-le en tant que fichier .jar.

Maintenant, créez un autre projet. Ajoutez le fichier jar exporté à classpath.

import ???.A;
public class Main
{
    public static void main(String[] args)
    {
        A a = new A();
        a.do();//NoClassDefFoundError thrown at here.
    }
} 

Exportez le projet, assurez-vous de ne pas inclure le fichier jar(avec la classe A). Exécutez le fichier jar nouvellement exporté, vous verrez cette erreur!

 2
Author: Jeremy, 2015-02-04 14:02:21

1) Je ne sais pas si c'est le cas.]}

  1. Cela se produit, quand nous essayons de charger une classe au moment de l'exécution à l'aide de Class.forName() ou ClassLoader.loadClass() ou ClassLoader.findSystemClass() méthodes, et il pourrait pas trouver la classe requise dans le chemin de classe.
  2. Dans ce cas, nous devrions vérifier le class path et ajouter la classe dans le chemin de la classe si elle est manquante.
  3. Il s'agit d'une exception vérifiée, qui est dérivée de java.lang.Exception classe .
  4. Ceci relève explicite chargement.

2) NoClassDefFoundError

  1. Cela se produit lorsque la classe était présente pendant le compile time et n'est pas disponible pendant run time pour certaines raisons. Cela signifie que la classe qui est chargée est present dans classpath, mais l'un des classe(s)dépendants requis par cette classe est suppriméou a échoué à charger par le compilateur.

  2. Dans ce cas, nous il suffit de vérifier le classes which are dependent on this class.

  3. Ceci est une erreur , qui est dérivée de java.lang.LinkageError.
  4. Cela vient sous chargement implicite.

 1
Author: Rohit Gaikwad, 2016-10-19 04:22:40

Comme mentionné dans les réponses précédentes, NoClassDefFoundError se produira lorsque la classe était présente pendant la compilation et n'est pas disponible pendant l'exécution pour certaines raisons.

Il y a un autre scénario que je souhaite ajouter, qui pourrait également entraîner NoClassDefFoundError.

Lorsque vous essayez de charger une classe qui n'a pas réussi à se charger en raison d'une exception, par exemple un échec dans le bloc d'initialisation statique, le système vous lancera ExceptionInInitializerError. Si vous essayez de charger le même classe à nouveau (qui n'a pas réussi à charger précédemment), le système lancera NoClassDefFoundError

Permet de l'explorer avec un échantillon

ClassWithStaticBlock.java

public class ClassWithStaticBlock {

    static {
       int total = 1/0;
    }
}

Principal.java

public class Main {

public static void main(String[] args) {
    ClassWithStaticBlock cs;
    try {
       cs = new ClassWithStaticBlock();
    }catch(Throwable e){
        e.printStackTrace();
    }
  }
}

Résultat:

java.lang.ExceptionInInitializerError
    at Main.main(Main.java:6)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ArithmeticException: / by zero
    at ClassWithStaticBlock.<clinit>(ClassWithStaticBlock.java:7)
    ... 6 more

Permet de modifier Principal.java

public class Main {

    public static void main(String[] args) {
        ClassWithStaticBlock cs;
        try {
           cs = new ClassWithStaticBlock();
        }catch(Throwable e){
            e.printStackTrace();
        }
        cs = new ClassWithStaticBlock(); //try to use ClassWithStaticBlock again
    }
}

Résultat:

java.lang.ExceptionInInitializerError
    at Main.main(Main.java:6)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ArithmeticException: / by zero
    at ClassWithStaticBlock.<clinit>(ClassWithStaticBlock.java:7)
    ... 6 more
Exception in thread "Main Thread" java.lang.NoClassDefFoundError: ClassWithStaticBlock
    at Main.main(Main.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Lorsque nous essayons à nouveau d'utiliser ClassWithStaticBlock (qui n'a pas réussi à s'initialiser plus tôt), le système lance NoClassDefFoundError.

Trouvé l'exemple de Pourquoi est-ce que je reçois une NoClassDefFoundError en Java?

 1
Author: IamVickyAV, 2017-05-23 12:32:08

L'un des cas où NoClassDefFoundError se produit est lorsque la classe JVM essaie d'accéder n'est pas trouvée dans classpath. Mais si class est présent dans classpath, Cela entraînera ClassNotFoundException.

En bref, NoClassDefFoundError viendra si une classe était présente pendant la compilation mais non disponible dans java classpath pendant l'exécution.

Essayez simplement de s'exécuter avec l'option explicit-classpath où le classpath ne contient pas de classe B.

 0
Author: Ajit Lakhwani, 2015-02-04 13:59:51

ClassNotFoundException et NoClassDefFoundError se produisent lorsqu'une classe particulière n'est pas trouvée 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 en utilisant Class.Les méthodes forName() ou loadClass() et 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 à l'exécution temps.

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 .les fichiers de classe seront générés. L'un est A.class et un autre est B.class. Si vous supprimez le A.class fichier et exécuter le B.class fichier, 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)
 0
Author: Neeraj Gahlawat, 2017-08-18 10:06:41

Tout sur ClassNotFoundException Vs NoClassDefFoundError l'article explique très clairement la différence entre ClassNotFoundException et NoClassDefFoundError avec exemple et selon lui.

ClassNotFoundException Vs NoClassDefFoundError Programming Programmation Mitra

Je ne sais pas si c'est le cas.]}

Est une exception vérifiée qui se produit lorsque nous disons à la JVM de charger une classe par son nom de chaîne en utilisant Class.forName () ou ClassLoader.findSystemClass () ou ClassLoader.Méthodes loadClass () et 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 lorsque vous effectuez le code JDBC pour vous connecter à votre base de données, c'est-à-dire MySQL, mais votre classpath n'a pas le jar pour cela.

public class Test {
    public static void main(String[] args) throws Exception {

        // Provide any class name to Class.forName() which does not exist
        // Or compile Test.java and then manually delete Person.class file so Person class will become unavailable
        // Run the program using java Test

        Class clazz = Class.forName("Person");
        Person person = (Person) clazz.newInstance();
        person.saySomething();
    }
}

class Person {
    void saySomething() {
        System.out.println("Hello");
    }
}

NoClassDefFoundError

Est un sous-type de java.lang.Error et Error class indiquent un comportement anormal qui ne devrait vraiment pas se produire avec une application mais et les développeurs d'applications ne devraient pas essayer de l'attraper, il est là pour une utilisation JVM uniquement.

NoClassDefFoundError se produit lorsque JVM essaie de charger une classe particulière qui fait partie de votre exécution de 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ésente une classe qui n'est pas présent compilateur va déclencher une erreur de compilation.

public class Test {
    public static void main(String[] args) throws Exception {

        // Do javac on Test.java, 
        // Program will compile successfully because Empoyee class exits
        // Manually delete Employee.class file
        // Run the program using java Test
        Employee emp = new Employee();
        emp.saySomething();

    }
}

class Employee {
    void saySomething() {
        System.out.println("Hello");
    }
}

 0
Author: Naresh Joshi, 2018-01-20 07:46:41

Les autres réponses dans ce fil sont correctes, je veux juste ajouter quelque chose que j'ai passé des heures à essayer de comprendre. Même si

Class.forName("apache.some.SomeLegitClass")

Fonctionne,

Class.forName("apache.some.somelegitclass")

Entraînera une NoClassDefFoundError. classe.forName () est sensible à la casse. Il en résultera différentes exceptions si le nom de classe est mal orthographié ou a simplement un boîtier incorrect.

 -1
Author: Nils-Erik, 2016-07-05 13:20:29