Pregunta

¿Cuál es la diferencia entre NoClassDefFoundError y ClassNotFoundException?

Es lo que los hace ser lanzado?Cómo se pueden resolver?

A menudo me encuentro con estos throwables al modificar el código existente para incluir nuevos archivos jar.Me han golpeado tanto en el lado cliente y del lado del servidor de una aplicación java distribuidos a través de webstart.

Posibles razones por las que me he encontrado:

  1. los paquetes que no están incluidos en build.xml por el lado del cliente de código
  2. tiempo de ejecución classpath falta para el nuevo frascos estamos utilizando
  3. conflictos de versión con la anterior jar

Cuando me encuentro con estas, hoy me tomo un sendero-y-error de enfoque para conseguir que las cosas funcionen.Necesito más claridad y comprensión.

¿Fue útil?

Solución

La diferencia con las especificaciones de API de Java es la siguiente.

En ClassNotFoundException :

  

Se lanza cuando una aplicación intenta   carga en una clase a través de su cadena de   nombrar usando:

     
      
  • El método forName en Class clase.
  •   
  • El método findSystemClass en ClassLoader clase.
  •   
  • El método loadClass en ClassLoader clase.
  •   
     

pero no hay una definición de la clase con   el nombre especificado se pudo encontrar.

En NoClassDefFoundError :

  

Lanzado si la máquina virtual de Java o   una instancia ClassLoader intenta cargar   en la definición de una clase (como parte   de una llamada de método normal o como parte de   la creación de una nueva instancia utilizando el nuevo   expresión) y no hay una definición de la   clase se pudo encontrar.

     

La definición de clase buscadas   existido cuando la ejecución de la actualidad   clase fue compilado, pero la definición   Ya no se puede encontrar.

Por lo tanto, parece que la NoClassDefFoundError se produce cuando la fuente se compila con éxito, pero en tiempo de ejecución, no se encontraron los archivos class requeridos. Esto puede ser algo que puede suceder en la distribución o producción de archivos JAR, en los que no se incluyeron todos los archivos requeridos class.

En cuanto a ClassNotFoundException, parece que puede provenir de tratar de hacer llamadas reflectantes a clases en tiempo de ejecución, pero se no existe las clases del programa está intentando llamar.

La diferencia entre los dos es que uno es un Error y el otro es un Exception. Con NoClassDefFoundError es un Error y se deriva de las máquina virtual Java tener problemas para encontrar una clase que esperaba encontrar. Un programa que se espera que funcione en tiempo de compilación no se puede ejecutar debido a class archivos no se encuentra, o no es lo mismo que fue producido o que se encuentran en tiempo de compilación. Este es un error bastante crítico, ya que el programa no puede ser iniciado por la JVM.

Por otro lado, el ClassNotFoundException es un Exception, por lo que se espera un poco, y es algo que es recuperable. El uso de la reflexión se puede ser propenso a errores (ya que hay algunas expectativas de que las cosas no pueden ir como se esperaba. No hay ninguna comprobación en tiempo de compilación para ver que se dan todas las clases requeridas, por lo que cualquier problema con la búsqueda de las clases deseadas aparecerá en tiempo de ejecución .

Otros consejos

A ClassNotFoundException se produce cuando la clase no se encuentra reportado por el cargador de clases. Normalmente, esto significa que la clase no se encuentra en el CLASSPATH. También podría significar que la clase en cuestión está tratando de ser cargado de otra clase, que estaba cargado en un cargador de clases padre y por lo tanto la clase desde el cargador de clases niño no es visible. Esto a veces es el caso cuando se trabaja en entornos más complejos, como un servidor de aplicaciones (WebSphere es famoso por estas cuestiones cargador de clases).

A menudo la gente tiende a confundir con java.lang.NoClassDefFoundError java.lang.ClassNotFoundException sin embargo hay una distinción importante. Por ejemplo una excepción (un error realmente desde java.lang.NoClassDefFoundError es una subclase de java.lang.Error) como

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

no significa que la clase ActiveMQConnectionFactory no está en el CLASSPATH. Infact es bastante lo contrario. Esto significa que el ActiveMQConnectionFactory clase fue encontrado por el cargador de clases, sin embargo cuando se trata de cargar la clase, se topó con un error al leer la definición de clase. Esto suele ocurrir cuando la clase en cuestión tiene bloques estáticos o miembros que utilizan una clase que no es encontrado por el cargador de clases. Así que para encontrar al culpable, ver el código fuente de la clase en cuestión (ActiveMQConnectionFactory en este caso) y buscarse un código usando bloques estáticos o miembros estáticos. Si no tiene acceso a la fuente, a continuación, simplemente descompilarlo usando JAD.

Al examinar el código, digamos que encontrar una línea de código, como a continuación, asegúrese de que la clase SomeClass en en su CLASSPATH.

private static SomeClass foo = new SomeClass();

Consejo: Para averiguar qué frasco de una clase pertenece, puede utilizar la página web jarFinder. Esto le permite especificar un nombre de clase, utilizando los patrones y se busca la clase en su base de datos de los frascos. jarhoo le permite hacer lo mismo, pero su ya no es libre de usar.

Si desea localizar el cual tarro de una clase pertenece a una ruta local, puede utilizar una utilidad como jarscan ( http://www.inetfeedback.com/jarscan/ ). Sólo tiene que especificar la clase desea localizar y la ruta del directorio raíz en el que desea que se inicie la búsqueda de la clase en frascos y archivos zip.

NoClassDefFoundError es un error de vinculación básicamente. Se produce cuando se intenta crear una instancia y un objeto (estáticamente con el "nuevo") y no se ha encontrado cuando era durante la compilación.

ClassNotFoundException es más general y es una excepción en tiempo de ejecución cuando intenta utilizar una clase que no existe. Por ejemplo, puede tener un parámetro de una función acepta una interfaz y alguien pasa en una clase que implementa la interfaz, pero que no tienen acceso a la clase. También cubre el caso de carga dinámica de clases, como el uso loadClass() o Class.forName().

A NoClassDefFoundError (NCDFE) ocurre cuando el código se ejecuta "nueva Y ()" y que no puede encontrar la clase Y.

Puede ser simplemente que Y se encuentra en su cargador de clases al igual que los otros comentarios sugieren, pero podría ser que la clase Y no está firmado o tiene una firma no válida, o que Y es cargado por un cargador de clases diferentes no visible a su código, o incluso de que y depende de Z que no pudo ser cargado por cualquiera de las razones anteriores.

Si esto sucede, entonces la JVM recordará el resultado de la carga X (NCDFE) y simplemente arrojará una nueva NCDFE cada vez que pida Y sin decirle por qué:

class a {
  static class b {}
  public static void main(String args[]) {
    System.out.println("First attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
    System.out.println("\nSecond attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
  }
}

Guardar como a.java algún lugar

El código intenta simplemente crear una instancia de una nueva clase "B" dos veces, aparte de eso, no tiene virus, y no hace nada.

Compilar el código con javac a.java, a continuación, ejecutar un invocando java -cp . a -. Sólo debe imprimir dos líneas de texto, y debería funcionar bien sin errores

A continuación, elimine el archivo "un $ b.class" (o llenarlo con basura, o copiar a.class sobre él) para simular la clase que falta o dañado. Esto es lo que sucede:

First attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:5)
Caused by: java.lang.ClassNotFoundException: a$b
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 1 more

Second attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:7)

Los primeros resultados de invocación en un ClassNotFoundException (lanzada por el cargador de clases cuando no puede encontrar la clase), que debe ser envuelto en una NoClassDefFoundError sin control, ya que el código en cuestión (new b()) sólo deben trabajar.

El segundo intento, por supuesto, fallan también, pero como se puede ver la excepción ajustada no es más, debido a que el cargador de clases parece recordar cargadores de clases fallidos. Sólo se ve la NCDFE con absolutamente ninguna pista sobre lo que realmente sucedió.

Así que si usted ve un NCDFE sin causa, es necesario ver si se puede rastrear de nuevo a la primera vez que la clase se cargó a encontrar la causa del error.

http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :

ClassNotFoundException : se produce cuando el cargador de clases no pudo encontrar la clase requerida en la ruta de clase. Así que, básicamente, usted debe comprobar su ruta de clase y añadir la clase en la ruta de clase.

NoClassDefFoundError : esto es más difícil de depurar y encontrar la razón. Esto se produce cuando en tiempo de compilación las clases requeridas están presentes, pero en tiempo de ejecución de las clases se cambia o se quita o se inicializa estáticos de la clase arrojó excepciones. Significa la clase que es cada vez cargado está presente en la ruta de clase, pero una de las clases que son requeridos por esta clase son ya sea eliminado o no se pudo cargar por compilador. Por lo que debe ver las clases que dependen de esta clase.

Ejemplo :

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

Ahora, después de la compilación de las clases tanto, si borra el archivo Test1.class y ejecutar la clase de prueba, lanzará

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    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)
    ... 1 more

ClassNotFoundException:. Produce cuando una aplicación intenta cargar en una clase a través de su nombre, pero no hay una definición de la clase con el nombre especificado se pudo encontrar

NoClassDefFoundError:. Arrojados si la Máquina Virtual de Java intenta cargar en la definición de una clase y no hay una definición de la clase se pudo encontrar

  

¿Cuál es la razón para conseguir cada uno de ellos y cualquier proceso de pensamiento sobre cómo hacer frente a este tipo de errores?

Están estrechamente relacionados. Un ClassNotFoundException se produce cuando Java fue a buscar a una clase en particular por su nombre y no podía cargar con éxito. Un NoClassDefFoundError se produce cuando Java fue en busca de una clase que estaba vinculado a un código existente, pero no pudo encontrar que por una razón u otra (por ejemplo, la ruta de clase equivocada, versión incorrecta de Java, versión incorrecta de una biblioteca) y es totalmente fatal, ya que indica que algo ha ido muy mal.

Si usted tiene un fondo C, una CNFE es como una falta de dlopen() / dlsym() y un NCDFE es un problema con el conector; en el segundo caso, los archivos de clase en cuestión nunca deberían haber sido en realidad compilado en la configuración que está tratando de usarlos.

Ejemplo # 1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

Si com/example/Class1 no existe en ninguna de las rutas de clases, entonces arroja ClassNotFoundException.

Ejemplo # 2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

Si existía com/example/Class2 durante la compilación de B, pero no encontró mientras que la ejecución, a continuación, arroja NoClassDefFoundError.

Ambos son administrados excepciones de tiempo.

ClassNotFoundException se produce cuando existe intentará cargar la clase refiriéndose a ella a través de una cadena. Por ejemplo, el parámetro a en Class.forName () es una cadena, y esto plantea el potencial de los nombres binarios no válidos que se pasa al cargador de clases.

El ClassNotFoundException se inicia cuando se detecta un nombre binario podría no ser válido; por ejemplo, si el nombre de la clase tiene el carácter '/', que están obligados a obtener una ClassNotFoundException. También se produce cuando la clase directamente hace referencia no está disponible en la ruta de clase.

Por otro lado, NoClassDefFoundError se lanza

  • cuando la representación física de la clase - el archivo .class no está disponible,
  • o la clase sido ya cargado en un cargador de clases diferentes (por lo general un cargador de clases padre hubiera cargado la clase y, por tanto, la clase no se puede cargar de nuevo),
  • o si se ha encontrado una definición de clase incompatibles - el nombre en el archivo de clase no coincide con el nombre solicitado,
  • o (más importante) si una clase dependiente no puede ser localizado y cargado. En este caso, la clase directamente referenciado podría haber sido localizado y cargado, pero la clase dependiente no está disponible o no se puede cargar. Este es un escenario donde la clase directamente referenciada se puede cargar a través de un Class.forName o métodos equivalentes. Esto indica una falla en enlace.

En resumen, un NoClassDefFoundError suele arrojados en el nuevo () declaraciones o invocaciones de métodos que cargan una clase que no tenía anteriormente (en contraposición a la carga basado en cadena de clases para ClassNotFoundException), cuando el cargador de clases no es capaz de encontrar o cargar el definición de clase (s).

Finalmente, es fiel a la aplicación cargador de clases para lanzar una instancia de ClassNotFoundException cuando no puede cargar una clase. La mayoría de las implementaciones classloader costumbre realizar esta medida que amplían la URLClassLoader. Por lo general, los cargadores de clases no lanzan explícitamente un NoClassDefFoundError en cualquiera de las implementaciones de métodos -. Esta excepción por lo general se devuelve JVM en el compilador HotSpot, y no por el propio cargador de clases

Diferencia entre ClassNotFoundException Vs NoClassDefFoundError

 introducir descripción de la imagen aquí

Con los nombres en sí podemos identificar fácilmente uno de Exception y el otro es de Error.

Excepción: Las excepciones se produce durante la ejecución de programa.Un programador puede manejar la excepción por intentar bloque catch.Tenemos dos tipos de excepciones.Excepción comprobada que lanza en tiempo de compilación.Excepciones de tiempo de ejecución que son arrojados en tiempo de ejecución, estos excepción usualmente ocurren debido a la mala programación.

Error: Estos no son excepciones en todo, está más allá del alcance de programador.Estos errores suelen ser lanzados por la JVM.


enter image description here fuente de la imagen

Diferencia:

ClassNotFoundException:

  • Cargador de clases no verificar una clase de código de bytes mencionamos en Enlace de la fase de de la carga de clases del subsistema de tenemos ClassNotFoundException.
  • ClassNotFoundException es una Excepción comprobada se derivan directamente de la java.lang.Exception clase y usted tiene que proporcionar explícito de manejo para
  • ClassNotFoundException aparece cuando hay un la carga explícita de la clase que implica proporcionar el nombre de la clase en tiempo de ejecución utilizando el cargador de clases.loadClass(), la Clase.forName() y cargador de clases.findSystemClass().

NoClassDefFoundError:

  • Cargador de clases no la resolución de referencias de una clase en Enlace de la fase de de la carga de clases del subsistema de tenemos NoClassDefFoundError.
  • NoClassDefFoundError es un Error derivado de LinkageError la clase, que se utiliza para indicar los casos de error, donde una clase tiene una dependencia en algunos otros de la clase y que clase tiene incompatibilidad cambiado después de la compilación.
  • NoClassDefFoundError es un resultado de implícito de carga de clase a causa de una llamada al método de la clase o cualquier variable de acceso.

Similitudes:

  • Ambos NoClassDefFoundError y ClassNotFoundException están relacionados con la falta de disponibilidad de una clase en tiempo de ejecución.
  • Ambos ClassNotFoundException y NoClassDefFoundError están relacionados con la classpath de Java.

Teniendo en cuenta las acciones que el cargador de clases sussystem:

http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

Este es un artículo que me ha ayudado mucho a entender la diferencia: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

  

Si se produce un error durante la carga de clases, a continuación, una instancia de una   subclase de LinkageError debe ser arrojado en un punto en el programa que   usos (directa o indirectamente) la clase o interfaz que se carga.

     

Si la Máquina Virtual de Java siempre intenta cargar una clase C durante   verificación (§5.4.1) o la resolución (§5.4.3) (pero no la inicialización   (§5.5)), y el cargador de clases que se utiliza para iniciar la carga de C   lanza una instancia de ClassNotFoundException , entonces el Java Virtual   La máquina debe emitir una instancia de NoClassDefFoundError cuya causa es   la instancia de ClassNotFoundException .

Así que un ClassNotFoundException es una causa fundamental de NoClassDefFoundError .
Y un NoClassDefFoundError es un caso especial de error de tipo de carga, que se produce en Enlazar paso.

Añadir una razón posible en la práctica:

  • ClassNotFoundException: como dijo Cletus, se utiliza la interfaz mientras que la clase heredada de la interfaz no está en la ruta de clase. Por ejemplo, servicio de patrón de Proveedor (o Servicio de Localización de ) tratar de localizar a algunos no clase -existing
  • NoClassDefFoundError: teniendo en cuenta la clase se encuentra, mientras que no se encuentra la dependencia de la clase dada

En la práctica, Error puede ser lanzado en silencio , por ejemplo, se envía una tarea de temporizador y en el tareas de cronómetros que arroja Error , mientras que en la mayoría de los casos, el programa solo detecta Excepción . A continuación, el Temporizador bucle principal se termina sin ninguna información. Un error similar a NoClassDefFoundError es ExceptionInInitializerError , cuando su inicializador estático o el inicializador para una variable estática genera una excepción.

ClassNotFoundException es una excepción comprobada que se produce cuando decimos a JVM para cargar una clase por su nombre de la cadena usando Class.forName () o ClassLoader.findSystemClass () o ClassLoader.loadClass () y métodos mencionados clase no se encuentra en la ruta de clase.

La mayoría de las veces, esta excepción se produce cuando intenta ejecutar una aplicación sin actualizar la ruta de clase con los archivos JAR necesarios. Por ejemplo, es posible que haya visto esta excepción cuando se hace el código JDBC para conectarse a la base de datos i.e.MySQL pero su ruta de clase no tiene por JAR para él.

NoClassDefFoundError error se produce cuando JVM intenta cargar una clase particular, que es la parte de su ejecución de código (como parte de una llamada al método normal o como parte de la creación de una instancia utilizando la nueva palabra clave) y esa clase no está presente en la ruta de clases, pero estuvo presente en tiempo de compilación, porque a fin de ejecutar su programa necesita compilar y si está intentando utilizar una clase que no está presente compilador elevará error de compilación.

A continuación se muestra una breve descripción

introducir descripción de la imagen aquí

Usted puede leer Todo Sobre ClassNotFoundException Vs NoClassDefFoundError para más detalles.

Me recuerdo una y otra vez la siguiente cuando necesito refrescar

ClassNotFoundException

Jerarquía de la clase

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

Mientras se depura

  1. JAR necesario, la clase no se encuentra en la ruta de clase.
  2. Verificar todos los frascos necesarios están en la ruta de clases de JVM.

NoClassDefFoundError

Jerarquía de la clase

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

Mientras se depura

  1. Problema con la carga de una clase de forma dinámica, que fue compilado correctamente
  2. Problema con bloques estáticos, constructores, init () de la clase dependiente y el error real es envuelto por múltiples capas [especialmente cuando se utiliza Spring, Hibernate la excepción real se envuelve y se obtendrá NoClassDefError]
  3. Cuando se enfrentan a "ClassNotFoundException" bajo un bloque estático de la clase depende
  4. Problema con versiones de clase. Esto sucede cuando se tiene dos versiones v1, v2 de la misma clase bajo diferentes tarro / paquetes, que fue compilado con éxito utilizando v1 y v2 se carga en el tiempo de ejecución que no hace tiene sus métodos / vars y verá esta excepción. [Una vez resuelto este problema eliminando el duplicado de log4j clase relacionada bajo múltiples frascos que apareció en la ruta de clase]

ClassNotFoundException y NoClassDefFoundError se producen cuando una clase particular no se encuentra en runtime.However, que se producen en diferentes escenarios.

ClassNotFoundException es una excepción que se produce cuando intenta cargar una clase en tiempo de ejecución utilizando Class.forName () o loadClass () métodos y clases mencionadas no se encuentran en la ruta de clase.

    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 es un error que se produce cuando una clase particular está presente en tiempo de compilación, pero faltaba en tiempo de ejecución.

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

Al compilar el programa anterior, se generarán dos archivos .class. Una de ellas es A.class y otra es B.class. Si elimina el archivo A.class y ejecute el archivo B.class, Java Runtime System lanzará NoClassDefFoundError, como a continuación:

    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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top