La excepción en el hilo "main" del tipo java.lang.NoClassDefFoundError
es uno de los errores más comunes que te puedes encontrar al programar en Java. Y también una de las que más quebraderos de cabeza te pueden ocasionar dependiendo de la circunstancia que la cause.
Exception in thread "main" java.lang.NoClassDefFoundError
Dependiendo del tamaño de tu aplicación, resolver este error puede ser más o menos difícil (cuanto más grande más complicado, lógicamente).
Vamos a ver a continuación las causas más comunes de que se produzca este error y cómo podemos intentar resolverlo.
¿Qué significa este error y por qué se produce?
Antes de nada es necesario que sepamos a qué se debe la aparición de este error. Como su propio nombre indica, este error se produce cuando la máquina virtual de Java no es capaz de encontrar la definición de una clase de la que depende el programa para su funcionamiento. Es decir, cuando su ClassLoader
no es capaz de encontrar la clase en su árbol de carga actual.
Si el programa compiló sin problema, quiere decir que la clase se encontró a la hora de compilar, pero luego, en ejecución, no aparece por ningún lado, lo cual puede parecer una cosa muy extraña, pero existen diversos motivos para que pueda ocurrir.
Para empezar, tiene mucho que ver el funcionamiento del ClassLoader
. Sin profundizar ni entrar en mucho detalle (info detallada aquí), este objeto funciona de manera jerárquica, de modo que hay varios ObjectLoader
a diferentes niveles que localizan y cargan clases. Por ello, por ejemplo, incluso aunque una clase se encuentre, dependiendo del nivel en el que aparezca, si la estamos usando en un nivel inferior es posible que se produzca el temido error que nos ocupa. O puede que si hay dos versiones diferentes del mismo paquete instaladas en el sistema, que se produzca también (generando lo que se conoce como el JAR Hell)
Hay muchas posibilidades. Para solucionar el problema, primero hay que determinar el motivo por el que está ocurriendo, y luego actuar en consecuencia.
Es interesante notar que la excepción
java.lang.ClassNotFoundException
, que se parece mucho a la que estamos tratando, solo se produce cuando intentamos cargar en tiempo de ejecución una clase utilizando su nombre. Son excepciones distintas aunque conceptualmente parecidas. Esta última es menos frecuente. La que nos ocupa tiene una ventaja y es que sabemos que durante la compilación la clase estaba presente.
Principales motivos para que se produzca la excepción NoClassDefFoundError
Por orden de importancia, los principales motivos de la excepción son:
1.- El paquete no está disponible en el Classpath
Esta es quizá la más común de las situaciones y se produce porque la JVM no es capaz de encontrar el paquete correspondiente en el Classpath de Java.
Si falta el archivo .jar
o se ha renombrado (por ejemplo, se cambia de miPaquete.jar
a miPaquete-v2.jar
), la JVM no es capaz de encontrarlo. En estos casos lo más sencillo es simplemente localizar el paquete y copiarlo a donde debería estar (o dejarle el nombre antiguo).
Si tienes dudas sobre dónde está ubicado el Classpath
puedes mostrar por pantalla la ruta usando:
System.getproperty("java.classpath")
Otra opción de emergencia para salir de dudas sobre si estamos yendo al sitio adecuado es lanzar el programa especificando manualmente la ruta desde la que se van a cargar los paquetes locales, usando la opción -classpath
(o -cp
, abreviada) al ejecutar el programa:
java -cp C:\java\MisClases miPrograma
De este modo estaremos seguros de que, a pesar de estar usando la ruta correcta y tener en ella el paquete apropiado, el programa no es capaz de cargar la clase, así que debemos ver otras posibilidades.
Nota : La opción
-cp
también puede hacer referencia a archivos.jar
directamente, uno o varios nombres separados por comas. Es habitual cuando una aplicación depende de código Java compilado (bibliotecas externas) que elclasspath
se mantenga apuntando al JRE de Java y luego se agregue con-cp
la referencia a los archivos.jar
de esas bibliotecas de terceros, que no forman parte del JRE sino que se distribuyen conjuntamente con la aplicación.
2.- Faltan permisos suficientes
Algún problema de permisos puede estar impidiendo que se puedan cargar las clases de un archivo .jar
y que se produzca la excepción NoClassDefFoundError
.
Debes asegurarte de que el usuario actual tiene permisos suficientes para acceder a los archivos. Esto es especialmente importante en el caso de que algún paquete sea compartido y por lo tanto pueda tener unos permisos establecidos por otro usuario, sin haber creado permisos que aseguren el acceso por parte de todos los usuarios.
3.- Falta alguna dependencia de terceros
Alguna dependencia del programa, por ejemplo una biblioteca nativa, no está disponible en el equipo actual, pero sí lo estaba en el equipo en el que se compiló.
Determina cuál es mirando el log de errores e instálala en el equipo actual.
4.- Falta de visibilidad entre niveles de la jerarquía del ClassLoader
En J2EE, como hemos explicado antes, la falta de visibilidad de la clase entre los diferentes niveles de la jerarquía en el proceso de carga puede provocar esta situación.
Esta es una situación compleja y puede dar bastante trabajo solucionarla, así que en lugar de escribir una larguísima explicación aquí te remito al excelente artículo de Pierre-Hugues Charbonneau en el blog de Java EE Support Partners, que lo explica detalladamente y con un ejemplo real paso a paso.
5.- Un script de inicialización sobrescribe a ClassPath
Una posibilidad menos frecuente, pero que puede darse es cuando un script de inicialización del programa está sobrescribiendo la variable de entorno Classpath
, lo cual hace que el resto del programa no pueda encontrar los archivos .jar
apropiados.
Prueba con lo comentado en el punto 1 para ver si se está usando la ruta correcta.
6.- Errores en un bloque de inicialización estática
Si el programa utiliza un bloque de inicialización estática (por ejemplo, es típico con clases de tipo Singleton, que no permiten más que una instancia), es posible que no se encuentre alguna referencia que se use desde ahí.
Puedes saberlo si en el archivo de log del error aparece referenciada la clase ExceptionInInitializerError
.
Por ejemplo, si en un bloque estático de inicialización se declara una clase de tipo Singleton que se inicializa a sí misma en dicho bloque, y se produce un error, al querer utilizar la clase posteriormente desde el programa se produce un error de tipo NoClassDefFoundError
, y en el log aparecerá la mencionada ExceptionInInitializerError
.
7.- JDK desconfigurado o mal instalado
Si alguna de las variables ClassPath
, JAVA_HOME
o PATH
está mal establecida debido a algún problema de la instalación de Java, vamos a obtener errores de tipo NoClassDefFoundError
, por supuesto. En este caso habría que reinstalar el runtime de Java para solucionarlo.
No están todos los que son pero sí son todos los que están
En este artículo hemos procurado repasar las causas y las soluciones más comunes para este error habitual a la hora de programar en Java. Dependiendo de lo que lo esté causando puede ser muy fácil o muy complicado de arreglar.
Los puntos que hemos comentado son los más comunes, pero existen todavía algunas situaciones más que lo pueden producir, si bien son menos habituales.
Una buena recomendación, no solo para este caso, sería que procures utilizar siempre algún entorno integrado de desarrollo como NetBeans o Eclipse, ya que con sus ayudas integradas minimizan mucho las situaciones difíciles y los posibles errores. Aún así, va a ser inevitable que ocurran cosas como esta de vez en cuando. Si es tu caso, espero que al menos este artículo te ayude y proporcione alguna pista para solucionarlo.
Top comments (0)