Domanda

Qual è la differenza tra NoClassDefFoundError E ClassNotFoundException?

Cosa li spinge a essere lanciati?Come possono essere risolti?

Incontro spesso questi oggetti lanciabili quando modifico il codice esistente per includere nuovi file jar.Li ho colpiti sia sul lato client che sul lato server per un'app Java distribuita tramite webstart.

Possibili ragioni che ho riscontrato:

  1. pacchetti non compresi nel build.xml per il lato client del codice
  2. percorso classe runtime mancante per i nuovi jar che stiamo utilizzando
  3. la versione è in conflitto con il jar precedente

Quando li incontro oggi, adotto un approccio trail-and-error per far funzionare le cose.Ho bisogno di più chiarezza e comprensione.

È stato utile?

Soluzione

La differenza dai Java API specifiche è la seguente.

ClassNotFoundException :

  

generata quando un'applicazione tenta di   carico in classe attraverso la stringa   nome utilizzando:

     
      
  • Il metodo forName in classe Class.
  •   
  • Il metodo findSystemClass in classe ClassLoader.
  •   
  • Il metodo loadClass in classe ClassLoader.
  •   
     

, ma nessuna definizione per la classe con   il nome specificato è stata trovata.

NoClassDefFoundError :

  

generata se la Java Virtual Machine o   un'istanza ClassLoader tenta di caricare   nella definizione di una classe (come parte   di una normale chiamata di metodo o come parte di   creazione di una nuova istanza utilizzando il nuovo   espressione) e definizione della   classe potrebbe essere trovato.

     

La definizione della classe ricercati   esisteva quando l'attualmente in esecuzione   di classe è stato compilato, ma la definizione   non può più essere trovato.

Quindi, sembra che il NoClassDefFoundError si verifica quando la sorgente è stato compilato con successo, ma in fase di esecuzione, i file class richiesti non sono stati trovati. Questo può essere qualcosa che può accadere nella distribuzione o produzione di file JAR, in cui non sono stati inclusi tutti i file necessari class.

Per quanto riguarda ClassNotFoundException, sembra che essa può derivare dal tentativo di effettuare chiamate riflettenti alle classi in fase di runtime, ma non esiste classi il programma sta tentando di chiamare.

La differenza tra i due è che uno è un Error e l'altro è un Exception. Con NoClassDefFoundError è un Error e nasce dalla macchina avere problemi Java Virtual trovare una classe si aspettava di trovare. Un programma che ci si aspettava di lavorare a tempo di compilazione non può essere eseguito a causa di class non i file di essere trovati, o non è lo stesso che è stato prodotto o incontrato a tempo di compilazione. Questo è un errore piuttosto critico, in quanto il programma non può essere avviato dalla JVM.

D'altra parte, il ClassNotFoundException è un Exception, quindi è in qualche modo previsto, ed è qualcosa che è recuperabile. Utilizzando riflessione è può essere soggetto a errori (in quanto v'è alcune aspettative che le cose potrebbero non andare come previsto. Non c'è alcun controllo in fase di compilazione per vedere che esistono tutte le classi richieste, in modo che qualsiasi problemi a trovare le classi desiderati appariranno in fase di esecuzione .

Altri suggerimenti

Un ClassNotFoundException viene generata quando la classe riportata non viene trovato dal ClassLoader. Ciò significa in genere che la classe non è presente nel CLASSPATH. Potrebbe anche significare che la classe in questione sta cercando di essere caricato da un'altra classe che è stato caricato in un programma di caricamento classe genitore e quindi la classe dalla classloader bambino non è visibile. Questo a volte è il caso quando si lavora in ambienti più complessi come un application server (WebSphere è tristemente nota per tali questioni classloader).

Spesso le persone tendono a confondere con java.lang.NoClassDefFoundError java.lang.ClassNotFoundException però c'è una distinzione importante. Per esempio un'eccezione (un errore davvero dato java.lang.NoClassDefFoundError è una sottoclasse di java.lang.Error) come

java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory

non significa che la classe ActiveMQConnectionFactory non è nel classpath. Infatti la sua piuttosto il contrario. Significa che l'ActiveMQConnectionFactory di classe è stato trovato dal ClassLoader però quando si cerca di caricare la classe, è imbattuto in un errore di lettura della definizione di classe. Questo accade tipicamente quando la classe in questione ha blocchi statici o membri che utilizzano una classe che non ha trovato dal ClassLoader. Quindi, per trovare il colpevole, visualizzare l'origine della classe in questione (ActiveMQConnectionFactory in questo caso) e cercare il codice usando blocchi statici o membri statici. Se non si ha accesso alla sorgente, poi semplicemente decompilare usando JAD.

Esaminando il codice, diciamo che si trova una riga di codice come qui di seguito, assicurarsi che la SomeClass classe nel classpath.

private static SomeClass foo = new SomeClass();

Suggerimento: per scoprire quale vaso una classe appartiene, è possibile utilizzare il sito web jarFinder. Ciò consente di specificare un nome di classe utilizzando i caratteri jolly e ricerca la classe nel suo database di vasi. jarhoo permette di fare la stessa cosa, ma la sua non è più libero di utilizzare.

Se si desidera individuare il vaso, che una classe appartiene ad un percorso locale, è possibile utilizzare un programma di utilità come jarscan ( http://www.inetfeedback.com/jarscan/ ). Basta specificare la classe che si desidera individuare e il percorso della directory principale in cui ti piacerebbe per avviare la ricerca per la classe in vasi e file zip.

NoClassDefFoundError è un errore di legame in fondo. Essa si verifica quando si cerca di un'istanza di un oggetto (staticamente con "nuovo") e non è trovato quando era durante la compilazione.

ClassNotFoundException è più generale ed è un'eccezione di runtime quando si tenta di utilizzare una classe che non esiste. Per esempio, si dispone di un parametro in una funzione accetta un'interfaccia e qualcuno passa in una classe che implementa l'interfaccia, ma non si ha accesso alla classe. Inoltre riguarda caso di carico classe dinamica, come l'utilizzo loadClass() o Class.forName().

Si verifica un NoClassDefFoundError (NCDFE) quando il codice esegue "new Y()" e non riesce a trovare la classe Y.

Potrebbe semplicemente essere che Y manchi dal tuo caricatore di classi come suggeriscono gli altri commenti, ma potrebbe essere che la classe Y non sia firmata o abbia una firma non valida, o che Y sia caricato da un diverso caricatore di classi non visibile al tuo codice , o anche che Y dipenda da Z che non è stato possibile caricare per nessuno dei motivi sopra indicati.

Se ciò accade, la JVM ricorderà il risultato del caricamento di X (NCDFE) e lancerà semplicemente un nuovo NCDFE ogni volta che chiedi Y senza dirti perché:

class a {
  static class b {}
  public static void main(String args[]) {
    System.out.println("First attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
    System.out.println("\nSecond attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
  }
}

salvalo come a.java da qualche parte

Il codice tenta semplicemente di istanziare una nuova classe "b" due volte, a parte questo, non presenta bug e non fa nulla.

Compila il codice con javac a.java, Quindi esegui invocando java -cp . a -- dovrebbe stampare solo due righe di testo e dovrebbe funzionare correttamente senza errori.

Quindi elimina il file "a$b.class" (o riempilo di spazzatura, o copiaci sopra a.class) per simulare la classe mancante o danneggiata.Ecco cosa succede:

First attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:5)
Caused by: java.lang.ClassNotFoundException: a$b
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 1 more

Second attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:7)

La prima invocazione risulta in una ClassNotFoundException (lanciata dal caricatore di classi quando non riesce a trovare la classe), che deve essere racchiusa in un NoClassDefFoundError non controllato, poiché il codice in questione (new b()) dovrebbe funzionare.

Ovviamente anche il secondo tentativo fallirà, ma come puoi vedere l'eccezione racchiusa non esiste più, perché ClassLoader sembra ricordare i caricatori di classi falliti.Vedi solo l'NCDFE senza alcuna idea di cosa sia realmente accaduto.

Pertanto, se mai vedi un NCDFE senza causa principale, devi vedere se riesci a risalire alla prima volta in cui la classe è stata caricata per trovare la causa dell'errore.

http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :

ClassNotFoundException : si verifica quando class loader non riusciva a trovare la classe richiesta nel percorso di classe. Quindi, in sostanza si dovrebbe verificare il percorso della classe e aggiungere la classe nel classpath.

NoClassDefFoundError : questo è più difficile da eseguire il debug e trovare la ragione. Questo viene generata quando al momento della compilazione le classi richieste sono presenti, ma in fase di esecuzione le classi vengono modificati o rimossi o inizializza statici della classe ha gettato eccezioni. Significa classe che è sempre caricato è presente nel percorso di classe, ma una delle classi che sono richiesti da questa classe sono rimosso o non caricava dal compilatore. Così si dovrebbe vedere le classi che dipendono da questa classe.

Esempio :

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

Ora, dopo la compilazione di entrambe le classi, se si elimina il file ed eseguire Test1.class classe Test, si getterà

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    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)
    ... 1 more

ClassNotFoundException:. Generata quando un'applicazione tenta di caricare in una classe attraverso il suo nome, ma nessuna definizione per la classe con il nome specificato è stato trovato

NoClassDefFoundError:. Gettato se la Java Virtual Machine tenta di caricare nella definizione di una classe e di definizione della classe è stato trovato

  

Qual è la ragione per ottenere ciascuno di essi e qualsiasi processo di pensiero su come affrontare tali errori?

Sono strettamente correlati. Un ClassNotFoundException viene generata quando Java è andato alla ricerca di una particolare classe per nome e non poteva successo caricarlo. Un NoClassDefFoundError viene generata quando Java è andato alla ricerca di una classe che è stato legato in qualche codice esistente, ma non riusciva a trovare per un motivo o per l'altro (ad esempio, classpath sbagliato, la versione sbagliata di Java, la versione sbagliata di una biblioteca) ed è a fondo fatale in quanto indica che qualcosa è andato storto.

Se hai un fondo C, un CNFE è come un fallimento per dlopen() / dlsym() ed un NCDFE è un problema con il linker; nel secondo caso, i file di classe in questione non dovrebbero mai sono stati effettivamente compilato nella configurazione si sta cercando di usarli.

Esempio # 1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

Se com/example/Class1 non esiste in nessuno dei percorsi di classe, poi si getta ClassNotFoundException.

Esempio # 2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

Se com/example/Class2 esisteva durante la compilazione B, ma non trovato durante l'esecuzione, poi si getta NoClassDefFoundError.

Entrambi gestiscono le eccezioni di tempo.

ClassNotFoundException generata quando c'è tentare di caricare la classe facendo riferimento a esso tramite una stringa. Ad esempio il parametro al Class.forName () è una stringa, e questo aumenta il potenziale di nomi binari non validi di essere passati al programma di caricamento classe.

Il ClassNotFoundException viene generata quando viene rilevato un nome binario potenzialmente non validi; per esempio, se il nome della classe ha il carattere '/', si sono tenuti a ottenere un ClassNotFoundException. E 'anche generata quando la classe direttamente riferimento non è disponibile nel classpath.

D'altra parte, NoClassDefFoundError è gettato

  • quando la rappresentazione fisica reale della classe - il file .class non è disponibile,
  • o classe state caricate già in un classloader diversa (solitamente un classloader genitore avrebbe caricato la classe e quindi la classe non può essere caricata),
  • o se è stata trovata una definizione di classe non compatibile - il nome del file di classe non corrisponde al nome richiesto,
  • o (soprattutto) se una classe dipendente non può essere individuato e caricato. In questo caso, la classe direttamente riferimento sarebbe stato localizzato e caricato, ma la classe dipendente non è disponibile o non può essere caricato. Questo è uno scenario in cui la classe direttamente riferimento può essere caricato tramite un Class.forName o metodi equivalenti. Questo indica un guasto nel collegamento.

In breve, un NoClassDefFoundError è solitamente gettato su nuovi () dichiarazioni o invocazioni di metodi che caricano una classe precedentemente assente (in opposizione al carico basato sulle stringhe di classi per ClassNotFoundException), quando il classloader non riesce a trovare o caricare la definizione di classe (s).

Alla fine, si è fino l'attuazione ClassLoader per lanciare un'istanza ClassNotFoundException quando si è in grado di caricare una classe. La maggior parte delle implementazioni classloader personalizzato eseguire questa dal momento che estendono l'URLClassLoader. Di solito classloader non buttare esplicitamente un NoClassDefFoundError su una delle implementazioni di metodo -. Questa eccezione viene di solito gettato dalla JVM HotSpot nel compilatore, e non dal programma di caricamento classe per sé

differenza tra ClassNotFoundException Vs NoClassDefFoundError

 entrare descrizione dell'immagine qui

  

Con i nomi si possiamo facilmente identificare uno da Exception e altro è da Error.

eccezione: Eccezioni si verifica durante l'esecuzione del programma. Un programmatore in grado di gestire queste eccezioni dal blocco try catch. Abbiamo due tipi di eccezioni. eccezione controllata che getta in fase di compilazione. Eccezioni runtime che vengono gettati in fase di esecuzione, queste eccezioni si verificano di solito a causa della cattiva programmazione.

Errore: Queste non sono eccezioni a tutti, è oltre la portata di programmatore. Questi errori di solito sono gettati dalla JVM.


entrare descrizione dell'immagine qui fonte immagine

Differenza:

ClassNotFoundException:

  • Classe loader non riesce a Verifica di un codice di classe di byte citiamo in fase di Link del sottosistema di caricamento delle classi si ottiene ClassNotFoundException.
  • ClassNotFoundException è un eccezione controllata derivato direttamente dalla classe java.lang.Exception ed è necessario fornire la gestione esplicita per esso
  • ClassNotFoundException si apre quando c'è un caricamenti espliciti di classe è coinvolta, fornendo nome della classe in fase di esecuzione utilizzando ClassLoader.loadClass (), Class.forName () e ClassLoader.findSystemClass ().

NoClassDefFoundError:

  • Classe loader non riesce a risolvere i riferimenti di una classe in fase di Link del sottosistema di caricamento delle classi otteniamo NoClassDefFoundError.
  • NoClassDefFoundError è un errore derivata dalla classe LinkageError, che viene utilizzato per indicare i casi di errore, in cui una classe ha una dipendenza da qualche altra classe e che classe è incompatili cambiato dopo la compilazione.
  • NoClassDefFoundError è il risultato di loading implicito della classe a causa di una chiamata di metodo da tale classe o qualsiasi accesso variabile.

Somiglianze:

  • Sia NoClassDefFoundError e ClassNotFoundException sono legati alla indisponibilità di una classe in fase di esecuzione.
  • Sia ClassNotFoundException e NoClassDefFoundError sono legati a Java classpath.

Dato azioni classe Loader sussystem:

http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

Questo è un articolo che mi ha aiutato molto a capire la differenza: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

  

Se si verifica un errore durante il caricamento della classe, quindi un'istanza di un   sottoclasse di LinkageError deve essere gettato in un punto del programma che   (Direttamente o indirettamente) utilizza la classe o interfaccia corso di caricamento.

     

Se la Java Virtual Machine tenta mai di caricare una classe C durante   verifica (§5.4.1) o la risoluzione (§5.4.3) (ma non inizializzazione   (§5.5)), e il caricatore classe che viene utilizzato per avviare il caricamento di C   getta un'istanza di ClassNotFoundException , quindi il Java virtuale   La macchina deve lanciare un'istanza di NoClassDefFoundError la cui causa è   l'istanza di ClassNotFoundException .

ClassNotFoundException è una causa principale di NoClassDefFoundError .
E un NoClassDefFoundError è un caso speciale di errore tipo di carico, che si verifica a Collegamento passo.

Aggiungi una possibile ragione pratica:

  • ClassNotFoundException: come ha detto Cletus, si utilizza l'interfaccia mentre la classe ereditata di interfaccia non è nel classpath. Ad esempio, servizio modello Provider (o Service Locator ) tenta di individuare alcuni non classe -existing
  • NoClassDefFoundError: data classe si trova, mentre la dipendenza della data classe non si trova

In pratica, Errore può essere gettato silenziosamente , per esempio, si invia un compito timer e nel Task timer getta Errore , mentre nella maggior parte dei casi, il programma di cattura solo eccezione . Poi il Timer ciclo principale è finito senza alcuna informazione. Un errore simile a NoClassDefFoundError è ExceptionInInitializerError , quando il vostro inizializzatore statico o l'inizializzazione di una variabile statica genera un'eccezione.

ClassNotFoundException è un'eccezione controllata che si verifica quando diciamo JVM per caricare una classe con il suo nome stringa utilizzando Class.forName () o ClassLoader.findSystemClass () o ClassLoader.loadClass () metodi e menzionati classe non si trova nel percorso di classe.

La maggior parte del tempo, questa eccezione si verifica quando si tenta di eseguire un'applicazione senza aggiornare il percorso di classe con i file JAR richiesti. Ad esempio, si può avere visto questa eccezione quando si fa il codice JDBC per la connessione al database i.e.MySQL ma il vostro percorso di classe non hanno JAR per esso.

NoClassDefFoundError errore si verifica quando JVM tenta di caricare una classe particolare, che è la parte del tuo esecuzione di codice (come parte di una normale chiamata di metodo o come parte della creazione di un'istanza utilizzando la nuova parola chiave) e che la classe non è presente nel classpath, ma era presente al momento della compilazione perché al fine di eseguire il programma è necessario compilarlo e se si sta tentando di utilizzare una classe che non è presente compilatore solleverà errore di compilazione.

Di seguito il breve descrizione

entrare descrizione dell'immagine qui

Si può leggere Tutto su ClassNotFoundException Vs NoClassDefFoundError per maggiori dettagli.

ricordo a me stesso più e più volte il seguente quando ho bisogno di aggiornare

ClassNotFoundException

Gerarchia delle classi

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

Durante il debug

  1. jar richiesti, la classe non è presente nella classpath.
  2. Verifica tutti i barattoli richiesti sono nel classpath di JVM.

NoClassDefFoundError

Gerarchia delle classi

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

Durante il debug

  1. Problema con il caricamento di una classe in modo dinamico, che è stato compilato correttamente
  2. problema con blocchi statici, costruttori, init () metodi di classe dipendente e l'errore effettivo è avvolto da strati multipli [soprattutto quando si utilizza la primavera, ibernazione l'eccezione reale è avvolto e otterrete NoClassDefError]
  3. Quando si faccia "ClassNotFoundException" sotto un blocco statico di classe dipendenti
  4. problema con le versioni di Classe. Questo succede quando si hanno due versioni V1, V2 della stessa classe in diverse vaso / pacchetti, che è stato compilato con successo usando v1 e v2 è caricato il runtime che non lo fa ha i relativi metodi / vars & vedrete questa eccezione. [Una volta ho risolto questo problema rimuovendo il duplicato della classe relativa log4j sotto molteplici vasi che è apparso nel classpath]

ClassNotFoundException e NoClassDefFoundError si verificano quando una classe particolare, non si trova in runtime.However, si verificano in diversi scenari.

ClassNotFoundException è un'eccezione che si verifica quando si tenta di caricare una classe in fase di esecuzione utilizzando Class.forName () o loadClass () metodi e classi citate non si trovano nel classpath.

    public class MainClass
    {
        public static void main(String[] args)
        {
            try
            {
                Class.forName("oracle.jdbc.driver.OracleDriver");
            }catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
    }



    java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    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 java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pack1.MainClass.main(MainClass.java:17)

NoClassDefFoundError è un errore che si verifica quando una classe particolare è presente al momento della compilazione, ma mancava in fase di esecuzione.

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

Quando si compila il programma di cui sopra, due file .class saranno generati. Uno è A.class e un altro è B.class. Se si rimuove il file A.class ed eseguire il file B.class, Java Runtime Sistema getterà NoClassDefFoundError come di seguito:

    Exception in thread "main" java.lang.NoClassDefFoundError: A
    at MainClass.main(MainClass.java:10)
    Caused by: java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top