Hoe kan ik “java.lang.NoClassDefFoundError” oplossen?

Ik heb beide voorbeelden geprobeerd in Oracle’s Java Tutorials. Ze compileren allebei prima, maar tijdens runtime komen beide met deze fout:

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

Ik denk dat ik het bestand Main.javain de verkeerde map heb staan.

Hier is de directoryhiërarchie:

graphics
├ Main.java
├ shapes
|   ├ Square.java
|   ├ Triangle.java
├ linepoint
|   ├ Line.java
|   ├ Point.java
├ spaceobjects
|   ├ Cube.java
|   ├ RectPrism.java

En hier is 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);
    }
}

Wat doe ik hier verkeerd?

UPDATE

Nadat ik de klasse Mainin het pakket graphicsheb geplaatst (ik heb er package graphics;aan toegevoegd), stel het classpath in op ” _test” (map met afbeeldingen), gecompileerd en uitgevoerd met java graphics.Main(vanaf de opdrachtregel), het werkte.

Heel late UPDATE #2

Ik gebruikte Eclipseniet (alleen Notepad++en de JDK), en de bovenstaande update loste mijn probleem op. Het lijkt er echter op dat veel van deze antwoorden voor Eclipse en IntelliJ IDEAzijn, maar ze hebben vergelijkbare concepten.


Antwoord 1, autoriteit 100%

Nadat je je code hebt gecompileerd, krijg je .class-bestanden voor elke klasse in je programma. Deze binaire bestanden zijn de bytecode die Java interpreteert om uw programma uit te voeren. De NoClassDefFoundErrorgeeft aan dat de classloader (in dit geval java.net.URLClassLoader), die verantwoordelijk is voor het dynamisch laden van klassen, de .classbestand voor de klas die je probeert te gebruiken.

Je code zou niet compileren als de vereiste klassen niet aanwezig waren (tenzij klassen zijn geladen met reflectie), dus meestal betekent deze uitzondering dat je klassenpad niet de vereiste klassen bevat. Onthoud dat de classloader (in het bijzonder java.net.URLClassLoader) zal zoeken naar klassen in pakket a.b.c in map a/b/c/ in elk item in je classpath. NoClassDefFoundErrorkan ook aangeven dat je een transitieve afhankelijkheid mist van een .jar-bestand dat je hebt gecompileerd en dat je probeert te gebruiken.

Als je bijvoorbeeld een klasse com.example.Foohad, zou je na het compileren een klassebestand Foo.classhebben. Stel bijvoorbeeld dat uw werkdirectory .../project/is. Dat klassenbestand moet in .../project/com/exampleworden geplaatst, en je zou je klassenpad instellen op .../project/.

Kanttekening: ik zou aanraden gebruik te maken van de geweldige tooling die bestaat voor Java- en JVM-talen. Moderne IDE’s zoals Eclipse en IntelliJ IDEA en buildbeheertools zoals Maven of Gradle helpen je om je niet (zoveel) zorgen te maken over classpaths en je op de code te concentreren! Dat gezegd hebbende, deze linklegt uit hoe u het klassenpad instelt wanneer u de opdrachtregel.


Antwoord 2, autoriteit 54%

Ik wil graag het perspectief van anderen corrigeren op NoClassDefFoundError.

NoClassDefFoundErrorkan meerdere redenen hebben, zoals:

  1. ClassNotFoundException — .class niet gevonden voor die klasse waarnaar wordt verwezen, ongeacht of deze beschikbaar is tijdens het compileren of niet (d.w.z. base/child-klasse).
  2. Klassebestand gevonden, maar uitzondering opgekomen tijdens het initialiseren van statische variabelen
  3. Klassebestand gevonden, uitzondering verhoogd tijdens initialisatie van statische blokken

In de oorspronkelijke vraag was dit het eerste geval dat kan worden gecorrigeerd door CLASSPATH in te stellen op het JAR-bestand met klassen waarnaar wordt verwezen of naar de pakketmap.

Wat betekent het om te zeggen “beschikbaar tijdens compileren”?

  • De klasse waarnaar wordt verwezen wordt in de code gebruikt.
    Bijv.: Twee klassen, A en B (verlengt A). Als er rechtstreeks in de code naar B wordt verwezen, is deze beschikbaar tijdens het compileren, d.w.z. A a = new B();

Wat betekent het om te zeggen “niet beschikbaar tijdens het compileren”?

  • De klasse voor compileren en runtime zijn verschillend, d.w.z. de basisklasse wordt bijvoorbeeld geladen met de klassenaam van de onderliggende klasse
    Class.forName(“klassenaam”)
    Bijv.: Twee klassen, A en B (verlengt A). Code heeft
    A a = Class.forName("B").newInstance();

Antwoord 3, autoriteit 6%

NoClassDefFoundErrorbetekent dat de klasse aanwezig is in het klassenpad op Compile time, maar niet bestaat in het klassenpad op Runtime.

Als je Eclipse gebruikt, zorg er dan voor dat je de shapes, linepointsen de spaceobjectsals items in de .classpathbestand.


Antwoord 4, autoriteit 5%

Als u een van deze fouten krijgt tijdens het compileren en uitvoeren:

  • NoClassDefFoundError

  • Fout: kan hoofdklasse niet vinden of laden hallo

  • Uitzondering in thread “main” java.lang.NoClassDefFoundError:javaTest/test/hello
    (verkeerde naam: test/hallo)

    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)
    

————————– Oplossing—— —————–

Het probleem zit vooral in de organisatie van pakketten. Je moet je klassen goed in mappen ordenen met betrekking tot de pakketclassificaties in je broncode.

Gebruik tijdens het compileren deze opdracht:

javac -d . [FileName.java]

Gebruik deze opdracht om de klas uit te voeren:

java [Package].[ClassName]

Antwoord 5, autoriteit 4%

java.lang.NoClassDefFoundError

geeft aan dat er iets is gevonden tijdens compilatietijd, maar niet tijdens runtime. Misschien moet je het gewoon aan het klassenpad toevoegen.


Antwoord 6, autoriteit 3%

NoClassDefFoundError in Java:

Definitie:

NoClassDefFoundError treedt op als een klasse aanwezig was tijdens het compileren, maar niet beschikbaar was in Java-klassenpad tijdens runtime. Normaal gesproken ziet u de onderstaande regel in het logboek wanneer u NoClassDefFoundError krijgt:
Uitzondering in thread “main” java.lang.NoClassDefFoundError

Mogelijke oorzaken:

  1. De klasse is niet beschikbaar in Java Classpath.

  2. Misschien voert u uw programma uit met het jar-commando en is class niet gedefinieerd in het ClassPath-kenmerk van het manifestbestand.

  3. Elk opstartscript overschrijft de omgevingsvariabele Classpath.

  4. Omdat NoClassDefFoundError een subklasse is van java.lang.LinkageError, kan het ook voorkomen als een van de afhankelijkheid, zoals de native bibliotheek, niet beschikbaar is.

  5. Controleer op java.lang.exeptionininitializerError in uw logbestand. NoclassdeffoundError Door het falen van statische initialisatie is vrij gebruikelijk.

  6. Als u in J2EE-omgeving werkt dan de zichtbaarheid van de les tussen meerdere klasserlader ook Java.lang.noclassdeffounror, zie voorbeelden en scenario-sectie voor gedetailleerde discussie.

Mogelijke resoluties:

  1. Controleer of alle vereiste Java-lessen zijn opgenomen in het klassenpad van de toepassing. De meest voorkomende fout is niet alle benodigde klassen op te nemen voordat u begint met het uitvoeren van een Java-applicatie die afhankelijkheden heeft op sommige externe bibliotheken.

  2. Het klassenpad van de applicatie is correct, maar de variabele Klasspath Milieu wordt opgeheven vóór de uitvoering van de toepassing.

  3. Controleer of de hiervoor genoemde uitzonderingsinalizerizerizerror niet in het stapelspoor van uw aanvraag verschijnt.

bronnen:

3 manieren om Java.lang.noclassdeffoundError op te lossen in Java J2EE

java.lang.noclassdeffoundError – Hoe oplossen geen klasse def gevonden fout


7, Autoriteit 3%

De uitzondering zonder class-definitie treedt op wanneer de beoogde klasse niet in het klassenpad wordt gevonden.

Bij Compile Time Class: Klasse werd gegenereerd uit de Java-compiler, maar op de een of andere manier wordt de afhankelijke klas op de een of andere manier niet gevonden.

Laten we doorgaan met een eenvoudig voorbeeld:

public class ClassA{
    public static void main(String args[]){
         // Some gibberish code...
         String text = ClassB.getString();
         System.out.println("Text is: " + text);
    }
}
public class ClassB{
    public static String getString(){
        return "Testing some exception";
    }
}

Laten we nu aannemen dat de bovenstaande twee Java-broncode in een map wordt geplaatst, laten we zeggen “noclassdefinationfoundexceptiondemo”

Open nu een schaal (ervan uitgaande dat Java al correct is ingesteld)

  1. Ga naar map “NoclassDefinationFoundExceptionDemo”

  2. Compile Java Source-bestanden
    Javac Classb
    Javac Classa

  3. Beide bestanden worden met succes gecompileerd en klasbestanden gegenereerd in dezelfde map als classa.class en classb.class

  4. Nu, omdat we het klassenpad op de huidige werkdirecteur overschrijven, voeren we de volgende opdracht uit
    Java -CP. Classa
    En het werkte met succes en je ziet de uitvoer op het scherm

  5. Laten we nu zeggen dat u ClassB.class-bestand uit de onderhavige map hebt verwijderd.
    En nu voer je het commando opnieuw uit.
    Java -CP. Classa Nu begroet het u met noclassdeffoundexception. Zoals ClassB dat een afhankelijkheid is voor de les is niet gevonden in het klassenpad (d.w.z. de huidige werkdirectory).


8, Autoriteit 2%

Als uw project in een pakket is zoals com.blahcodeen uw klasse wordt Maingenoemd, kunnen de gecompileerde bestanden worden uitgevoerd in een directorystructuur zoals ./out/com/blahcode/Main.class. Dit geldt vooral voor Intellij Idee.

Wanneer u probeert uit te voeren vanaf een Shell of Cmd, moet u cdnodig hebben op die welke comals een submap bevat.

cd out
java -classpath . com.blahcode.Main

9

Ik heb vandaag met het probleem geconfronteerd. Ik heb een Android-project en na het inschakelen van multidexzou het project niet meer beginnen.

De reden was dat ik vergeten was om de specifieke MultImex-methode te bellen die moet worden toegevoegd aan de Application classen vóór al het andere.

MultiDex.install(this);

Volg deze tutorial om MultImex correct in te schakelen. https://developer.android.com/studio/build/multidex.html

U moet deze regels toevoegen aan uw toepassingsklasse

@Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     MultiDex.install(this);
  }

10

Nadat ik vele maanden op een netwerk van NetBeans heb gewerkt, kreeg ik plotseling het NoclassDeffoundror-bericht kort na het verkrijgen van een “lage geheugen” -alarm. Het doen van een schone rebuild hielp niet, maar het sluiten van netbeans en het heropenen van het project Er waren geen foutmeldingen.


11

Dit antwoord is specifiek voor een Java.lang.noclassdeffoundError gebeuren in een -service :

Mijn team heeft deze fout onlangs gezien na het upgraden van een RPM die een service heeft geleverd. De RPM en de software binnenin waren gebouwd met MAVEN, dus het leek erop dat we een compileertijdafhankelijkheid hadden die net niet in de RPM was opgenomen.

Tijdens het onderzoeken was de klasse die niet is gevonden in dezelfde module als verschillende van de klassen in het stapelspoor. Bovendien was dit geen module die pas onlangs aan de build was toegevoegd. Deze feiten gaf aan dat het misschien geen probleem met de afhankelijkheid van MAVE is.

De uiteindelijke oplossing: Start de service opnieuw!

Het lijkt erop dat de RPM-upgrade de bestandshendel van de service in het onderliggende JAR-bestand ongeldig is. De service zag vervolgens een klasse die niet in het geheugen was geladen, ernaar doorzocht onder de lijst van de handgrepen van JAR-bestand, en kon het niet vinden omdat het bestand aan de dossier kan worden geladen. Het opnieuw opstarten van de service dwong het om al zijn dossiergrepen opnieuw te laden, die het vervolgens toestond om die klasse te laden die niet in het geheugen was gevonden, direct na de RPM-upgrade.


12

Voor mijn project was wat het probleem opgelost was dat Chrome Browser en Chromedriver geen compatibellen waren. Ik had een heel oude versie van de bestuurder die de browser niet eens kon openen. Ik heb zojuist de nieuwste versie van zowel en probleem opgelost.

Hoe heb ik het probleem ontdekt? Omdat ik mijn project liep met behulp van de Selenium Native Firefox-stuurprogramma met een oude versie van Firefox die bij mijn aanvraag is inbegrepen. Ik realiseerde me toen dat het probleem incompatibiliteit was tussen de browser en de bestuurder.


Antwoord 13

Als u meer dan één module gebruikt, moet u

dexOptions {
    preDexLibraries = false
}

in uw buildbestand.


Antwoord 14

Ik had hetzelfde probleem met mijn Android-ontwikkeling met Android Studio. De geboden oplossingen zijn algemeen en hebben me niet geholpen (tenminste voor mij).

Na urenlang onderzoek heb ik de volgende oplossing gevonden en het kan helpen voor Android-ontwikkelaars die aan het ontwikkelen zijn met Android Studio.

Wijzig de instelling zoals hieronder:

VoorkeurenBuild, Execution, DeploymentInstant Run→ *schakel de eerste optie uit.

Met deze wijziging ben ik aan de slag.


Antwoord 15

Mijn twee cent in deze ketting:

Zorg ervoor dat het classpathvolledigepaden bevat (/home/user/lib/some_lib.jarin plaats van ~/lib/some_lib.jar) anders kunt u nog steeds te maken krijgen met een NoClassDefFoundError-fout.


Antwoord 16

Gebruik geen testklassen buiten de module

Ik heb geen oplossing, gewoon een andere smaak van het geval “aanwezig bij compilatie, afwezig tijdens runtime”.

Ik probeerde een erg handige methode te gebruiken van een JUnit-testklasse van een andere testklasse die zich in een andere module bevindt. Dat is een nee-nee, aangezien testcode geen deel uitmaakt van de verpakte pot, maar ik wist het niet omdat het zichtbaar lijkt voor de gebruikersklasse vanuit Eclipse.

Mijn oplossing was om de methode in een bestaande utilities-klasse te plaatsen die deel uitmaakt van de productiecode.


Antwoord 17

Ik krijg NoClassFoundError wanneer klassen die door de runtime-klasselader zijn geladen, geen toegang hebben tot klassen die al door de Java-rootlader zijn geladen. Omdat de verschillende klassenladers zich in verschillende beveiligingsdomeinen bevinden (volgens Java), staat de JVM niet toe dat klassen die al door de rootloader zijn geladen, worden omgezet in de adresruimte van de runtime-lader.

Voer uw programma uit met ‘java -javaagent:tracer.jar [UW ‘java’-ARGUMENTEN]’

Het produceert uitvoer met de geladen klasse en de laderomgeving die de klasse heeft geladen. Het is erg handig om te achterhalen 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 18

Het is mij overkomen in Android Studio.

De oplossing die voor mij werkte: herstart Android Studio.


Antwoord 19

Controleer dat als je een statische handler in je klas hebt. Als dit het geval is, wees dan voorzichtig, want de statische handler kan alleen worden gestart in een thread met een looper, de crash kan op deze manier worden geactiveerd:

  1. Maak eerst de instantie van klasse in een eenvoudige thread en vang de crash op.

  2. Bel vervolgens de veldmethode Class aan in de hoofdthread, je krijgt de NoClassDefFoundError.

Hier is de testcode:

public class MyClass{
       private static  Handler mHandler = new Handler();
       public static int num = 0;
}

Voeg in uw onCreate-methode van de hoofdactiviteit het testcodegedeelte toe:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //test code start
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                MyClass myClass = new MyClass();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }).start();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    MyClass.num = 3;
    // end of test code
}

Er is een eenvoudige manier om dit op te lossen met behulp van een handlerThread naar de init-handler:

private static Handler mHandler;
private static HandlerThread handlerThread = new HandlerThread("newthread");
static {
    handlerThread.start();
    mHandler = new Handler(handlerThread.getLooper(), mHandlerCB);
}

Antwoord 20

Eén bron van fouten voor deze uitzondering kan het gevolg zijn van inconsistente definities voor Proguardbijv een ontbrekende

-libraryJars “path.to.a.missing.jar.library”.

Dit verklaart waarom het compileren en uitvoeren prima werkt, aangezien het JAR-bestand aanwezig is, terwijl opschonen en bouwen mislukt. Vergeet niet om de nieuw toegevoegde JAR-bibliotheken te definiëren in de ProGuard-configuratie!

Merk op dat foutmeldingen van ProGuard echt niet aan de norm voldoen, omdat ze gemakkelijk kunnen worden verward met vergelijkbare Ant berichten die binnenkomen wanneer het JAR-bestand er helemaal niet is. Alleen helemaal onderaan zal er een kleine hint zijn dat ProGuard in de problemen zit. Daarom is het heel logisch om te beginnen met zoeken naar traditionele classpath-fouten, enz., maar dit zal tevergeefs zijn.

Het is duidelijk dat de NoClassDefFound-uitzondering de resultaten zijn bij het uitvoeren, bijvoorbeeld het resulterende uitvoerbare JAR-bestand dat is gebouwd en gebaseerd op een gebrek aan ProGuard-consistentie. Sommigen noemen het ProGuard “Hell”.


Antwoord 21

Ik gebruik de FileSync-plug-in voor Eclipse, dus ik kan live debuggen op Tomcat . Ik ontving NoClassFoundError, omdat ik een synchronisatie-item had toegevoegd voor de bin-directory in de Eclipse-werkruimte => classesin de metadatavoor Tomcat, maar ik had niet ook een mapsynchronisatie toegevoegd voor de extlib-directory in Eclipse =>

C:\Users\Stuart\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\webapps\myApp\WEB-INF\lib


Antwoord 22

Als u recentelijk als volgt multidex-ondersteuning in Android Studio heeft toegevoegd:

// To support MultiDex
implementation 'com.android.support:multidex:1.0.1'

Dus uw oplossing is gewoon een uitbreiding van MultiDexApplication in plaats van Application:

public class MyApp extends MultiDexApplication {

Antwoord 23

In mijn omgeving kwam ik dit probleem tegen tijdens een unit-test. Na het toevoegen van één bibliotheekafhankelijkheid aan *.pom, is dat opgelost.

Voorbeeld:

Foutbericht:

java.lang.NoClassDefFoundError: com/abc/def/foo/xyz/Iottt

POM-inhoud:

<dependency>
    <groupId>com.abc.def</groupId>
    <artifactId>foo</artifactId>
    <scope>test</scope>
</dependency>

Antwoord 24

Ik kreeg deze fout na een Git branch verandering. Voor het specifieke geval van Eclipse waren er regels in de .settingsdirectory voor het org.eclipse.wst.common.common.component bestand. Zoals je hieronder kunt zien.

Het zou helpen om de projectafhankelijkheden te herstellen met Maven-installatie.


Antwoord 25

Als je gradlewgebruikt, ga dan naar ./gradle/wrapper/gradle-wrapper.propertiesen verander distributionUrlnaar de juiste versie van Gradle.

Als je JDK14 gebruikt, probeer dan:

distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip

Antwoord 26

Voor Meteorof Cordova-gebruikers,

Dit kan worden veroorzaakt door de Java-versie die u gebruikt. Voor Meteor en Cordova, blijf voorlopig bij versie 8.

  1. Controleer de beschikbare Java-versies /usr/libexec/java_home -V en zoek naar de padnaam voor Java-versie 8

  2. Stel het pad in voor Java versie 8
    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home

  3. Controleer of het klaar is
    echo $JAVA_HOME

Ga door en ga door met coderen.


Antwoord 27

Deze fout betekent dat je enkele van de afhankelijkheden niet hebt toegevoegd.


28

de Java 11 + Eclipse-oplossing:

Deze oplossing is voor u als u module-info.javain uw Eclipse-project niet gebruikt, en u de potbestanden handmatig toegevoegd in plaats van het gebruik van Maven / gradle .

  1. Rechts klik op project → Build pad Configureer pad Bibliotheken Tab
  2. Verwijder het problematische JAR-bestand van de MODULEPATH
  3. Voeg het JAR-bestand toe aan het klassenpad

Meer informatie is in
in Eclipse, wat is het verschil tussen ModulePath en ClassPath? .

Other episodes