¿Cómo puedo solucionar "java.lang.NoClassDefFoundError"?

Resuelto Jonathan Lam asked hace 11 años • 34 respuestas

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.javaarchivo 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 Mainclase en el graphicspaquete (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.

Jonathan Lam avatar Jul 31 '13 22:07 Jonathan Lam
Aceptado

Después de compilar su código, obtendrá .classarchivos para cada clase en su programa. Estos archivos binarios son el código de bytes que Java interpreta para ejecutar su programa. Indica NoClassDefFoundErrorque el cargador de clases (en este caso java.net.URLClassLoader), que es responsable de cargar clases dinámicamente, no puede encontrar el .classarchivo 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. NoClassDefFoundErrorTambié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.

Samuel avatar Jul 31 '2013 15:07 Samuel

Me gustaría corregir la perspectiva de otros sobre NoClassDefFoundError.

NoClassDefFoundErrorpuede ocurrir por múltiples razones como:

  1. 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).
  2. Se localizó el archivo de clase, pero se generó una excepción al inicializar variables estáticas
  3. 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();
p1nkrock avatar Jan 23 '2014 09:01 p1nkrock

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]
sami avatar Oct 07 '2014 11:10 sami

Una posible razón para esto NoClassDefFoundErrorpodrí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 shapesy linepointsas spaceobjectsen el .classpatharchivo.

Konstantin Yovkov avatar Jul 31 '2013 15:07 Konstantin Yovkov
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.

sschrass avatar Jul 31 '2013 15:07 sschrass