¿Cuál es la diferencia entre NoClassDefFoundError
y ClassNotFoundException
?
¿Qué hace que sean arrojados? ¿Cómo se pueden resolver?
A menudo encuentro estos objetos arrojables al modificar el código existente para incluir nuevos archivos jar. Los golpeé tanto en el lado del cliente como en el servidor para una aplicación java distribuida a través de webstart.
Posibles razones por las que me he encontrado:
- paquetes no incluidos en
build.xml
el lado del código del cliente - faltan classpath en tiempo de ejecución para los nuevos frascos que estamos usando
- la versión entra en conflicto con el jar anterior
Cuando los encuentro hoy, adopto un enfoque de seguimiento y error para que las cosas funcionen. Necesito más claridad y comprensión.
-verbose
(p-verbose:class -verbose:jni
. Ej. ) Ayuda, pero los informes de Mogsie debajo de su respuesta dicen que esto no proporciona información adicional útil :(Respuestas:
La diferencia con las especificaciones API de Java es la siguiente.
Para
ClassNotFoundException
:Para
NoClassDefFoundError
:Entonces, parece que
NoClassDefFoundError
ocurre cuando la fuente se compiló con éxito, pero en tiempo de ejecución,class
no se encontraron los archivos necesarios . Esto puede ser algo que puede suceder en la distribución o producción de archivos JAR, donde noclass
se incluyeron todos los archivos necesarios .En cuanto a
ClassNotFoundException
, parece que puede provenir de intentar hacer llamadas reflexivas a las clases en tiempo de ejecución, pero las clases que el programa intenta llamar no existen.La diferencia entre los dos es que uno es un
Error
y el otro es unException
. WithNoClassDefFoundError
es anError
y surge de la Java Virtual Machine que tiene problemas para encontrar una clase que esperaba encontrar. Un programa que se esperaba que funcionara en tiempo de compilación no puede ejecutarse debido aclass
que no se encuentran los archivos, o no es el mismo que fue producido o encontrado 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 unException
, por lo que es algo esperado, y es algo recuperable. El uso de la reflexión puede ser propenso a errores (ya que hay algunas expectativas de que las cosas no salgan como se esperaba. No hay verificación en tiempo de compilación para ver que existen todas las clases requeridas, por lo que cualquier problema para encontrar las clases deseadas aparecerá en tiempo de ejecución .fuente
NoClassDefFoundError
generalmente ocurre cuando hay un problema (excepción lanzada) con el bloque estático o la inicialización de los campos estáticos de la clase, por lo que la clase no se puede inicializar con éxito.Error
y el otro es unException
. :)Se lanza una ClassNotFoundException cuando el ClassLoader no encuentra la clase informada. Esto generalmente significa que falta la clase en CLASSPATH. También podría significar que la clase en cuestión está intentando cargarse desde otra clase que se cargó en un cargador de clases padre y, por lo tanto, la clase del cargador de clases hijo no es visible. Este es a veces el caso cuando se trabaja en entornos más complejos como un servidor de aplicaciones (WebSphere es infame por tales problemas con el cargador de clases).
La gente a menudo tienden a confundir
java.lang.NoClassDefFoundError
conjava.lang.ClassNotFoundException
sin embargo hay una distinción importante. Por ejemplo, una excepción (un error realmente dado quejava.lang.NoClassDefFoundError
es una subclase de java.lang.Error) comono significa que la clase ActiveMQConnectionFactory no esté en CLASSPATH. De hecho, es todo lo contrario. Significa que ClassLoader encontró la clase ActiveMQConnectionFactory, sin embargo, al intentar cargar la clase, se encontró con un error al leer la definición de clase. Esto suele suceder cuando la clase en cuestión tiene bloques estáticos o miembros que usan una clase que ClassLoader no encuentra. Entonces, para encontrar al culpable, vea el origen de la clase en cuestión (ActiveMQConnectionFactory en este caso) y busque el código usando bloques estáticos o miembros estáticos. Si no tiene acceso a la fuente, simplemente descompílelo usando JAD.
Al examinar el código, digamos que encuentra una línea de código como la siguiente, asegúrese de que la clase SomeClass esté en su CLASSPATH.
Consejo: para saber a qué jar pertenece una clase, puede usar el sitio web jarFinder. Esto le permite especificar un nombre de clase utilizando comodines y busca la clase en su base de datos de jarras. jarhoo te permite hacer lo mismo pero ya no es gratis.
Si desea ubicar a qué jar pertenece una clase en una ruta local, puede usar una utilidad como jarscan ( http://www.inetfeedback.com/jarscan/ ). Simplemente especifique la clase que desea ubicar y la ruta del directorio raíz donde desea que comience a buscar la clase en archivos jar y zip.
fuente
NoClassDefFoundError
Es básicamente un error de vinculación. Se produce cuando intenta crear una instancia de un objeto (estáticamente con "nuevo") y no se encuentra cuando estaba 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, si tiene un parámetro en una función, acepta una interfaz y alguien pasa a una clase que implementa esa interfaz, pero no tiene acceso a la clase. También cubre el caso de carga de clase dinámica, como el uso deloadClass()
oClass.forName()
.fuente
Un NoClassDefFoundError (NCDFE) ocurre cuando su código ejecuta "new Y ()" y no puede encontrar la clase Y.
Puede ser simplemente que falta su Y en su cargador de clases como sugieren los otros comentarios, pero podría ser que la clase Y no está firmada o tiene una firma no válida, o que Y está cargado por un cargador de clases diferente que no está visible para su código , o incluso que Y depende de Z que no se pudo cargar por ninguno de los motivos anteriores.
Si esto sucede, la JVM recordará el resultado de cargar X (NCDFE) y simplemente lanzará un nuevo NCDFE cada vez que solicite Y sin decirle por qué:
guarda esto como a.java en alguna parte
El código simplemente intenta crear una instancia de una nueva clase "b" dos veces, aparte de eso, no tiene ningún error y no hace nada.
Compile el código con
javac a.java
, luego ejecute a invocandojava -cp . a
: solo debe imprimir dos líneas de texto y debe funcionar bien sin errores.Luego elimine el archivo "a $ b.class" (o llénelo con basura, o copie a.class sobre él) para simular la clase faltante o corrupta. Esto es lo que pasa:
La primera invocación resulta en una ClassNotFoundException (lanzada por el cargador de clases cuando no puede encontrar la clase), que debe estar envuelta en un NoClassDefFoundError no verificado, ya que el código en cuestión (
new b()
) debería funcionar.Por supuesto, el segundo intento también fallará, pero como puede ver, la excepción envuelta ya no existe, porque el ClassLoader parece recordar los cargadores de clases fallidos. Solo ve el NCDFE sin absolutamente ninguna idea de lo que realmente sucedió.
Entonces, si alguna vez ve un NCDFE sin causa raíz, debe ver si puede rastrear hasta la primera vez que se cargó la clase para encontrar la causa del error.
fuente
-verbose
o alguna opción similar dependiendo de la JVM específica? Probablemente-verbose:class
, tal vez-verbose:class:jni
si usa JNI, pero no estoy seguro de la sintaxis. Si esto es útil, quizás podría mostrar los resultados.-verbose:class
tampoco-verbose:jni
dan ningún resultado adicional relevante para la clase que falta.-verbose:class:jni
está mal: uno tiene que especificar dos opciones separadas:.-verbose:class -verbose:jni
)De http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :
ClassNotFoundException
: ocurre cuando el cargador de clases no pudo encontrar la clase requerida en la ruta de clase. Entonces, básicamente, debe verificar su ruta de clase y agregar 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 el momento de la compilación están presentes las clases requeridas, pero en el tiempo de ejecución las clases se cambian o eliminan o las inicializaciones estáticas de la clase arrojan excepciones. Significa que la clase que se está cargando está presente en classpath, pero una de las clases que requiere esta clase se elimina o el compilador no puede cargarla. Entonces debería ver las clases que dependen de esta clase.Ejemplo :
Ahora, después de compilar ambas clases, si elimina el archivo Test1.class y ejecuta Test class, arrojará
ClassNotFoundException
: se lanza cuando una aplicación intenta cargarse en una clase a través de su nombre, pero no se pudo encontrar una definición para la clase con el nombre especificado.NoClassDefFoundError
: arrojado si la máquina virtual Java intenta cargar la definición de una clase y no se puede encontrar ninguna definición de la clase.fuente
-verbose
o alguna opción similar dependiendo de la JVM específica? Probablemente-verbose:class
, tal vez-verbose:class:jni
si usa JNI, pero no estoy seguro de la sintaxis.-verbose:class:jni
está mal, pero se pueden pasar dos opciones diferentes:-verbose:class -verbose:jni
.Están estrechamente relacionados. Se
ClassNotFoundException
lanza A cuando Java fue a buscar una clase particular por su nombre y no pudo cargarla con éxito. SeNoClassDefFoundError
arroja una A cuando Java fue a buscar una clase que estaba vinculada a algún código existente, pero no pudo encontrarla por una razón u otra (por ejemplo, ruta de clase incorrecta, versión incorrecta de Java, versión incorrecta de una biblioteca) y es completamente fatal ya que indica que algo salió mal.Si tiene antecedentes de C, un CNFE es como un fallo en
dlopen()
/dlsym()
y un NCDFE es un problema con el enlazador; en el segundo caso, los archivos de clase en cuestión nunca deberían haberse compilado realmente en la configuración que está tratando de usar.fuente
Ejemplo 1:
Si
com/example/Class1
no existe en ninguno de los classpaths, arrojaClassNotFoundException
.Ejemplo # 2:
Si
com/example/Class2
existió mientras compilaba B, pero no se encontró durante la ejecución, entonces se arrojaNoClassDefFoundError
.Ambas son excepciones de tiempo de ejecución.
fuente
Se produce ClassNotFoundException cuando se intenta cargar la clase haciendo referencia a ella a través de una Cadena. Por ejemplo, el parámetro en Class.forName () es una cadena, y esto aumenta el potencial de que se pasen nombres binarios no válidos al cargador de clases.
La excepción ClassNotFoundException se produce cuando se encuentra un nombre binario potencialmente inválido; por ejemplo, si el nombre de la clase tiene el carácter '/', seguramente obtendrá una ClassNotFoundException. También se produce cuando la clase a la que se hace referencia directamente no está disponible en el classpath.
Por otro lado, se lanza NoClassDefFoundError
En resumen, un NoClassDefFoundError generalmente se genera en declaraciones () o invocaciones de métodos que cargan una clase previamente ausente (a diferencia de la carga de clases basada en cadenas para ClassNotFoundException), cuando el cargador de clases no puede encontrar o cargar la definición de clase ( s)
Finalmente, corresponde a la implementación de ClassLoader lanzar una instancia de ClassNotFoundException cuando no puede cargar una clase. La mayoría de las implementaciones de cargadores de clases personalizadas realizan esto ya que extienden el URLClassLoader. Por lo general, los cargadores de clases no arrojan explícitamente un NoClassDefFoundError en ninguna de las implementaciones de métodos; esta excepción generalmente se produce desde la JVM en el compilador HotSpot, y no por el cargador de clases en sí.
fuente
Diferencia entre ClassNotFoundException Vs NoClassDefFoundError
fuente
Excepción: se producen excepciones durante la ejecución del programa. Un programador puede manejar estas excepciones al intentar bloquear el bloque. Tenemos dos tipos de excepciones. Excepción marcada que arroja en tiempo de compilación. Excepciones de tiempo de ejecución que se generan en tiempo de ejecución, estas excepciones generalmente ocurren debido a una mala programación.
Error: estas no son excepciones en absoluto, está más allá del alcance del programador. Estos errores generalmente los arroja JVM.
fuente de imagen
Diferencia:
ClassNotFoundException:
ClassNotFoundException
.ClassNotFoundException
es una excepción marcada derivada directamente de lajava.lang.Exception
clase y debe proporcionar un manejo explícitoClassNotFoundException
aparece cuando hay una carga explícita de clase involucrada al proporcionar el nombre de la clase en tiempo de ejecución usando ClassLoader.loadClass (), Class.forName () y ClassLoader.findSystemClass ().No Error Clase Def Encontrado:
NoClassDefFoundError
.NoClassDefFoundError
es un error derivado de laLinkageError
clase, que se utiliza para indicar casos de error, donde una clase depende de otra clase y esa clase ha cambiado de manera incompatible después de la compilación.NoClassDefFoundError
es el resultado de la carga implícita de la clase debido a una llamada al método desde esa clase o cualquier acceso variable.Similitudes:
NoClassDefFoundError
yClassNotFoundException
están relacionados con la falta de disponibilidad de una clase en tiempo de ejecución.ClassNotFoundException
yNoClassDefFoundError
están relacionados con Java classpath.fuente
Dadas las acciones del subsistema del cargador de clases:
Este es un artículo que me ayudó mucho a comprender la diferencia: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
Entonces, una ClassNotFoundException es una causa raíz de NoClassDefFoundError .
Y un NoClassDefFoundError es un caso especial de error de carga de tipo, que ocurre en el paso Vinculación .
fuente
Agregue una posible razón en la práctica:
En la práctica, el error se puede lanzar silenciosamente , por ejemplo, envía una tarea de temporizador y en la tarea de temporizador arroja error , mientras que en la mayoría de los casos, su programa solo detecta la excepción . Luego, el ciclo principal del temporizador finaliza sin ninguna información. Un error similar a NoClassDefFoundError es ExceptionInInitializerError , cuando su inicializador estático o el inicializador de una variable estática arroja una excepción.
fuente
ClassNotFoundException es una excepción comprobada que ocurre cuando le decimos a JVM que cargue una clase por su nombre de cadena usando los métodos Class.forName () o ClassLoader.findSystemClass () o ClassLoader.loadClass () y la clase mencionada no se encuentra en el classpath.
La mayoría de las veces, esta excepción ocurre cuando intenta ejecutar una aplicación sin actualizar el classpath con los archivos JAR requeridos. Por ejemplo, es posible que haya visto esta excepción al hacer el código JDBC para conectarse a su base de datos, es decir, MySQL, pero su classpath no tiene JAR para ello.
El error NoClassDefFoundError ocurre cuando JVM intenta cargar una clase particular que es parte de la ejecución de su código (como parte de una llamada a método normal o como parte de crear una instancia usando la nueva palabra clave) y esa clase no está presente en su classpath pero estaba presente en el momento de la compilación porque para ejecutar su programa necesita compilarlo y si está intentando usar una clase que no está presente, el compilador generará un error de compilación.
A continuación se muestra la breve descripción.
Puede leer Everything About ClassNotFoundException Vs NoClassDefFoundError para obtener más detalles.
fuente
Me recuerdo lo siguiente una y otra vez cuando necesito actualizar
ClassNotFoundException
Jerarquía de clase
Mientras se depura
No Error Clase Def Encontrado
Jerarquía de clase
Mientras se depura
fuente
ClassNotFoundException y NoClassDefFoundError ocurren cuando una clase particular no se encuentra en tiempo de ejecución, sin embargo, ocurren en diferentes escenarios.
ClassNotFoundException es una excepción que ocurre cuando intenta cargar una clase en tiempo de ejecución utilizando los métodos Class.forName () o loadClass () y las clases mencionadas no se encuentran en el classpath.
NoClassDefFoundError es un error que ocurre cuando una clase particular está presente en tiempo de compilación, pero faltaba en tiempo de ejecución.
Cuando compila el programa anterior, se generarán dos archivos .class. Uno es A.class y otro es B.class. Si elimina el archivo A.class y ejecuta el archivo B.class, Java Runtime System arrojará NoClassDefFoundError como a continuación:
fuente