De ce primesc un NoClassDefFoundError în Java?

Eu sunt obtinerea o `NoClassDefFoundError când îmi conduc aplicație Java. Ceea ce este de obicei cauza asta?

Comentarii la întrebare (4)

În timp ce-l's posibil ca acest lucru se datorează unei clase nepotrivire între compilare-timp și run-time, l's nu este neapărat adevărat.

Este important să păstrați două sau trei excepții direct în capul nostru, în acest caz:

  1. java.lang.ClassNotFoundException Această excepție indică faptul că class nu a fost găsit în classpath. Acest lucru indică faptul că am fost încercarea de a încărca definiția de clasă, și la clasa nu exista pe clase.

  2. java.lang.NoClassDefFoundError Această excepție indică faptul că JVM privit în clasă internă definiție structură de date pentru definirea unei clase și nu-l găsiți. Acest lucru este diferit decât spunând că acesta nu a putut fi încărcat de la classpath. De obicei, acest lucru indică faptul că am încercat anterior să se încarce o clasă de clase, dar nu a reușit pentru un motiv de - acum ne-am're încercarea de a utiliza clasa din nou (și, prin urmare, trebuie să-l încarce, deoarece nu a reușit data trecută), dar am're nu chiar de gând să încerce să-l încarce, pentru că nu am reușit încărcare mai devreme (și suspectăm că vom eșua din nou). Anterior eșec ar putea fi un ClassNotFoundException sau un ExceptionInInitializerError (indicând o defecțiune în static de initializare bloc) sau orice număr de alte probleme. Ideea este, o NoClassDefFoundError nu este neapărat un classpath problema.

Comentarii (12)
Soluția

Acest lucru este cauzat atunci când există un fișier de clasă care codul dvs. depinde și este prezent la compilare dar nu a fost găsit în timpul rulării. Uita-te pentru diferențele în timp construi și de execuție căi.

Comentarii (7)

Aici este codul pentru a ilustra java.lang.NoClassDefFoundError. Vă rugăm să consultați Jared's a răspunde pentru o explicație detaliată.

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;
}
Comentarii (3)

NoClassDefFoundError În Java

Definiție:

  1. Java Virtual Machine nu este capabil de a găsi o anumită clasă la runtime, care a fost disponibil la momentul compilării.

  2. Dacă o clasă a fost prezent în timpul compilării, dar nu sunt disponibile în java clase în timpul rulării.

Exemple:

  1. Clasa nu este în Clase, nu există nici o lovitură sigur mod de a ști, dar de multe ori puteți avea doar o privire la Sistemul de imprimare.getproperty("java.classpath") și va imprima classpath de acolo, puteți obține cel puțin o idee de runtime real classpath.

  2. Un exemplu simplu de NoClassDefFoundError este clasa aparține lipsește un fișier JAR sau BORCAN nu a fost adăugat în classpath sau uneori borcan's nume a fost schimbat de cineva ca in cazul meu unul dintre colegii mei s-a schimbat tibco.jar în tibco_v3.jar iar programul este faptul că nu cu java.lang.NoClassDefFoundError și mă întrebam ce's-a întâmplat.

  3. Doar să încercați pentru a rula în mod explicit cu -classpath opțiune cu clase credeți că va funcționa și în cazul'e de lucru, apoi se's un sigur semn scurt că cineva este imperativ java-classpath.

  4. Permisiunea problema pe JAR fișier poate provoca, de asemenea, NoClassDefFoundError în Java.

  5. Typo pe Configurare XML poate provoca, de asemenea NoClassDefFoundError în Java.

  6. când compilat clasa care este definit într-un pachet, nu prezintă în același pachet în timp ce de încărcare ca în cazul JApplet se va arunca NoClassDefFoundError în Java.

Soluții Posibile:

  1. Clasa nu este disponibil în Java-Classpath.
  2. Dacă lucrați în J2EE mediu decât cel de vizibilitate de Clasă între multiple Agent poate, de asemenea, provoca java.lang.NoClassDefFoundError, a se vedea exemplele și scenariu secțiune pentru discuții detaliate.
  3. Verificați pentru java.lang.ExceptionInInitializerError în fișierul jurnal. NoClassDefFoundError din cauza eșecului de static de initializare este destul de comună.
  4. Pentru că NoClassDefFoundError este o subclasă de java.lang.LinkageError se poate veni, de asemenea, dacă unul dintre dependența de astfel de nativ library poate nu este disponibil.
  5. Orice start-up script este imperativ variabila de mediu Classpath.
  6. S-ar putea fi difuzate programul folosind borcan de comandă și de clasă nu a fost definit în fișierul manifest's Clase atribut.

Resurse:

3 moduri de a rezolva NoClassDefFoundError

java.lang.NoClassDefFoundError Problema modele

Comentarii (2)

Am constatat că uneori am o NoClassDefFound de eroare atunci când codul este compilat cu o versiune incompatibilă de clasa a găsit la runtime. Specifice de exemplu, îmi amintesc este cu apache axis bibliotecă. De fapt au fost 2 versiuni pe clase de execuție și a cules din data de și incompatibile versiune și nu cea corectă, cauzând un NoClassDefFound eroare. Acest lucru a fost într-o aplicație de linie de comandă în cazul în care am fost, folosind o comandă asemănătoare cu aceasta.

set classpath=%classpath%;axis.jar

Am fost capabil de a obține pentru a alege versiunea corectă prin utilizarea:

set classpath=axis.jar;%classpath%;
Comentarii (2)

Asta e cea mai bună soluție]1 am găsit până acum.

Să presupunem că avem un pachet numit org.mypackage conțin clase:

  • HelloWorld (clasa principală)
  • SupportClass
  • UtilClass

și fișierele definirea acestui pachet sunt stocate fizic în directorul D:\myprogram (pe Windows) sau /home/user/myprogram (pe Linux).

Structura fișierului va arata astfel:

Atunci când invocăm Java, vom specifica numele aplicației pentru a rula: org.mypackage.HelloWorld. Cu toate acestea, trebuie să spun, de asemenea, Java unde să căutați pentru fișiere și directoare care definesc pachetul nostru. Deci, pentru a lansa programul, trebuie să folosim următoarea comandă:

Comentarii (0)

Am fost folosind Cadru de Primăvară cu Maven și a rezolvat această eroare în proiectul meu.

Nu a fost o eroare de execuție din clasa. Am citit o proprietate ca un întreg, dar când se citește valoarea din fișierul de proprietate, valoarea sa a fost dublă.

Primavara nu mi-a dat un full stack trace-ul de pe care linia de runtime nu a reușit. S-a spus simplu NoClassDefFoundError. Dar când am executat-o ca un nativ aplicație Java (ia de MVC), a dat ExceptionInInitializerError` care a fost adevarata cauza și care este modul în care am urmărit de eroare.

@xli's a raspuns mi-a dat o perspectivă în ceea ce poate fi greșit în codul meu.

Comentarii (1)

Am NoClassFoundError când clasele încărcate de runtime class loader nu pot accesa clase deja încărcate de java rootloader. Deoarece diferite încărcătoare de clasă sunt în diferite domenii de securitate (în conformitate cu java) jvm câștigat't permite clase deja încărcate de rootloader să fie rezolvate în execuție loader spațiu de adrese.

Rula programul cu 'java -javaagent:tracer.jar [java ARGS]'

Se produce de ieșire arată încărcate de clasă, și încărcător env că încărcate clasa. L's foarte utile contur de ce o clasă nu pot fi rezolvate.

// 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;
            }
        });
    }
}
Comentarii (1)

Un caz interesant, în care s-ar putea vedea o mulțime de NoClassDefFoundErrors` este atunci când:

  1. "arunca" o RuntimeException în "statice" bloc de clasă "Exemplu"
  2. Intercepta (sau dacă nu't contează ca acesta este aruncat într-o test)
  3. Încercați să creați o instanță a acestei clase "Exemplu"


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 va fi aruncat însoțită cu ExceptionInInitializerErrorde la bloc staticRuntimeException`.


Acest lucru este important mai ales în cazul când veți vedea NoClassDefFoundErrors în TESTE UNITARE.

Într-un fel're "schimbul de" "statice" bloc de execuție între teste, dar inițială ExceptionInInitializerError va fi doar într-un singur caz-test. Primul care folosește problematice "Exemplu" de clasă. Alte cazuri de testare care folosesc "Exemplu" clasa va arunca NoClassDefFoundErrors.

Comentarii (1)

În cazul în care ați generat-cod (EMF, etc.) nu pot fi prea multe static initialisers care consuma toate stivă spațiu.

Vezi Stiva Preaplin întrebare https://stackoverflow.com/questions/3700459/how-to-increase-the-java-stack-size.

Comentarii (2)

Tehnica de mai jos m-a ajutat de multe ori:

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

unde TheNoDefFoundClass este clasa care ar putea fi "pierdut" din cauza la o preferință pentru o versiune mai veche de aceeași bibliotecă utilizate de program. Acest cel mai frecvent se întâmplă cu cazurile, atunci când software-ul client este implementat într-o dominantă container, înarmat cu propriile classloaders și de tone de versiuni vechi de cel mai popular libs.

Comentarii (0)

NoClassDefFoundError poate apărea, de asemenea, atunci când un static inițializare încearcă să încarce un pachet de resurse, care nu este disponibil în timpul rulării, de exemplu, un fișier de proprietăți pe care afectate de clasă încearcă să încarce din META-INFdirector, dar nu e acolo. Dacă nu prind NoClassDefFoundError, uneori, nu va fi capabil pentru a vedea full stack trace; pentru a depăși acest lucru, puteți utiliza temporar un "prinde" clauza pentru Throwable`:

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

Mi-am reparat problema prin dezactivarea preDexLibraries pentru toate modulele:

dexOptions {
        preDexLibraries false
        ...
Comentarii (1)

Am primit această eroare atunci când am adăuga Maven dependența de un alt modul pentru proiectul meu, problema a fost rezolvată în cele din urmă de a adăuga `-Xss2m la programul meu's JVM opțiune(It's un megabyte în mod implicit, deoarece JDK5.0). L's-a crezut programul nu are suficient stiva la clasa de încărcare.

Comentarii (0)

Dacă cineva vine aici pentru că de java.lang.NoClassDefFoundError: org/apache/log4j/Loggereroare, în cazul meu acesta a fost produs pentru că am folosit log4j 2 (dar nu't adăuga toate fișierele care vin cu ea), și unele dependență de bibliotecă utilizate log4j 1. Soluția a fost de a adăuga Log4j 1.x bridge: borcanlog4j-1.2-api-.borcan`, care vine cu log4j 2. Mai multe informații în log4j 2 migrației.

Comentarii (0)

Două tipuri diferite de checkout copii ale aceluiași proiect

În cazul meu, problema a fost Eclipsa's incapacitatea de a diferenția între două copii diferite ale aceluiași proiect. Am unul blocat pe portbagaj (versiunea SVN control) și celălalt de lucru într-o ramură la un moment dat. Am încercat o schimbare în copia de lucru ca un JUnit test de caz, care sunt incluse extragerea unui interioară privată clasă să fie o clasă publică pe cont propriu și în timp ce ea a fost de lucru, am deschis o altă copie a proiectului să se uite în jurul valorii de la o parte de cod care avea nevoie de modificări. La un moment dat, NoClassDefFoundError a apărut proteste privată interioară class nu a fost acolo; dublu-clic în stivă urmă m-a adus la fișierul sursă în proiect greșit copie.

Închideți portbagajul copie a proiectului și funcționare caz test din nou am scapat de problema.

Comentarii (0)

Această eroare poate fi cauzată de necontrolat versiune Java cerinte.

În cazul meu, am fost capabil de a rezolva această eroare, în timp ce construirea unui profil mare proiect open-source, prin trecerea de la Java 9 pentru Java 8 folosind SDKMAN!.

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

Apoi face o instalare curată, așa cum este descris mai jos.


Atunci când se utilizează Maven ca instrument de a construi, uneori este util ... și de obicei îmbucurător, pentru a face o curat 'instala' de a construi cu testarea cu handicap.

mvn clean install -DskipTests

Acum, că totul a fost construit și instalat, puteți să mergeți mai departe și a alerga la teste.

mvn test
Comentarii (0)

Am NoClassDefFound erori atunci când am't de export o clasă pe "Ordine și de Export" fila în Java Build Path de proiectul meu. Asigurați-vă că pentru a pune o bifă în "Ordine și de Export" fila de orice dependențe adăugați la proiect's a construi calea. Vezi https://stackoverflow.com/questions/8884818/eclipse-warning-xxxxxxxxxxx-jar-will-not-be-exported-or-published-runtime-clas.

Comentarii (0)

Ar putea fi, de asemenea, pentru că vă copiați fișiere de la un IDE cu un anumit pachetul nume și doriți să încercați să rulați-l folosind terminalul. Va trebui să scoateți pachetul nume de cod în primul rând. Acest lucru se întâmplă cu mine.

Comentarii (0)

Java a fost în imposibilitatea de a găsi de clasă în timpul rulării. Clasa a fost în proiect maven ArtClient dintr-un alt spațiu de lucru. Așa că am importat ArtClient meu proiect Eclipse. Două dintre proiectele mele a fost folosind ArtClient fel de dependență. Am schimbat bibliotecă de referință pentru proiect de referință pentru acestea (Build Path -> Configurare Construi Calea).

Și problema a dispărut.

Comentarii (0)