Pregunta

Yo estoy haciendo un NoClassDefFoundError cuando ejecuto mi aplicación Java.Lo que es normalmente la causa de esto?

¿Fue útil?

Solución

Esto se produce cuando hay un archivo de clase que su código depende y está presente en tiempo de compilación, pero no se encuentra en tiempo de ejecución.Busca las diferencias en el tiempo de compilación y tiempo de ejecución de rutas de clases.

Otros consejos

Aunque es posible que esto se deba a una ruta de clases de desajuste entre el tiempo de compilación y tiempo de ejecución, no es necesariamente cierto.

Es importante mantener dos o tres excepciones directamente en nuestra cabeza, en este caso:

  1. java.lang.ClassNotFoundException Esta excepción se indica que la clase no se encontró en la ruta de clases.Esto indica que estábamos tratando de cargar la definición de clase, y la clase no existe en el classpath.

  2. java.lang.NoClassDefFoundError Esta excepción indica que la JVM miró en su interior la definición de clase de estructura de datos para la definición de una clase y no la encontró.Esto es diferente a decir que no podía ser cargado desde el classpath.Normalmente, esto indica que anteriormente hemos intentado cargar una clase de la ruta de clases, pero falló por alguna razón - ahora estamos tratando de utilizar la clase de nuevo (y por lo tanto necesidad de cargarlo, ya que no es la última vez), pero ni siquiera vamos a intentar cargarlo, porque la carga de los anteriores (y razonablemente sospechar que nos iba a fallar de nuevo).El anterior fallo podría ser un ClassNotFoundException o un ExceptionInInitializerError (lo que indica un fallo en la inicialización estática del bloque) o cualquier número de otros problemas.El punto es, un NoClassDefFoundError no es necesariamente una ruta de clases del problema.

Aquí está el código para ilustrar java.lang.NoClassDefFoundError.Por favor consulte La respuesta de Jared para una explicación detallada.

NoClassDefFoundErrorDemo.java

public class NoClassDefFoundErrorDemo {
    public static void main(String[] args) {
        try {
            // The following line would throw ExceptionInInitializerError
            SimpleCalculator calculator1 = new SimpleCalculator();
        } catch (Throwable t) {
            System.out.println(t);
        }
        // The following line would cause NoClassDefFoundError
        SimpleCalculator calculator2 = new SimpleCalculator();
    }

}

SimpleCalculator.java

public class SimpleCalculator {
    static int undefined = 1 / 0;
}

He encontrado que a veces me da un NoClassDefFound de error cuando el código es compilado con una versión incompatible de la clase se encuentra en tiempo de ejecución.La instancia específica, recuerdo que con el apache eje de la biblioteca.De hecho hubo 2 versiones en mi tiempo de ejecución classpath y se fue recogiendo al de la fecha y la versión incompatible y no son los correctos, causando un NoClassDefFound de error.Esto fue en una aplicación de línea de comandos donde yo estaba usando un comando similar a este.

set classpath=%classpath%;axis.jar

Yo era capaz de llegar a recoger la versión correcta mediante el uso de:

set classpath=axis.jar;%classpath%;

NoClassDefFoundError En Java

Definición:

  1. La Máquina Virtual de Java no es capaz de encontrar una clase en particular en tiempo de ejecución, que estaba disponible en el momento de la compilación.

  2. Si una clase estuvo presente durante el tiempo de compilación, pero no disponible en la classpath de java en tiempo de ejecución.

enter image description here

Ejemplos:

  1. La clase no está en la ruta de clases, no se tiro manera de saberlo pero muchas veces se puede echar un vistazo a el Sistema de impresión.getproperty("java.ruta de clases") y se imprimirá el classpath desde allí se puede al menos tener una idea de su real tiempo de ejecución de classpath.
  2. Un ejemplo sencillo de NoClassDefFoundError es la clase pertenece a una falta archivo JAR o FRASCO no se ha agregado en el classpath o a veces del tarro nombre ha sido cambiado por alguien como en mi caso uno de mis colegas ha cambiado tibco.jar en tibco_v3.jar y el programa está fallando con java.lang.NoClassDefFoundError y me preguntan lo que está mal.

  3. Sólo trate de ejecutar con explícitamente -classpath opción con el classpath crees que va a funcionar y si funciona, entonces es un seguro de corto señal de que alguien está anulando la classpath de java.

  4. Problema de permisos en el archivo JAR también puede causar NoClassDefFoundError en Java.
  5. Error en el XML de Configuración también puede causar NoClassDefFoundError en Java.
  6. cuando su clase compilada que se define en un paquete, no presentes en el mismo paquete, mientras que la carga como en el caso de JApplet lanzará NoClassDefFoundError en Java.

Posibles Soluciones:

  1. La clase no está disponible en la Classpath de Java.
  2. Si usted está trabajando en entorno J2EE que la visibilidad de Clase entre varios cargador de clases también puede causar java.lang.NoClassDefFoundError, ver ejemplos y escenario de sección para una discusión detallada.
  3. De verificación para java.lang.ExceptionInInitializerError en su archivo de registro.NoClassDefFoundError debido a la falta de inicialización estática es bastante común.
  4. Porque NoClassDefFoundError es una subclase de java.lang.LinkageError también puede venir si uno de ellos es la dependencia como nativos de la biblioteca pueden no estar disponibles.
  5. Cualquier script de inicio es reemplazar la variable de entorno Classpath.
  6. Usted podría estar ejecutando su programa utilizando jar y la clase no fue definido en el archivo de manifiesto de la ClassPath de atributo.

Recursos:

3 maneras de resolver NoClassDefFoundError

java.lang.NoClassDefFoundError Problema patrones

Este es el la mejor solución He encontrado hasta ahora.

Supongamos que tenemos un paquete que se llama org.mypackage contiene las clases:

  • HelloWorld (clase principal)
  • SupportClass
  • UtilClass

y los archivos de definición de este paquete se almacenan físicamente en el directorio D:\myprogram (en Windows) o /home/user/myprogram (en Linux).

La estructura del archivo tendrá este aspecto:enter image description here

Cuando invocamos a Java, podemos especificar el nombre de la aplicación a ejecutar: org.mypackage.HelloWorld.Sin embargo también debemos decirle a Java, donde buscar los archivos y directorios de la definición de nuestro paquete.Así que para lanzar el programa, tenemos que usar el siguiente comando:enter image description here

Yo estaba usando Framework Spring con Maven y solucionado este error en mi proyecto.

Hubo un error en tiempo de ejecución en la clase.Estaba leyendo una propiedad como entero, pero cuando se lee el valor de la propiedad de archivo, su valor era doble.

La primavera no me dé un completo seguimiento de la pila de en que la línea del tiempo de ejecución error.Él simplemente dijo: NoClassDefFoundError.Pero cuando he ejecutado como un nativo de aplicaciones Java (sacándolo de la MVC), que dio ExceptionInInitializerError cual fue la verdadera causa y que es cómo he trazado el error.

@xli la respuesta que me dio la idea de lo que puede estar equivocado en mi código.

Puedo obtener NoClassFoundError cuando las clases cargadas por el tiempo de ejecución de la clase loader no puede acceder a las clases ya carga el java rootloader.Porque el carácter de clase de los cargadores están en diferentes dominios de seguridad (de acuerdo con java), la jvm no permiten que las clases ya cargado por el rootloader a ser resuelta en el tiempo de ejecución del gestor de espacio de direcciones.

Ejecutar el programa con " java -javaagent:tracer.jar [java ARGS]'

Se produce la salida que muestra la clase cargada y el cargador env que se ha cargado la clase.Es muy útil el seguimiento por qué una clase no puede ser resuelto.

// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5

import java.lang.instrument.*;
import java.security.*;

// manifest.mf
// Premain-Class: ClassLoadTracer

// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class

// java -javaagent:tracer.jar  [...]

public class ClassLoadTracer 
{
    public static void premain(String agentArgs, Instrumentation inst) 
    {
        final java.io.PrintStream out = System.out;
        inst.addTransformer(new ClassFileTransformer() {
            public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

                String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
                out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);

                // dump stack trace of the thread loading class 
                Thread.dumpStack();

                // we just want the original .class bytes to be loaded!
                // we are not instrumenting it...
                return null;
            }
        });
    }
}

Leer esto, especialmente si usted ve NoClassDefFoundErrors en la UNIDAD de PRUEBAS...


Un caso interesante, en la que puede ver un montón de NoClassDefFoundErrors es cuando:

  1. throw un RuntimeException en el static bloque de su clase Example
  2. Interceptar (o si no importa como se produce en un caso de prueba)
  3. Intentar crear una instancia de esta clase Example

static class Example {
    static {
        thisThrowsRuntimeException();
    }
}

static class OuterClazz {

    OuterClazz() {
        try {
            new Example();
        } catch (Throwable ignored) { //simulating catching RuntimeException from static block
            // DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
        }

        new Example(); //this throws NoClassDefFoundError
    }
}

NoClassDefError será lanzado acompañado con ExceptionInInitializerError desde el bloque estático RuntimeException.


Esto es especialmente importante en el caso de que cuando usted vea NoClassDefFoundErrors en su LA UNIDAD DE PRUEBAS.

En una forma de "compartir" la static bloque de ejecución entre las pruebas, pero el inicial ExceptionInInitializerError será sólo en un caso de prueba.El primero que utiliza la problemática Example clase.Otros casos de prueba que utilizan la Example la clase se acaba de lanzar NoClassDefFoundErrors.

En caso de haber generado-código (EMF, etc.) no puede ser demasiado estática inicializadores que consumir todo el espacio de la pila.

Ver Desbordamiento de Pila pregunta Cómo aumentar el Java tamaño de la pila?.

La técnica de abajo me ayudó muchas veces:

System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());

donde el TheNoDefFoundClass es la clase que podría ser "perdido" debido a una preferencia por una versión anterior de la misma biblioteca utilizados por el programa.Esto ocurre con más frecuencia con los casos, cuando el cliente de software se implementa en una posición dominante en el recipiente, armados con sus propios cargadores de clases y un montón de versiones antiguas de los más populares libs.

He solucionado mi problema desactivando la preDexLibraries para todos los módulos:

dexOptions {
        preDexLibraries false
        ...

NoClassDefFoundError también puede ocurrir cuando un estática inicializador intenta cargar un paquete de recursos que no está disponible en tiempo de ejecución, por ejemplo un archivo de propiedades que los afectados clase trata de la carga de la META-INF directorio, pero no está allí.Si no coges NoClassDefFoundError, a veces usted no será capaz de ver toda la traza de la pila;para superar esto, usted puede utilizar temporalmente un catch la cláusula de Throwable:

try {
    // Statement(s) that cause the affected class to be loaded
} catch (Throwable t) {
    Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}

Si alguien viene aquí a causa de java.lang.NoClassDefFoundError: org/apache/log4j/Logger error, en mi caso fue producido porque yo log4j 2 (pero yo no agregar todos los archivos que vienen con él), y algunos de dependencia de la biblioteca de log4j 1.La solución fue añadir la Log4j 1.x puente:el frasco log4j-1.2-api-<version>.jar el que viene con log4j 2.Más info en el log4j 2 la migración.

Dos diferentes checkout copias de un mismo proyecto

En mi caso, el problema fue el Eclipse de la incapacidad para diferenciar entre los dos copias diferentes del mismo proyecto.He trabado en el tronco (versión SVN de control) y el otro trabaja en una rama en un momento.He intentado un cambio en la copia de trabajo como JUnit test case, que incluye la extracción de una clase interna privada a un público de clase por su propia cuenta y mientras estaba trabajando, me abre la otra copia del proyecto a mirar a su alrededor en algunos de los otros la parte del código que los cambios que se necesitan.En algún punto, la NoClassDefFoundError apareció quejándose de que el privado de la clase interna no estaba allí;haga doble clic en la traza de la pila me trajo para el archivo de origen en el mal copiar proyectos.

Cierre el tronco copia del proyecto y la ejecución del caso de prueba otra vez se deshizo de el problema.

Este error puede ser causado por desmarcada La versión de Java requisitos.

En mi caso yo era capaz de resolver este error, mientras que la construcción de un alto perfil de proyecto de código abierto, por el cambio de Java 9 a Java 8 uso de la SDKMAN!.

sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu

Luego de hacer una instalación limpia como se describe a continuación.


Cuando se utiliza Maven como su herramienta de construcción, a veces es útil-y generalmente gratificante, para hacer un limpia 'instalar' construir con las pruebas de movilidad.

mvn clean install -DskipTests

Ahora que todo ha sido construido e instalado, usted puede seguir adelante y ejecutar las pruebas.

mvn test

Tengo NoClassDefFound errores cuando yo no exportar una clase en el "Orden y la Exportación" en la ficha de Java Build Path de mi proyecto.Asegúrese de poner una marca de verificación en el "Orden y la Exportación" en la ficha de las dependencias de agregar a la ruta de compilación del proyecto.Ver Eclipse de advertencia:XXXXXXXXXXX.jar no va a ser exportado o publicado.Tiempo de ejecución de ClassNotFoundExceptions puede resultar.

Java fue incapaz de encontrar la clase en tiempo de ejecución.La clase estaba en el proyecto de maven ArtClient de un espacio de trabajo diferente.Así que me importan ArtClient para mi proyecto de Eclipse.Dos de mis proyectos era el uso de ArtClient como dependencia.He cambiado de referencia de la biblioteca de referencia del proyecto para estas (Build Path -> Configure Build Path).

Y el problema desaparece.

Yo tenía el mismo problema, y me fue de stock durante muchas horas.

He encontrado la solución.En mi caso, no fue el método estático definido, debido a que.La JVM no puede crear el objeto de esa clase.

Por ejemplo,

private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");

Tengo este mensaje después de la eliminación de los dos archivos del SRC de la biblioteca, y cuando me trajo de vuelta yo seguía viendo este mensaje de error.

Mi solución fue:Reiniciar Eclipse.Desde entonces no he visto este mensaje otra vez :-)

Asegúrese de que coincida en el module:app y module:lib:

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }

    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top