Le due eccezioni sono concettualmente simili (manca qualche jar o .class nel classpath) ma è diversa la tipologia di eccezione, la ClassNotFoundException è di tipo checked (che estende dunque da java.lang.Exception e che ha bisogno del try/catch) mentre la NoClassDefFoundError è di tipo Error , quindi unchecked
java.lang.ClassNotFoundException
L' eccezione ClassNotFoundException si verifica quando una applicazione tenta di chiamare una classe utilizzando :
Tale codice produce il seguente risultato:
java.lang.NoClassDefException
Questa eccezione è sollevata dalla JVM quando cerca di caricare una classe a runtime e non la trova.
E' una sottoclasse di java.lang.LinkageError, il problema è che la classe che stiamo chiamando ne utilizza un'altra a runtime non presente.
Il classico esempio si ha quando proviamo ad invocare da console una classe java dimenticandoci il nome completo del package (il classico Hello World che all'inizio non funziona mai).
Esempio:
Supponiamo di utilizzare la libreria jmimemagic (descritta in un precedente post) e di usarla dimenticandoci di aggiungere al classpath la libreria commons-logging.jar.
Il codice compila correttamente, in quanto la nostra classe richiama esclusivamente la classe MagicMatcher che fa parte della libreria jmimemagic e che è inclusa nel classpath.
A Runtime abbiamo una NoClassDefException .
Eseguendo il codice non si passa per il catch (si ricordi che l'eccezione è sottoclasse di LinkageError e quindi di Throwable, non di Exception) e in console sarà stampata direttamente la NoClassDefException, nel cui stacktrace troviamo anche l'origine dell'errore, che è una eccezione di tipo ClassNotFoundException per l'appunto.
java.lang.ClassNotFoundException
L' eccezione ClassNotFoundException si verifica quando una applicazione tenta di chiamare una classe utilizzando :
- Il metodo
forName
nella classeClass
. - Il metodo
findSystemClass
nella classeClassLoader
. - Il metodo
loadClass
nella classeClassLoader
.
public static void main(String[] args) throws Exception{
Class c=Class.forName("classenonEsistente");
System.out.println(c.getName());
}
Tale codice produce il seguente risultato:
Exception in thread "main" java.lang.ClassNotFoundException: classenonEsistente
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at ExceptionSample.main(ExceptionSample.java:5)
java.lang.NoClassDefException
Questa eccezione è sollevata dalla JVM quando cerca di caricare una classe a runtime e non la trova.
E' una sottoclasse di java.lang.LinkageError, il problema è che la classe che stiamo chiamando ne utilizza un'altra a runtime non presente.
Il classico esempio si ha quando proviamo ad invocare da console una classe java dimenticandoci il nome completo del package (il classico Hello World che all'inizio non funziona mai).
Esempio:
Supponiamo di utilizzare la libreria jmimemagic (descritta in un precedente post) e di usarla dimenticandoci di aggiungere al classpath la libreria commons-logging.jar.
Il codice compila correttamente, in quanto la nostra classe richiama esclusivamente la classe MagicMatcher che fa parte della libreria jmimemagic e che è inclusa nel classpath.
A Runtime abbiamo una NoClassDefException .
public static void main(String[] args) {
try
{
Magic m=new Magic();
byte[] lb=FileUtil.load(new File("file/WS.png"));
MagicMatch match = m.getMagicMatch(lb);
System.out.println(match.getMimeType());
}
catch (Exception e) {
System.out.println("Eccezione!!!");
e.printStackTrace();
}
}
Eseguendo il codice non si passa per il catch (si ricordi che l'eccezione è sottoclasse di LinkageError e quindi di Throwable, non di Exception) e in console sarà stampata direttamente la NoClassDefException, nel cui stacktrace troviamo anche l'origine dell'errore, che è una eccezione di tipo ClassNotFoundException per l'appunto.
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at net.sf.jmimemagic.Magic.(Magic.java:46)
at MatchMagic.main(MatchMagic.java:21)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 2 more
Nessun commento:
Posta un commento