it-swarm.com.de

Wie löse ich Java.lang.NoClassDefFoundError?

Ich habe beide Beispiele in Oracle Java Tutorials probiert. Beide kompilieren gut, aber zur Laufzeit kommen beide zu diesem Fehler:

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

Ich denke, ich habe die Main.Java-Datei im falschen Ordner. Hier ist die Verzeichnishierarchie:

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

Und hier ist 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);
    }
}

Was mache ich hier falsch?

UPDATE

Nachdem ich die Main-Klasse im graphics-Paket abgelegt hatte (ich habe package graphics; hinzugefügt), den Klassenpfad auf "_test" (Ordner mit Grafiken) gesetzt, ihn kompiliert und mit Java graphics.Main (von der Befehlszeile aus) ausgeführt, funktionierte er.

Wirklich spät UPDATE # 2

Ich habe Eclipse nicht verwendet (nur Notepad ++ und das JDK) und das obige Update hat mein Problem gelöst. Es scheint jedoch, dass viele dieser Antworten für Eclipse und IntelliJ gelten, aber sie haben ähnliche Konzepte.

178
Jonathan Lam

Nachdem Sie Ihren Code kompiliert haben, erhalten Sie .class-Dateien für jede Klasse in Ihrem Programm. Diese Binärdateien sind der Bytecode, den Java zur Ausführung Ihres Programms interpretiert. Die Variable NoClassDefFoundError gibt an, dass der Klassenlader (in diesem Fall Java.net.URLClassLoader), der für das dynamische Laden von Klassen verantwortlich ist, die .class-Datei für die Klasse, die Sie verwenden möchten, nicht finden kann. 

Ihr Code würde nicht kompiliert, wenn die erforderlichen Klassen nicht vorhanden wären (es sei denn, Klassen werden mit Reflektion geladen). Daher bedeutet diese Ausnahme normalerweise, dass Ihr Klassenpfad die erforderlichen Klassen nicht enthält. Denken Sie daran, dass der Klassenlader (insbesondere Java.net.URLClassLoader) in jedem Eintrag in Ihrem Klassenpfad nach Klassen im Paket a.b.c im Ordner a/b/c/sucht. NoClassDefFoundError kann auch anzeigen, dass Sie eine transitive Abhängigkeit einer .jar-Datei vermissen, für die Sie kompiliert haben und die Sie verwenden möchten.

Wenn Sie beispielsweise eine Klasse com.example.Foo hätten, hätten Sie nach dem Kompilieren eine Klassendatei Foo.class. Angenommen, Ihr Arbeitsverzeichnis lautet beispielsweise .../project/. Diese Klassendatei muss in .../project/com/example platziert werden, und Sie würden Ihren Klassenpfad auf .../project/ setzen.

Randbemerkung: Ich würde empfehlen, die erstaunlichen Tools für Java und JVM-Sprachen zu nutzen. Moderne IDEs wie Eclipse und IDEA und Build-Management-Tools wie Maven oder Gradle helfen Ihnen dabei, sich nicht um Klassenpfade (so sehr) zu kümmern und sich auf den Code zu konzentrieren! Das heißt dieser Link erklärt, wie der Klassenpfad gesetzt wird, wenn Sie ihn in der Befehlszeile ausführen.

186
Samuel

Ich möchte die Perspektive anderer auf NoClassDefFoundError korrigieren.

NoClassDefFoundError kann aus verschiedenen Gründen auftreten, z

  1. ClassNotFoundException - .class wurde für diese referenzierte Klasse nicht gefunden, unabhängig davon, ob sie zur Kompilierzeit verfügbar ist oder nicht (d. H. Basis-/Kindklasse).
  2. Klassendatei wurde gefunden, aber beim Initialisieren statischer Variablen wurde eine Ausnahme ausgelöst
  3. Klassendatei befindet, Ausnahme beim Initialisieren statischer Blöcke ausgelöst 

In der ursprünglichen Frage war dies der erste Fall, der korrigiert werden kann, indem CLASSPATH auf die JAR-Datei der referenzierten Klassen oder auf dessen Paketordner gesetzt wird. 

Was bedeutet es, wenn Sie "in Kompilierzeit verfügbar" sagen? 

  • Die referenzierte Klasse wird im Code verwendet. 
    ZB: Zwei Klassen, A Und B (erweitert A). Wenn B direkt im Code referenziert wird, steht es zur Kompilierzeit zur Verfügung, d. H. A a = new B ();

Was bedeutet es, wenn Sie sagen, "nicht zur Kompilierzeit verfügbar"?

  • Die Klasse der Kompilierungszeit und die Laufzeitklasse sind unterschiedlich, d. H. Die Basisklasse wird beispielsweise unter Verwendung des Klassennamens der untergeordneten Klasse geladen. Zum Beispiel Class.forName ("Klassenname")
    ZB: Zwei Klassen A und B (erweitert A). Code hat
    A a = Class.forName ("B"). NewInstance ();
111
p1nkrock

NoClassDefFoundError bedeutet, dass die Klasse im Klassenpfad bei Compile time vorhanden ist, aber nicht im Klassenpfad bei Runtime vorhanden ist.

Wenn Sie Eclipse verwenden, stellen Sie sicher, dass Sie die Einträge shapes, linepoints und spaceobjects in der .classpath-Datei haben.

12

wenn Sie beim Kompilieren und Ausführen einen dieser Fehler erhalten haben:

* NoClassDefFoundError

* Error: Could not find or load main class hello

* Exception in thread "main" Java.lang.NoClassDefFoundError:javaTest/test/hello 
(wrong name: 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)

--------------------------LÖSUNG------------- ----------

Das Problem liegt meistens in der Paketorganisation. Sie sollten Ihre Klassen entsprechend den Paketklassifizierungen in Ihrem Quellcode in Ordnern ordnen.

On Compiling process use this command:

javac -d . [FileName.Java]

To Run the class please use this command:

Java [Package].[ClassName]
10
sami
Java.lang.NoClassDefFoundError

zeigt an, dass etwas zur compiletime gefunden wurde, aber nicht zur Laufzeit Vielleicht müssen Sie es nur dem Klassenpfad hinzufügen.

8
sschrass

Keine Klassendefinitionsausnahme tritt auf, wenn die beabsichtigte Klasse nicht im Klassenpfad gefunden wird. Zur Kompilierungszeit Klasse: Die Klasse wurde vom Java Compiler generiert, aber irgendwie wird die abhängige Klasse zur Laufzeit nicht gefunden.

Lassen Sie uns ein einfaches Beispiel durchgehen:

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

Nehmen wir nun an, dass die beiden oben genannten Java Quellcode in einem Ordner abgelegt sind, sagen wir "NoClassDefinationFoundExceptionDemo".

Öffnen Sie nun eine Shell (Angenommen, Java wird bereits korrekt eingerichtet)

  1. Gehe zum Ordner "NoClassDefinationFoundExceptionDemo"
  2. Kompiliere Java Quelldateien javac ClassB javac ClassA
  3. Beide Dateien werden erfolgreich kompiliert und Klassendateien im selben Ordner wie ClassA.class und ClassB.class generiert
  4. Da wir nun ClassPath auf das aktuelle Arbeitsverzeichnis überschreiben, führen wir den folgenden Befehl Java -cp aus. ClassA und Es hat erfolgreich funktioniert und Sie sehen die Ausgabe auf dem Bildschirm
  5. Nehmen wir an, Sie haben die Datei ClassB.class aus dem Present Directory entfernt. und jetzt führen Sie den Befehl erneut aus. Java -cp. ClassA Jetzt werden Sie mit NoClassDefFoundException begrüßt. als ClassB, das eine Abhängigkeit für ClassA darstellt, wird nicht im Klassenpfad (d. h. aktuelles Arbeitsverzeichnis) gefunden.
6
bharatj

Wenn sich Ihr Projekt in einem Paket wie com.blahcode befindet und Ihre Klasse Main heißt, werden die kompilierten Dateien in einer Verzeichnisstruktur wie ./out/com/blahcode/Main.class ausgegeben. Dies gilt insbesondere für IntelliJ IDEA.

Wenn Sie versuchen, von einer Shell oder einem Cmd aus zu laufen, müssen Sie cd auf das Verzeichnis setzen, das com als Unterverzeichnis enthält.

cd out
Java -classpath . com.blahcode.Main
2
Hypershadsy

Nachdem ich viele Monate an einem NetBeans-Projekt gearbeitet hatte, erhielt ich plötzlich die Meldung NoClassDefFoundError, kurz nachdem ich die Warnung "Wenig Speicher" erhalten hatte. Es hat nicht geholfen, einen Clean-Rebuild durchzuführen, aber Netbeans wurde geschlossen und das Projekt wieder geöffnet. Es gab keine Fehlerberichte.

1
Ed S

NoClassDefFoundError in Java:

Definition: 

NoClassDefFoundError wird angezeigt, wenn eine Klasse während der Kompilierungszeit vorhanden war, aber zur Laufzeit nicht im Java-Klassenpfad verfügbar ist. Normalerweise sehen Sie unten im Protokoll, wenn Sie NoClassDefFoundError erhalten: Ausnahme im Thread "main" Java.lang.NoClassDefFoundError

Mögliche Ursachen:

  1. Die Klasse ist in Java Classpath nicht verfügbar.

  2. Möglicherweise führen Sie Ihr Programm mit dem Befehl jar aus, und die Klasse wurde nicht im ClassPath-Attribut der Manifestdatei definiert.

  3. Jedes Startskript überschreibt die Umgebungsvariable Classpath.

  4. Da NoClassDefFoundError eine Unterklasse von Java.lang.LinkageError ist, kann es auch kommen, wenn eine davon abhängige Bibliothek wie die native Bibliothek nicht verfügbar ist.

  5. Suchen Sie in Ihrer Protokolldatei nach Java.lang.ExceptionInInitializerError. NoClassDefFoundError aufgrund eines Fehlers der statischen Initialisierung ist recht häufig.

  6. Wenn Sie in einer J2EE-Umgebung arbeiten, kann die Sichtbarkeit von Class unter mehreren Classloader auch Java.lang.NoClassDefFoundError verursachen. Ausführliche Informationen finden Sie in den Beispielen und im Szenarioabschnitt.

Mögliche Lösungen:

  1. Stellen Sie sicher, dass alle erforderlichen Java-Klassen im Klassenpfad der Anwendung enthalten sind. Der häufigste Fehler besteht darin, nicht alle erforderlichen Klassen einzuschließen, bevor Sie mit der Ausführung einer Java-Anwendung beginnen, die Abhängigkeiten zu einigen externen Bibliotheken aufweist.

  2. Der Klassenpfad der Anwendung ist korrekt, aber die Umgebungsvariable Classpath wird vor der Ausführung der Anwendung überschrieben.

  3. Stellen Sie sicher, dass der oben genannte ExceptionInInitializerError nicht im Stack-Trace Ihrer Anwendung angezeigt wird.

Ressourcen: 

3 Möglichkeiten, Java.lang.NoClassDefFoundError in Java J2EE zu lösen

Java.lang.NoClassDefFoundError - So lösen Sie keinen Klassendefinitionsfehler

1
Virtual

Ich bin heute mit dem Problem konfrontiert. Ich habe ein Android-Projekt und nach der Aktivierung von multidex würde das Projekt nicht mehr gestartet.

Der Grund war, dass ich vergessen hatte, die spezifische Multidex-Methode aufzurufen, die dem Application class hinzugefügt und vor allem anderen aufgerufen werden sollte.

 MultiDex.install(this);

Befolgen Sie dieses Tutorial, um Multidex korrekt zu aktivieren. https://developer.Android.com/studio/build/multidex.html

Sie sollten diese Zeilen Ihrer Application-Klasse hinzufügen

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

Diese Antwort ist spezifisch für ein Java.lang.NoClassDefFoundError, das in einem service auftritt:

Mein Team hat diesen Fehler kürzlich nach dem Upgrade eines UpM festgestellt, das einen Dienst bereitgestellt hat. Das RPM und die darin enthaltene Software wurden mit Maven erstellt. Es schien also, dass wir eine Abhängigkeit von der Kompilierzeit hatten, die gerade nicht in das RPM aufgenommen worden war. 

Bei der Untersuchung befand sich jedoch die nicht gefundene Klasse im selben Modul wie mehrere Klassen im Stack-Trace. Außerdem war dies kein Modul, das erst kürzlich zum Build hinzugefügt wurde. Diese Fakten deuteten darauf hin, dass es sich nicht um ein Maven-Abhängigkeitsproblem handelt.

Die mögliche Lösung: Starten Sie den Service neu!

Es hat den Anschein, dass das RPM-Upgrade den Datei-Handle des Service für die zugrunde liegende JAR-Datei ungültig gemacht hat. Der Service sah dann eine Klasse, die noch nicht in den Speicher geladen worden war, suchte in der Liste der JAR-Datei-Handles danach und konnte sie nicht finden, da das Datei-Handle, aus dem die Klasse geladen werden konnte, ungültig wurde. Beim Neustart des Dienstes musste er alle Dateizugriffsnummern neu laden, sodass er die Klasse laden konnte, die nach der UpM-Aktualisierung nicht im Speicher gefunden wurde.

Hoffe, dass dieser spezielle Fall jemandem hilft.

1
John Chesshir

Meine zwei Cents in dieser Kette:

Stellen Sie sicher, dass die Pfade classpath full (/home/user/lib/some_lib.jar anstelle von ~/lib/some_lib.jar) enthalten, andernfalls können Sie noch mit dem NoClassDefFoundError-Fehler konfrontiert werden.

0
khkarens

Ich hatte das gleiche Problem mit meiner Android-Entwicklung unter Verwendung von Android Studio . Die bereitgestellten Lösungen sind allgemein und haben mir nicht geholfen (zumindest für mich) ..__ Entwicklung wird mit Android Studio durchgeführt. Ändern Sie die Einstellung wie folgt. Ändern Sie die erste Option, und klicken Sie auf Voreinstellungen.

Mit dieser Änderung bin ich fertig. Ich hoffe das hilft meinen Entwicklern.

0
mask

Ich benutze das FileSync-Plugin für Eclipse , damit ich live auf Tomcat debuggen kann & NoClassFoundError erhalten habe, da ich im Eclipse-Arbeitsbereich => classes in der bin für Tomcat einen Sync-Eintrag für das metadata-Verzeichnis hinzugefügt hatte, aber noch keinen Ordnersynchronisierung für das Verzeichnis extlib in Eclipse =>

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

0
Stuart Cardall

wenn Sie kürzlich Multidex-Unterstützung in Android Studio hinzugefügt haben, wie folgt:

// To Support MultiDex
implementation 'com.Android.support:multidex:1.0.1'

daher ist Ihre Lösung einfach von MultiDexApplication statt Application erweitert

public class MyApp extends MultiDexApplication {
0
do01

Es ist mir in Android Studio passiert.

Die Lösung, die für mich funktioniert hat: Starten Sie einfach das Studio neu.

0
yanish

Überprüfen Sie dies, wenn Sie einen statischen Handler in Ihrer Klasse haben. Wenn ja, seien Sie bitte vorsichtig, da statische Handler nur in Thread mit einem Looper initiiert werden könnten und der Absturz auf diese Weise ausgelöst werden könnte:

1.Erstellen Sie zunächst die Instanz der Klasse in einem einfachen Thread und fangen Sie den Absturz ab.

2. Wenn Sie dann die Feldmethode von Class im Haupt-Thread aufrufen, erhalten Sie NoClassDefFoundError.

hier ist der Testcode:

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

fügen Sie in Ihrer onCrete-Methode der Hauptaktivität den Testcodeteil hinzu:

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

es gibt eine einfache Möglichkeit, das Problem mithilfe eines handlerThread-zu-init-Handlers zu beheben: 

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

Für mein Projekt wurde das Problem gelöst, dass Chrome Browser und Chromedriver nicht kompatibel waren. Ich hatte eine sehr alte Version des Treibers, die den Browser nicht einmal öffnen konnte. Ich habe gerade die neueste Version von beiden heruntergeladen und das Problem gelöst. Wie habe ich das Problem entdeckt? Da ich mein Projekt mit dem nativen Firefox-Treiber von Selen mit einer alten Version von FF ausgeführt habe, die in meiner Anwendung enthalten war, erkannte ich, dass das Problem die Inkompatibilität zwischen Browser und Treiber war.

Ich hoffe, dass dies jedem helfen kann, der ein ähnliches Problem wie das meine hat und die gleiche Fehlermeldung generiert hat.

0
Kyon Perez

Wenn Sie mehr als ein Modul verwenden, sollten Sie dies tun 

dexOptions {
    preDexLibraries = false
}

in Ihrer Build-Datei.

0
Matin Petrulak

Ich entwickle eine auf Eclipse basierende Anwendung, die auch als RCP (Rich Client Platform) ..__ bezeichnet wird. Nach dem Refactoring ist das Problem aufgetreten (Verschieben einer Klasse von einem PlugIn in ein neues).

Das Bereinigen des Projekts und das Update von Maven haben nicht geholfen.

Das Problem wurde durch den Bundle-Activator verursacht, der nicht automatisch aktualisiert wurde. Das manuelle Update des Bundle-Activators unter MANIFEST.MF im neuen PlugIn hat mein Problem behoben.

0

Ich bekomme NoClassFoundError, wenn Klassen, die vom Laufzeitklassenlader geladen werden, nicht auf Klassen zugreifen können, die bereits vom Java-Rootloader geladen wurden. Da sich die verschiedenen Klassenladeprogramme in verschiedenen Sicherheitsdomänen befinden (laut Java), erlaubt jvm nicht, dass bereits vom Rootloader geladene Klassen im Adressraum des Laufzeitladeprogramms aufgelöst werden.

Führen Sie Ihr Programm mit 'Java-javaagent: tracer.jar [YOUR Java ARGS]' aus.

Es erzeugt eine Ausgabe, die die geladene Klasse und das Ladeprogramm env zeigt, das die Klasse geladen hat. Es ist sehr hilfreich zu verfolgen, warum eine Klasse nicht aufgelöst werden kann.

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

Eine Fehlerquelle für diese Ausnahme könnte von inkonsistenten Definitionen für Proguard herrühren, z. ein fehlender

-libraryJars "path.to.a.missing.jar.library". 

Dies erklärt, warum das Kompilieren und Laufen gut funktioniert, da die Dose vorhanden ist und Clean & Build fehlschlägt. Denken Sie daran, neu hinzugefügte Jar-Bibliotheken im Proguard-Setup zu definieren!

Beachten Sie, dass die Fehlermeldungen von Proguard wirklich nicht dem Standard entsprechen, da sie leicht mit ähnlichen Ant-Meldungen verwechselt werden können, wenn das Glas überhaupt nicht da ist. Nur ganz unten wird ein kleiner Hauch Proguard in Schwierigkeiten sein. Daher ist es logisch, nach traditionellen Klassenpfadfehlern usw. zu suchen. Dies ist jedoch vergeblich.

Offensichtlich sind die Ergebnisse der NoClassDefFound-Ausnahme die Ergebnisse, wenn z. Das resultierende ausführbare Glas wurde erstellt und basiert auf einer mangelnden Proguard-Konsistenz. Manche nennen es Vormund "Hölle" 

0
carl

Es passiert viel mit meinen genymotion-Geräten. Stellen Sie sicher, dass auf Ihrem Laufwerk, auf dem Genymotion installiert ist, ausreichend Speicherplatz vorhanden ist.

0
totteire