2011-11-12 17 views
5

Sto osservando le differenze tra piattaforme su quando Class.forName() genera ClassNotFoundException e quando genera NoClassDefFoundError. Questo comportamento è ben definito da qualche parte o mi sono imbattuto in un bug?Capitalization e NoClassDefFoundError vs ClassNotFoundException

Si consideri il seguente codice (che è un file standalone Java nel pacchetto predefinito):

public class DLExceptionType { 

    private static void printFindError(String name) { 
    System.out.print(name + ": "); 
    try { 
     Class.forName(name); 
     System.out.println("** no error **"); 
    } catch (Throwable e) { 
     System.out.println(e); 
    } 
    } 

    public static void main(String[] args) { 
    printFindError("DLExceptionType"); 
    printFindError("dLExceptionType"); // note the mis-capitalization 
    } 
} 

Il codice produce i risultati attesi su Linux:

[eos18:~]$ java -version DLExceptionType 
java version "1.6.0_26" 
Java(TM) SE Runtime Environment (build 1.6.0_26-b03) 
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode) 
[eos18:~]$ java DLExceptionType 
DLExceptionType: ** no error ** 
dLExceptionType: java.lang.ClassNotFoundException: dLExceptionType 

Produce un diverso, ma comprensibile, uscita su Windows:

java version "1.7.0_01" 
Java(TM) SE Runtime Environment (build 1.7.0_01-b08) 
Java HotSpot(TM) Client VM (build 21.1-b02, mixed mode, sharing) 

Y:\Temp>java DLExceptionType 
DLExceptionType: ** no error ** 
dLExceptionType: java.lang.NoClassDefFoundError: dLExceptionType (wrong name: DLExceptionType) 

L'uscita su Windows ha un senso: Beca utilizzare il file system non è case sensitive, la JVM carica il file dLExceptionType.class, ma che il file contiene una classe con un nome diverso: DLExceptionType

Tuttavia, quando si esegue il codice su Mac (con ha un case-sensitive file system e una JVM più recente rispetto alla macchina Linux) ottengo la stessa uscita di Windows:

$ java -version 
java version "1.6.0_29" 
Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-10M3527) 
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode) 
$ java DLExceptionType 
DLExceptionType: ** no error ** 
dLExceptionType: java.lang.NoClassDefFoundError: dLExceptionType (wrong name: DLExceptionType) 
+0

Ho avuto un problema con un file repository git l'altro giorno; in OS X trattava 'foo.rb' e' Foo.rb' come lo stesso file. Bash sapeva la differenza. –

risposta

3

HFS + (Mac Extended) di solito non è tra maiuscole e minuscole. Dal momento che Mac OS 10.3 Apple ha introdotto HFSX che può essere case sensitive (ma non è l'impostazione predefinita). Se non è stata specificata l'opzione dall'inizializzazione del disco, il volume è probabilmente non sensibile al maiuscolo/minuscolo.

Vedi: http://en.wikipedia.org/wiki/HFS_Plus

+0

Wow. Ho usato un Mac per 8 anni e non ho mai notato che la FS non fosse sensibile alle maiuscole e alle minuscole! – Zack

0

Non c'è bug qui. Quello che stai vedendo è causato interamente dalla distinzione tra maiuscole e minuscole del filesystem.

Quando si carica la classe dLExceptionType su un file system senza distinzione tra maiuscole e minuscole, la JVM può trovare un file dLException.class. Tuttavia, la classe in essa contenuta non ha il nome dLException e ciò causa il numero NoClassDefFoundError. Quando si tenta di caricare questa classe su un filesystem con distinzione tra maiuscole e minuscole, la JVM non riesce a trovare il file.

A NoClassDefFoundError con (wrong name: ...) nel messaggio viene generato dalla JVM ogni volta che carica una classe che sembra avere un nome diverso dal nome del file da cui è stata letta. Puoi provare questo su qualsiasi filesystem rinominando il file di classe e tentando di eseguirlo.

Problemi correlati