¿Qué causas y cuáles son las diferencias entre NoClassDefFoundError y ClassNotFoundException?

Resuelto krisp asked hace 14 años • 15 respuestas

¿ Cuál es la diferencia entre NoClassDefFoundErrory ClassNotFoundException?

¿Qué causa que sean arrojados? ¿Cómo se pueden resolver?

A menudo me encuentro con estos elementos arrojables cuando modifico el código existente para incluir nuevos archivos jar. Los he utilizado tanto en el lado del cliente como en el del servidor para una aplicación Java distribuida a través de webstart.

Posibles razones con las que me he encontrado:

  1. Paquetes no incluidos en build.xmlel lado del cliente del código.
  2. Falta el classpath en tiempo de ejecución para los nuevos archivos jar que estamos usando
  3. la versión entra en conflicto con el jar anterior

Cuando me encuentro con estos hoy, adopto un enfoque de seguimiento y error para que todo funcione. Necesito más claridad y comprensión.

krisp avatar Sep 22 '09 09:09 krisp
Aceptado

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

Para ClassNotFoundException:

Se lanza cuando una aplicación intenta cargar una clase a través de su nombre de cadena usando:

  • El forNamemétodo en clase Class.
  • El findSystemClassmétodo en clase ClassLoader.
  • El loadClassmétodo en clase ClassLoader.

pero no se pudo encontrar ninguna definición para la clase con el nombre especificado.

Para NoClassDefFoundError:

Se lanza si la máquina virtual Java o una ClassLoaderinstancia intenta cargar la definición de una clase (como parte de una llamada a un método normal o como parte de la creación de una nueva instancia usando la nueva expresión) y no se puede encontrar ninguna definición de la clase.

La definición de clase buscada existía cuando se compiló la clase que se está ejecutando actualmente, pero ya no se puede encontrar la definición.

Entonces, parece que esto NoClassDefFoundErrorocurre cuando la fuente se compiló exitosamente, pero en tiempo de ejecución, classno se encontraron los archivos requeridos. Esto puede ser algo que puede suceder en la distribución o producción de archivos JAR, donde no classse incluyeron todos los archivos requeridos.

En cuanto a ClassNotFoundException, parece que puede deberse a intentar realizar llamadas reflexivas a clases en tiempo de ejecución, pero las clases a las que el programa intenta llamar no existen.

La diferencia entre los dos es que uno es un Errory el otro es un Exception. With NoClassDefFoundErrores un Errory surge porque la máquina virtual Java tiene problemas para encontrar una clase que esperaba encontrar. Un programa que se esperaba que funcionara en tiempo de compilación no se puede ejecutar debido a que classno se encuentran archivos o no es el mismo que se produjo o se encontró en tiempo de compilación. Este es un error bastante crítico, ya que la JVM no puede iniciar el programa.

Por otro lado, ClassNotFoundExceptiones un Exception, por lo que es algo esperado y es algo recuperable. El uso de la reflexión puede ser propenso a errores (ya que existen algunas expectativas de que las cosas no salgan como se esperaba). No hay una 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. .

coobird avatar Sep 22 '2009 02:09 coobird

Se genera una ClassNotFoundException cuando el ClassLoader no encuentra la clase informada. Normalmente, esto significa que la clase falta 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 principal y, por lo tanto, la clase del cargador de clases secundario no es visible. A veces, este es el caso cuando se trabaja en entornos más complejos como un servidor de aplicaciones (WebSphere es famoso por este tipo de problemas con el cargador de clases).

La gente a menudo tiende a confundirse java.lang.NoClassDefFoundErrorcon java.lang.ClassNotFoundExceptionuna distinción importante. Por ejemplo, una excepción (un error realmente ya que java.lang.NoClassDefFoundErrores una subclase de java.lang.Error) como

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

no 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 produjo 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 usan una clase que ClassLoader no encuentra. Entonces, para encontrar al culpable, vea el código fuente de la clase en cuestión (ActiveMQConnectionFactory en este caso) y busque código que utilice bloques estáticos o miembros estáticos. Si no tiene acceso a la fuente, simplemente descompílela 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.

private static SomeClass foo = new SomeClass();

Consejo: para saber a qué jar pertenece una clase, puede utilizar el sitio web jarFinder. Esto le permite especificar un nombre de clase usando comodines y busca la clase en su base de datos de archivos jar. jarhoo te permite hacer lo mismo pero ya no es de uso gratuito.

Si desea localizar a qué archivo jar pertenece una clase en una ruta local, puede utilizar una utilidad como jarscan ( http://www.inetfeedback.com/jarscan/ ). Simplemente especifica 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.

Sanjiv Jivan avatar Feb 06 '2010 14:02 Sanjiv Jivan

NoClassDefFoundErrorEs básicamente un error de vinculación. Ocurre cuando intentas crear una instancia de un objeto (estáticamente con "nuevo") y no se encuentra cuando estaba durante la compilación.

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

cletus avatar Sep 22 '2009 02:09 cletus