¿Cómo puedo solucionar "java.lang.NoClassDefFoundError"?
Probé ambos ejemplos en los Tutoriales de Java de Oracle . Ambos se compilan bien, pero en tiempo de ejecución, ambos generan este error:
Exception in thread "main" java.lang.NoClassDefFoundError: graphics/shapes/Square
at Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: graphics.shapes.Square
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
Creo que es posible que tenga el Main.java
archivo en la carpeta equivocada.
Aquí está la jerarquía de directorios:
graphics
├ Main.java
├ shapes
| ├ Square.java
| ├ Triangle.java
├ linepoint
| ├ Line.java
| ├ Point.java
├ spaceobjects
| ├ Cube.java
| ├ RectPrism.java
Y aquí está Main.java
:
import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;
public class Main {
public static void main(String args[]) {
Square s = new Square(2, 3, 15);
Line l = new Line(1, 5, 2, 3);
Cube c = new Cube(13, 32, 22);
}
}
¿Qué estoy haciendo mal aquí?
ACTUALIZAR
Después de colocar la Main
clase en el graphics
paquete (le agregué package graphics;
), configuré la ruta de clases en "_test" (carpeta que contiene gráficos), la compilé y la ejecuté usando java graphics.Main
(desde la línea de comando), funcionó.
Realmente tarde ACTUALIZACIÓN #2
No estaba usando Eclipse (solo Notepad++ y JDK) y la actualización anterior resolvió mi problema. Sin embargo, parece que muchas de estas respuestas son para Eclipse e IntelliJ IDEA , pero tienen conceptos similares.
Después de compilar su código, obtendrá .class
archivos para cada clase en su programa. Estos archivos binarios son el código de bytes que Java interpreta para ejecutar su programa. Indica NoClassDefFoundError
que el cargador de clases (en este caso java.net.URLClassLoader
), que es responsable de cargar clases dinámicamente, no puede encontrar el .class
archivo para la clase que estás intentando usar.
Su código no se compilaría si las clases requeridas no estuvieran presentes (a menos que las clases estén cargadas con reflexión), por lo que generalmente esta excepción significa que su classpath no incluye las clases requeridas. Recuerde que el cargador de clases (específicamente java.net.URLClassLoader
) buscará clases en el paquete abc en la carpeta a/b/c/ en cada entrada de su classpath. NoClassDefFoundError
También puede indicar que le falta una dependencia transitiva de un archivo .jar que ha compilado y que está intentando utilizar.
Por ejemplo, si tuvieras una clase com.example.Foo
, después de compilar tendrías un archivo de clase Foo.class
. Digamos, por ejemplo, que su directorio de trabajo es .../project/
. Ese archivo de clase debe colocarse en .../project/com/example
, y usted establecerá su classpath en .../project/
.
Nota al margen: recomendaría aprovechar las increíbles herramientas que existen para los lenguajes Java y JVM. Los IDE modernos como Eclipse e IntelliJ IDEA y las herramientas de administración de compilación como Maven o Gradle te ayudarán a no tener que preocuparte (tanto) por los classpaths y a concentrarte en el código. Dicho esto, este enlace explica cómo configurar el classpath cuando ejecuta en la línea de comando.
Me gustaría corregir la perspectiva de otros sobre NoClassDefFoundError
.
NoClassDefFoundError
puede ocurrir por múltiples razones como:
- ClassNotFoundException: .class no encontrada para esa clase a la que se hace referencia, independientemente de si está disponible en el momento de la compilación o no (es decir, clase base/secundaria).
- Se localizó el archivo de clase, pero se generó una excepción al inicializar variables estáticas
- Archivo de clase localizado, excepción generada al inicializar bloques estáticos
En la pregunta original, era el primer caso que se puede corregir configurando CLASSPATH en el archivo JAR de clases al que se hace referencia o en su carpeta de paquete.
¿Qué significa "disponible en tiempo de compilación"?
- La clase a la que se hace referencia se utiliza en el código.
Por ejemplo: dos clases, A y B (extiende A). Si se hace referencia a B directamente en el código, está disponible en el momento de la compilación, es decir,A a = new B();
¿Qué significa "no disponible en tiempo de compilación"?
- La clase en tiempo de compilación y la clase en tiempo de ejecución son diferentes, es decir, por ejemplo, la clase base se carga usando el nombre de clase de la clase secundaria, por ejemplo Class.forName("classname") Por ejemplo: dos clases, A y B (extiende A). El código tiene
A a = Class.forName("B").newInstance();
Si recibió uno de estos errores al compilar y ejecutar:
No Error Clase Def Encontrado
Error: no se pudo encontrar ni cargar la clase principal hola
Excepción en el hilo "principal" java.lang.NoClassDefFoundError:javaTest/test/hello (nombre incorrecto: test/hello)
at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$100(Unknown Source) 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) at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
-------------------------- Solución -----------------------
El problema está principalmente en la organización de los paquetes. Debes organizar tus clases en carpetas correctamente con respecto a las clasificaciones de paquetes en tu código fuente.
En el proceso de compilación, use este comando:
javac -d . [FileName.java]
Para ejecutar la clase, utilice este comando:
java [Package].[ClassName]
Una posible razón para esto NoClassDefFoundError
podría ser que la clase está presente en el classpath en Compile time
, pero no existe en el classpath en Runtime
.
Si está utilizando Eclipse, asegúrese de tener las entradas shapes
y linepoints
as spaceobjects
en el .classpath
archivo.
java.lang.NoClassDefFoundError
indica que se encontró algo en tiempo de compilación , pero no en tiempo de ejecución . Quizás solo tengas que agregarlo al classpath.