Recibo un mensaje NoClassDefFoundError
cuando ejecuto mi aplicación Java. ¿Cuál es típicamente la causa de esto?
java
noclassdeffounderror
John Meagher
fuente
fuente
Respuestas:
Esto se produce cuando hay un archivo de clase del que depende su código y está presente en tiempo de compilación pero no se encuentra en tiempo de ejecución. Busque diferencias en sus rutas de clase de tiempo de ejecución y tiempo de ejecución.
fuente
Si bien es posible que esto se deba a una falta de coincidencia de classpath entre el tiempo de compilación y el tiempo de ejecución, no es necesariamente cierto.
Es importante mantener dos o tres excepciones diferentes directamente en nuestra cabeza en este caso:
java.lang.ClassNotFoundException
Esta excepción indica que la clase no se encontró en el classpath. Esto indica que estábamos intentando cargar la definición de clase, y la clase no existía en el classpath.java.lang.NoClassDefFoundError
Esta excepción indica que la JVM buscó en su estructura interna de datos de definición de clase la definición de una clase y no la encontró. Esto es diferente a decir que no se pudo cargar desde el classpath. Por lo general, esto indica que anteriormente intentamos cargar una clase desde el classpath, pero falló por alguna razón, ahora estamos tratando de usar la clase nuevamente (y por lo tanto necesitamos cargarla, ya que falló la última vez), pero nosotros ' Ni siquiera vamos a intentar cargarlo, porque no logramos cargarlo antes (y sospechamos razonablemente que volveríamos a fallar). La falla anterior podría ser una ClassNotFoundException o una ExceptionInInitializerError (que indica una falla en el bloque de inicialización estática) o cualquier otro problema. El punto es que un NoClassDefFoundError no es necesariamente un problema de classpath.fuente
Error: Could not find or load main class
se clasificará en qué categoría de error.Aquí está el código para ilustrar
java.lang.NoClassDefFoundError
. Consulte la respuesta de Jared para obtener una explicación detallada.NoClassDefFoundErrorDemo.java
SimpleCalculator.java
fuente
SimpleCalculator
después de la división por cero? ¿Alguien tiene una referencia a la documentación oficial de este comportamiento?new SimpleCalculator()
se llama, obtiene un ExceptionInInitializerError con una causa de ArithmeticException. La segunda vez que llamanew SimpleCalculator()
, obtiene un NoClassDefFoundError tan puro como cualquier otro. El punto es que puede obtener un NoClassDefFoundError por una razón que no sea SimpleCalculator.class que no está en el classpath en tiempo de ejecución.NoClassDefFoundError en Java
Definición:
Java Virtual Machine no puede encontrar una clase particular en tiempo de ejecución que estaba disponible en tiempo de compilación.
Si una clase estuvo presente durante el tiempo de compilación pero no está disponible en java classpath durante el tiempo de ejecución.
Ejemplos:
Un ejemplo simple de NoClassDefFoundError es que la clase pertenece a un archivo JAR faltante o JAR no se agregó a classpath o, a veces, alguien ha cambiado el nombre de jar, como en mi caso uno de mis colegas ha cambiado tibco.jar a tibco_v3.jar y el programa es fallando con java.lang.NoClassDefFoundError y me preguntaba qué está mal.
Solo intente ejecutar explícitamente la opción -classpath con la classpath que cree que funcionará y si está funcionando, entonces es una señal corta y segura de que alguien está anulando java classpath.
Soluciones posibles:
Recursos:
3 formas de resolver NoClassDefFoundError
java.lang.NoClassDefFoundError Patrones del problema
fuente
He descubierto que a veces obtengo un error NoClassDefFound cuando el código se compila con una versión incompatible de la clase encontrada en tiempo de ejecución. La instancia específica que recuerdo es con la biblioteca del eje apache. En realidad, había 2 versiones en mi classpath en tiempo de ejecución y estaba recogiendo la versión desactualizada e incompatible y no la correcta, causando un error NoClassDefFound. Esto estaba en una aplicación de línea de comando donde estaba usando un comando similar a este.
Pude conseguir que recogiera la versión adecuada usando:
fuente
Esta es la mejor solución que encontré hasta ahora.
Supongamos que tenemos un paquete llamado que
org.mypackage
contiene las clases:y los archivos que definen este paquete se almacenan físicamente en el directorio
D:\myprogram
(en Windows) o/home/user/myprogram
(en Linux).La estructura del archivo se verá así:
Cuando invocamos Java, se especifica el nombre de la aplicación se ejecute:
org.mypackage.HelloWorld
. Sin embargo, también debemos decirle a Java dónde buscar los archivos y directorios que definen nuestro paquete. Entonces, para iniciar el programa, tenemos que usar el siguiente comando:fuente
Estaba usando Spring Framework con Maven y resolví este error en mi proyecto.
Hubo un error de tiempo de ejecución en la clase. Estaba leyendo una propiedad como número entero, pero cuando leyó el valor del archivo de propiedades, su valor era el doble.
Spring no me dio un seguimiento completo de la pila en qué línea falló el tiempo de ejecución. Simplemente dijo
NoClassDefFoundError
. Pero cuando lo ejecuté como una aplicación Java nativa (sacándola de MVC), dioExceptionInInitializerError
cuál era la verdadera causa y cuál era la forma en que rastreé el error.La respuesta de @ xli me dio una idea de lo que puede estar mal en mi código.
fuente
NoClassDefFoundError
realidad fue causado porExceptionInInitalizerError
, que fue causado porDateTimeParseException
). Es un poco engañoso, ¿no? Sé que probablemente tenían sus razones para hacerlo así, pero sería bueno tener al menos una pequeña pista, queNoClassDefFoundError
fue el resultado de otra excepción, sin la necesidad de deducirlo. Solo lanzar deExceptionInInitializerError
nuevo sería mucho más claro. A veces la conexión entre los dos puede no ser tan obvia.Obtengo NoClassFoundError cuando las clases cargadas por el cargador de clases en tiempo de ejecución no pueden acceder a las clases ya cargadas por el cargador de raíz de Java. Debido a que los diferentes cargadores de clases están en diferentes dominios de seguridad (de acuerdo con Java), jvm no permitirá que las clases ya cargadas por el cargador de raíz se resuelvan en el espacio de direcciones del cargador de tiempo de ejecución.
Ejecute su programa con 'java -javaagent: tracer.jar [YOUR java ARGS]'
Produce una salida que muestra la clase cargada y el entorno del cargador que cargó la clase. Es muy útil rastrear por qué una clase no se puede resolver.
fuente
Un caso interesante en el que puede ver mucho
NoClassDefFoundErrors
es cuando:throw
unRuntimeException
en elstatic
bloque de tu claseExample
Example
NoClassDefError
será arrojado acompañadoExceptionInInitializerError
del bloque estáticoRuntimeException
.Este es un caso especialmente importante cuando ve
NoClassDefFoundErrors
en las PRUEBAS DE LA UNIDAD .En cierto modo, está "compartiendo" la
static
ejecución del bloque entre pruebas, pero la inicialExceptionInInitializerError
será solo en un caso de prueba. El primero que usa laExample
clase problemática . Otros casos de prueba que usan laExample
clase simplemente arrojaránNoClassDefFoundErrors
.fuente
La siguiente técnica me ayudó muchas veces:
donde TheNoDefFoundClass es la clase que podría "perderse" debido a una preferencia por una versión anterior de la misma biblioteca utilizada por su programa. Esto ocurre con mayor frecuencia con los casos, cuando el software del cliente se implementa en un contenedor dominante, armado con sus propios cargadores de clases y toneladas de versiones antiguas de las bibliotecas más populares.
fuente
En caso de que haya generado código (EMF, etc.), puede haber demasiados inicializadores estáticos que consuman todo el espacio de la pila.
Consulte la pregunta sobre desbordamiento de pila ¿ Cómo aumentar el tamaño de pila de Java? .
fuente
Solucioné mi problema deshabilitando las bibliotecas preDexLibrary para todos los módulos:
fuente
NoClassDefFoundError
También puede ocurrir cuando un inicializador estático intenta cargar un paquete de recursos que no está disponible en tiempo de ejecución, por ejemplo, un archivo de propiedades que la clase afectada intenta cargar desde elMETA-INF
directorio, pero no está allí. Si no capturaNoClassDefFoundError
, a veces no podrá ver el seguimiento completo de la pila; para superar esto, puede usar temporalmente unacatch
cláusula paraThrowable
:fuente
for example a properties file that the affected class tries to load from the META-INF directory
. Esto realmente me sucedió y pude resolverloNoClassDefFoundError
agregando el archivo de propiedades que faltaba. Agregué esta respuesta exactamente porque uno no esperaría este error en las circunstancias mencionadas.static
inicialización ... que desencadenó una excepción no verificada y provocó el inicio de clase fallar Cualquier excepción no comprobada que se propague desde la inicialización estática haría eso.static
inicialización fallida ), me interesaría ver un ejemplo real (es decir, un MCVE) que demuestre el comportamiento.Recibí este error cuando agrego la dependencia de Maven de otro módulo a mi proyecto, el problema finalmente se resolvió agregando
-Xss2m
a la opción JVM de mi programa (es un megabyte por defecto desde JDK5.0). Se cree que el programa no tiene suficiente pila para cargar la clase.fuente
Si alguien viene aquí por
java.lang.NoClassDefFoundError: org/apache/log4j/Logger
error, en mi caso se produjo porque usé log4j 2 (pero no agregué todos los archivos que vienen con él), y alguna biblioteca de dependencia usó log4j 1. La solución fue agregar Log4j Puente 1.x: el jarlog4j-1.2-api-<version>.jar
que viene con log4j 2. Más información en la migración log4j 2 .fuente
Dos copias de pago diferentes del mismo proyecto
En mi caso, el problema era la incapacidad de Eclipse para diferenciar entre dos copias diferentes del mismo proyecto. Tengo uno bloqueado en el tronco (control de versión SVN) y el otro trabajando en una rama a la vez. Probé un cambio en la copia de trabajo como un caso de prueba JUnit, que incluía extraer una clase interna privada para ser una clase pública por sí sola y, mientras funcionaba, abro la otra copia del proyecto para mirar a otro parte del código que necesitaba cambios. En algún momento, el
NoClassDefFoundError
aparecieron quejándose de que la clase interna privada no estaba allí; hacer doble clic en el seguimiento de la pila me llevó al archivo de origen en la copia del proyecto incorrecta.Al cerrar la copia troncal del proyecto y ejecutar el caso de prueba nuevamente se eliminó el problema.
fuente
Este error puede ser causado por requisitos de versión Java no verificados .
En mi caso, pude resolver este error, al construir un proyecto de código abierto de alto perfil, al cambiar de Java 9 a Java 8 usando SDKMAN. .
Luego, realice una instalación limpia como se describe a continuación.
Cuando se utiliza Maven como su herramienta de compilación, a veces es útil, y generalmente gratificante, hacer una compilación de 'instalación' limpia con las pruebas deshabilitadas .
Ahora que todo se ha construido e instalado, puede continuar y ejecutar las pruebas.
fuente
Obtuve errores NoClassDefFound cuando no exporté una clase en la pestaña "Ordenar y Exportar" en la Ruta de compilación de Java de mi proyecto. Asegúrese de poner una marca de verificación en la pestaña "Ordenar y Exportar" de cualquier dependencia que agregue a la ruta de compilación del proyecto. Consulte la advertencia de Eclipse: XXXXXXXXXXX.jar no se exportará ni se publicará. Tiempo de ejecución ClassNotFoundExceptions puede resultar .
fuente
También podría deberse a que copia el archivo de código de un IDE con un nombre de paquete determinado y desea intentar ejecutarlo usando la terminal. Primero deberá eliminar el nombre del paquete del código. Esto me pasa a mi.
fuente
En mi caso, recibí este error debido a una falta de coincidencia en las versiones de JDK. Cuando traté de ejecutar la aplicación desde Intelij no funcionaba, pero funcionó desde la línea de comandos. Esto se debe a que Intelij estaba intentando ejecutarlo con el Java 11 JDK que estaba configurado, pero en la línea de comandos se estaba ejecutando con el Java 8 JDK. Después de cambiar esa configuración en Archivo> Estructura del proyecto> Configuración del proyecto> Project SDK, funcionó para mí.
fuente
Todos hablan aquí sobre algunas cosas de configuración de Java, problemas de JVM, etc., en mi caso, el error no estaba relacionado con estos temas y tenía una razón muy trivial y fácil de resolver: tenía una anotación incorrecta en mi punto final en mi Controlador ( Aplicación Spring Boot).
fuente
He tenido un problema interesante con NoClassDefFoundError en JavaEE al trabajar con el servidor Liberty. Estaba usando adaptadores de recursos IMS y mi server.xml ya tenía un adaptador de recursos para imsudbJXA.rar. Cuando agregué un nuevo adaptador para imsudbXA.rar, comencé a recibir este error para objetos de instancia para DLIException, IMSConnectionSpec o SQLInteractionSpec. No pude entender por qué, pero lo resolví creando un nuevo server.xml para mi trabajo usando solo imsudbXA.rar. Estoy seguro de que usar múltiples adaptadores de recursos en server.xml está bien, simplemente no tuve tiempo de investigarlo.
fuente
Java no pudo encontrar la clase A en tiempo de ejecución. La clase A estaba en el proyecto Maven ArtClient desde un espacio de trabajo diferente. Entonces importé ArtClient a mi proyecto Eclipse. Dos de mis proyectos usaban ArtClient como dependencia. Cambié la referencia de la biblioteca a la referencia del proyecto para estos (Build Path -> Configure Build Path).
Y el problema desapareció.
fuente
Tuve el mismo problema y estuve en stock durante muchas horas.
Encontré la solución. En mi caso, estaba el método estático definido debido a eso. La JVM no puede crear el otro objeto de esa clase.
Por ejemplo,
fuente
Recibí este mensaje después de eliminar dos archivos de la biblioteca SRC, y cuando los recuperé seguí viendo este mensaje de error.
Mi solución fue: reiniciar Eclipse. Desde entonces no he vuelto a ver este mensaje :-)
fuente
Asegúrese de que esto coincida en
module:app
ymodule:lib
:fuente
{s
y dos}
). ¿Puedes arreglarlo?