Waarom krijg ik een NoClassDefFoundError in Java?

Ik krijg een NoClassDefFoundErrorwanneer ik mijn Java-toepassing start. Wat is hier typisch de oorzaak van?


Antwoord 1, autoriteit 100%

Dit wordt veroorzaakt wanneer er een klassenbestand is waarvan uw code afhankelijk is en dat aanwezig is tijdens het compileren, maar niet wordt gevonden tijdens runtime. Zoek naar verschillen in uw bouwtijd en runtime-klassepaden.


Antwoord 2, autoriteit 90%

Hoewel het mogelijk is dat dit te wijten is aan een classpath-mismatch tussen compile-time en run-time, is dit niet noodzakelijk waar.

Het is belangrijk om in dit geval twee of drie verschillende uitzonderingen in ons hoofd te houden:

  1. java.lang.ClassNotFoundExceptionDeze uitzondering geeft aan dat de klasse niet is gevonden op het klassenpad. Dit geeft aan dat we de klassedefinitie probeerden te laden en dat de klasse niet bestond op het klassenpad.

  2. java.lang.NoClassDefFoundErrorDeze uitzondering geeft aan dat de JVM in zijn interne klassedefinitiegegevensstructuur heeft gezocht naar de definitie van een klasse en deze niet heeft gevonden . Dit is iets anders dan zeggen dat het niet kan worden geladen vanuit het klassenpad. Meestal geeft dit aan dat we eerder hebben geprobeerd een klasse van het klassenpad te laden, maar dat dit om de een of andere reden is mislukt – nu proberen we de klasse opnieuw te gebruiken (en moeten deze dus laden, omdat het de vorige keer niet lukte), maar we’ we gaan het niet eens proberen om het te laden, omdat we het eerder niet hebben geladen (en redelijkerwijs vermoeden dat we het opnieuw zouden mislukken). De eerdere fout kan een ClassNotFoundException of een ExceptionInInitializerError zijn (die een fout aangeeft in het statische initialisatieblok) of een aantal andere problemen. Het punt is dat een NoClassDefFoundError niet per se een classpath-probleem is.


Antwoord 3, autoriteit 48%

Hier is de code om java.lang.NoClassDefFoundErrorte illustreren. Zie Jareds antwoordvoor gedetailleerde uitleg.

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;
}

Antwoord 4, autoriteit 15%

NoClassDefFoundError In Java

Definitie:

  1. Java Virtual Machine kan tijdens runtime een bepaalde klasse niet vinden die beschikbaar was tijdens het compileren.

  2. Als een klasse aanwezig was tijdens het compileren, maar niet beschikbaar was in Java-klassenpad tijdens runtime.

Voorbeelden:

  1. De klasse bevindt zich niet in Classpath, er is geen zekere manier om het te weten, maar vaak kun je gewoon kijken om System.getproperty (“java.classpath”) af te drukken en het zal het klassenpad van daaruit afdrukken. krijg in ieder geval een idee van je werkelijke runtime-klassenpad.
  2. Een eenvoudig voorbeeld van noclassdeffounror is klasse behoort tot een ontbrekend jar-bestand of pot is niet toegevoegd in het klassenpad of soms is de naam van JAR zijn veranderd door iemand zoals in mijn geval een van mijn collega’s in Tibco.jar is in Tibco_v3 veranderd .jar en het programma faalt met Java.lang.noclassdeffoundError en ik vroeg me af wat er aan de hand is.

  3. Probeer gewoon te rennen met expliciet -classpath-optie met het klassenpad waarvan je denkt dat het zal werken en als het werkt, dan is het een zeker kort teken dat iemand het Java ClassPath overschrijft.

  4. Toestemmingsprobleem op JAR-bestand kan ook noclassdeffoundror in Java veroorzaken.
  5. TYPO ON XML-configuratie kan ook noclassdeffoundror in Java veroorzaken.
  6. Wanneer uw gecompileerde klasse die is gedefinieerd in een pakket, niet in hetzelfde pakket aanwezig is tijdens het laden zoals in het geval van japplet, gooide het noclassdeffoundror in Java.

mogelijke oplossingen:

  1. De klasse is niet beschikbaar in Java ClassPath.
  2. Als u in J2EE-omgeving werkt dan de zichtbaarheid van de les onder meerlasserlader ook Java.lang.noclassDeffoundError kan veroorzaken, zie voorbeelden en scenario-sectie voor gedetailleerde discussie.
  3. Controleer op java.lang.exeptionininitializerError in uw logbestand. NoclassdeffoundError Vanwege het falen van statische initialisatie is vrij gebruikelijk.
  4. Omdat NoclassdeffoundError een subklasse van Java.lang.LinkageError is, kan het ook komen als een van de afhankelijkheid van de inheemse bibliotheek niet beschikbaar is.
  5. Elk start-up-script is overheersend klassenvariabele.
  6. U kunt uw programma gebruiken met behulp van JAR-opdracht en -klasse is niet gedefinieerd in het ClassPath-attribuut van Manifest File.

Middelen:

3 manieren om NoclassdeffoundError

op te lossen

java.lang.noclassdeffoundError Probleem Patronen


Antwoord 5, Autoriteit 12%

Ik heb gevonden dat ik soms een noclassdeffound-fout krijg wanneer de code is samengesteld met een incompatibele versie van de klasse die op runtime wordt gevonden. De specifieke instantie die ik recall is met de Apache Axis-bibliotheek. Er waren eigenlijk 2 versies op mijn runtime-klassenpad en het oppakte de verouderde en incompatibele versie en niet de juiste, waardoor een noclassdeffound-fout veroorzaakt. Dit was in een opdrachtregel-app waar ik een commando met behulp van.

set classpath=%classpath%;axis.jar

Ik kon het krijgen om de juiste versie op te halen met behulp van:

set classpath=axis.jar;%classpath%;

Antwoord 6, Autoriteit 3%

Dit is de beste oplossing Ik heb tot nu toe gevonden.

Stel dat we een pakket hebben genaamd org.mypackagemet de klassen:

  • HELLOWORLD (hoofdklasse)
  • Ondersteuningsclass
  • utilclass

en de bestanden die dit pakket definiëren worden fysiek opgeslagen onder de directory D:\myprogram(op Windows) of /home/user/myprogram(op Linux).

De bestandsstructuur ziet er als volgt uit:

Als we Java aanroepen, specificeren we de naam van de uit te voeren toepassing: org.mypackage.HelloWorld. We moeten Java echter ook vertellen waar we moeten zoeken naar de bestanden en mappen die ons pakket definiëren. Dus om het programma te starten, moeten we de volgende opdracht gebruiken:


Antwoord 7, autoriteit 2%

Ik gebruikte Spring Frameworkmet Mavenen loste deze fout in mijn project op.

Er is een runtime-fout opgetreden in de klas. Ik las een eigenschap als geheel getal, maar toen het de waarde uit het eigenschappenbestand las, was de waarde dubbel.

Spring gaf me geen volledige stack-tracering van op welke regel de runtime mislukte.
Er stond gewoon NoClassDefFoundError. Maar toen ik het uitvoerde als een native Java-toepassing (het uit MVC haalde), gaf het ExceptionInInitializerErrorwat de echte oorzaak was en zo heb ik de fout getraceerd.

@xli’s antwoord gaf me inzicht in wat er mis kan zijn in mijn code.


Antwoord 8, autoriteit 2%

Een interessant geval waarin u mogelijk veel NoClassDefFoundErrorsziet, is wanneer u:

  1. throween RuntimeExceptionin het staticblok van je klas Example
  2. Onderschep het (of als het er gewoon niet toe doet, zoals het in een testcasewordt gegooid)
  3. Probeer een instantie van deze klasse te maken 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
    }
}

NoClassDefErrorWORDT GEGEN GEGONDIGHEID MET ExceptionInInitializerErrorVAN HET STATISCHE BLOK RuntimeException.


Dit is met name belangrijke zaak wanneer u NoClassDefFoundErrorsin uw –eenheidstests hebt.

Op een manier ben je “delen” de staticBlokkeer uitvoering tussen tests, maar de initiële ExceptionInInitializerErroris net in één testcase. De eerste die de problematische Exampleklasse. Andere testgevallen die de ExampleKlasse worden gewoon gooien NoClassDefFoundErrors.


Antwoord 9, Autoriteit 2%

Ik krijg NoclassfoundError wanneer klassen die worden geladen door de runtime-klassenlader geen toegang hebben tot klassen die al door de Java-rootloader zijn geladen. Omdat de verschillende klassladers in verschillende beveiligingsdomeinen zijn (volgens Java), zal de JVM niet toestaan ​​dat klassen die al zijn geladen door de rootloader die moet worden opgelost in de runtime-ladingsadresruimte.

Voer uw programma uit met ‘Java -JavaAgent: Tracer.jar [Your Java Args]’

Het produceert uitgang die de geladen klasse toont, en de loader-env die de klas heeft geladen. Het is zeer nuttig om te traceren waarom een ​​klasse niet kan worden opgelost.

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

Antwoord 10

De onderstaande techniek heeft me vaak geholpen:

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

waarbij de TheNoDefFoundClass de klasse is die mogelijk “verloren” gaat vanwege een voorkeur voor een oudere versie van dezelfde bibliotheek die door uw programma wordt gebruikt. Dit gebeurt het vaakst met de gevallen waarin de clientsoftware wordt geïmplementeerd in een dominante container, gewapend met zijn eigen classloaders en tonnen oude versies van de meest populaire bibliotheken.


Antwoord 11

In het geval dat u gegenereerde code (EMF, etc.) heeft, kunnen er te veel statische initialisatoren zijn die alle stackruimte in beslag nemen.

Zie Stack Overflow-vraag Hoe de Java-stackgrootte te vergroten ?.


Antwoord 12

Twee verschillende kassa-exemplaren van hetzelfde project

In mijn geval was het probleem het onvermogen van Eclipse om onderscheid te maken tussen twee verschillende exemplaren van hetzelfde project. Ik heb er een die op de stam is vergrendeld (SVN-versiebeheer) en de andere werkt in één tak tegelijk. Ik heb één wijziging in de werkkopie uitgeprobeerd als een JUnit-testcase, waaronder het extraheren van een privé-innerlijke klasse om op zichzelf een openbare klasse te zijn en terwijl het werkte, open ik de andere kopie van het project om rond te kijken naar een andere deel van de code dat moest worden gewijzigd. Op een gegeven moment dook de NoClassDefFoundErrorop en klaagde dat de private innerlijke klasse er niet was; dubbelklikken in de stacktracering bracht me bij het bronbestand in de verkeerde projectkopie.

Het sluiten van de trunk-kopie van het project en het opnieuw uitvoeren van de testcase loste het probleem op.


Antwoord 13

Ik heb mijn probleem opgelost door de preDexLibraries voor alle modules uit te schakelen:

dexOptions {
        preDexLibraries false
        ...

Antwoord 14

Ik kreeg deze foutmelding toen ik Maven-afhankelijkheid van een andere module aan mijn project toevoeg, het probleem werd uiteindelijk opgelost door -Xss2mtoe te voegen aan de JVM-optie van mijn programma (het is standaard één megabyte sinds JDK5.0 ). Er wordt aangenomen dat het programma niet genoeg stack heeft om de klasse te laden.


Antwoord 15

NoClassDefFoundErrorkan ook optreden wanneer een statischeinitializer probeert een resourcebundel te laden die niet beschikbaar is in runtime, bijvoorbeeld een eigenschappenbestand dat de getroffen klasse probeert te laden uit de META-INFdirectory, maar is er niet. Als u NoClassDefFoundErrorniet opvangt, kunt u soms de volledige stacktracering niet zien; om dit te verhelpen kunt u tijdelijk een catch-clausule gebruiken voor Throwable:

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

Antwoord 16

Als iemand hier komt vanwege een java.lang.NoClassDefFoundError: org/apache/log4j/Logger-fout, is deze in mijn geval gemaakt omdat ik log4j 2 heb gebruikt (maar ik heb niet alle de bijbehorende bestanden), en een afhankelijkheidsbibliotheek gebruikte log4j 1. De oplossing was om de Log4j 1.x-brug toe te voegen: de jar log4j-1.2-api-<version>.jardie wordt geleverd met log4j 2. Meer info in de log4j 2 migratie.


Antwoord 17

Deze fout kan worden veroorzaakt door niet-aangevinkte vereisten voor de Java-versie.

In mijn geval kon ik deze fout oplossen, terwijl ik een spraakmakend open-sourceproject bouwde, door over te schakelen van Java 9 naar Java 8 met behulp van SDKMAN!.

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

Doe vervolgens een schone installatie zoals hieronder beschreven.


Bij gebruik Maven Zoals uw build-tool is, is het soms behulpzaam – en meestal bevredigend, om een ​​schoon te maken ‘install’ build met testen gehandicapten .

mvn clean install -DskipTests

Nu dat alles is gebouwd en geïnstalleerd, kunt u doorgaan en de tests uitvoeren.

mvn test

Antwoord 18

Ik heb noclassdeffound fouten toen ik geen klasse exporteerde op het tabblad ‘Bestel en export’ in het Java Build Path of My Project. Zorg ervoor dat u een vinkje in het tabblad “Bestellen en exporteren” van alle afhankelijkheden toevoegen die u toevoegt aan het Build Path van het project. Zie Eclipse Waarschuwing: XXXXXXXXXXX.JAR niet worden geëxporteerd of gepubliceerd. Runtime ClassNotFoundexceptions kan resulteren .


Antwoord 19

Het kan ook zijn omdat u het codebestand kopieert van een IDE met een bepaalde pakketnaam en u wilt proberen het te gebruiken met Terminal. U moet eerst de pakketnaam van de code verwijderen.
Dit gebeurt met mij.


Antwoord 20

In mijn geval kreeg ik deze foutmelding vanwege een mismatch in de JDK-versies. Toen ik probeerde de applicatie uit Intelij te runnen, werkte het niet, maar rende het dan van de gewerkte opdrachtregel. Dit komt omdat Intelij probeerde het te rennen met de Java 11 JDK die opgezet was, maar op de opdrachtregel werd het uitgevoerd met de Java 8 JDK. Na het schakelen van die instelling onder File & GT; Projectstructuur & GT; Projectinstellingen & GT; Project SDK, het werkte voor mij.


Antwoord 21

Iedereen praat hier over Java-configuratiedingen, JVM-problemen, enz., in mijn geval was de fout helemaal niet gerelateerd aan deze onderwerpen en had een zeer triviale en gemakkelijk op te lossen reden: ik had een verkeerde annotatie op mijn eindpunt in mijn Controller (Spring Boot-toepassing).


Antwoord 22

Ik heb een interessant probleem gehad met NoClassDefFoundError in JavaEE die werkt met de Liberty-server. Ik gebruikte IMS-bronadapters en mijn server.xml had al een bronadapter voor imsudbJXA.rar.
Toen ik een nieuwe adapter voor imsudbXA.rar toevoegde, kreeg ik deze fout voor bijvoorbeeld objecten voor DLIException, IMSConnectionSpec of SQLInteractionSpec.
Ik begreep niet waarom, maar ik heb het opgelost door een nieuwe server.xml te maken voor mijn werk met alleen imsudbXA.rar. Ik weet zeker dat het gebruik van meerdere bronadapters in server.xml prima is, ik had alleen geen tijd om daar naar te kijken.


Antwoord 23

Bijwerken [https://www.infoq.com/articles/single-file-execution-java11/]:

In Java SE 11 krijgt u de mogelijkheid om een enkel broncodebestand te starten
direct, zonder tussentijdse compilatie. Gewoon voor uw gemak,
zodat nieuwelingen zoals jij geen javac + java hoeven te gebruiken (natuurlijk,
waardoor ze in de war raken waarom dat zo is).


Antwoord 24

Ik had deze fout maar kon de oplossing niet vinden op basis van deze thread, maar heb het zelf opgelost.

Voor mijn probleem was ik deze code aan het compileren:

package valentines;
import java.math.BigInteger;
import java.util.ArrayList;
public class StudentSolver {
    public static ArrayList<Boolean> solve(ArrayList<ArrayList<BigInteger>> problems) {
        //DOING WORK HERE
    }
    public static void main(String[] args){
        //TESTING SOLVE FUNCTION
    }
}

Ik was toen deze code aan het compileren in een mappenstructuur die eruitzag als /ProjectName/valentines
Het compileren werkte prima, maar probeerde uit te voeren: java StudentSolver

Ik kreeg de NoClassDefError.

Om dit op te lossen heb ik simpelweg verwijderd: package valentines;

Ik ben niet zo goed thuis in Java-pakketten en dergelijke, maar dit is hoe ik mijn fout heb opgelost, dus sorry als dit al door iemand anders is beantwoord, maar ik kon het niet interpreteren voor mijn probleem.


Antwoord 25

Ik kreeg NoClassDefFoundErrorterwijl ik probeerde een applicatie te implementeren op Tomcat/JBOSS-servers. Ik speelde met verschillende afhankelijkheden om het probleem op te lossen, maar kreeg steeds dezelfde foutmelding. Markeerde alle javax.*-afhankelijkheden zoals voorzien in pom.xml, en oorlog had letterlijk geen afhankelijkheid. Toch bleef het probleem zich voordoen.

Eindelijk gerealiseerd dat src/main/webapps/WEB-INF/classesde map classeshad die naar mijn oorlog werd gekopieerd, dus in plaats van gecompileerde klassen, werden deze klassen gekopieerd, vandaar dat geen verandering in de afhankelijkheid het probleem oploste.

Wees daarom voorzichtig als eerder gecompileerde gegevensworden gekopieerd. Na het verwijderen van de klassenmap en een nieuwe compilatie, werkte het!..


Antwoord 26

ClassNotFoundException versus NoClassDefFoundError

[ClassLoader]

Statisch versus dynamisch laden van klassen

Static(Implicit) class loading– resultaat van verwijzing, concretisering of overerving.

MyClass myClass = new MyClass();

Dynamic(Explicit) class loadingis het resultaat van Class.forName(), loadClass(), findSystemClass()

MyClass myClass = (MyClass) Class.forName("MyClass").newInstance();

Elke klas heeft een ClassLoaderdie gebruik maakt van loadClass(String name);Daarom

explicit class loader uses implicit class loader

NoClassDefFoundErroris een onderdeel van explicit class loader. Het is Errorom te garanderen dat tijdens de compilatie deze klasse is gepresenteerd, maar nu
(in tun tijd) het is afwezig

ClassNotFoundExceptionis een onderdeel van implicit class loader. Het is Exceptionom elastisch te zijn met scenario’s waar bovendien het kan worden gebruikt – bijvoorbeeld reflectie.


Antwoord 27

Java kon de klasse A in runtime niet vinden.
Klasse A was in Maven Project ArtClient van een andere werkruimte.
Dus importeerde ik artclient aan mijn Eclipse-project.
Twee van mijn projecten gebruikten artclient als afhankelijkheid.
Ik veranderde bibliotheekreferentie naar projectreferentie voor deze (Build Path – & GT; Configure Build Path).

en het probleem verdwenen.


Antwoord 28

Ik had hetzelfde probleem, en ik was voor vele uren voorraad.

Ik heb de oplossing gevonden. In mijn geval was er vanwege die daaraan gedefinieerde statische methode. De JVM kan het andere object van die klasse niet maken.

Bijvoorbeeld,

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

Antwoord 29

Ik heb dit bericht na het verwijderen van twee bestanden van de SRC-bibliotheek en toen ik ze terug bracht, bleef ik deze foutmelding zien.

Mijn oplossing was: Restart Eclipse. Sindsdien heb ik dit bericht niet meer gezien: -)


ANTWOORD 30

Zorg ervoor dat dit overeenkomt in de module:appen module:lib:

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }
    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }

Other episodes