2011-11-12 13 views
5

Widzę różnice między platformami, gdy Class.forName() generuje ClassNotFoundException i gdy rzuca NoClassDefFoundError. Czy to zachowanie jest gdzieś zdefiniowane, czy też natknąłem się na błąd?Capitalization i NoClassDefFoundError vs ClassNotFoundException

Rozważmy następujący kod (który jest samodzielny plik java w domyślnym zestawie):

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

Kod daje spodziewanych rezultatów w systemie 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 

produkuje różne, ale zrozumiałe, wyjście w systemie 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) 

Dane wyjściowe w systemie Windows mają sens: Beca w systemie plików nie jest rozróżniana wielkość liter, JVM ładuje plik dLExceptionType.class, ale ten plik zawiera klasę o innej nazwie: DLExceptionType

Jednak po uruchomieniu kodu na komputerze Mac (z uwzględnieniem wielkości liter System plików i nowsza JVM niż Linux) uzyskać taki sam efekt jak 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

Miałem problem z plikiem z repozytorium git na drugi dzień; w OS X traktowano "foo.rb" i "Foo.rb" jako ten sam plik. Bash znał różnicę. –

Odpowiedz

3

HFS + (Mac Extended) zwykle nie jest uwzględniana wielkość liter. Ponieważ Mac OS 10.3 Apple wprowadził HFSX, który może być rozróżniany wielkość liter (ale nie jest domyślny). Jeśli opcja ta nie została określona przez inicjalizację dysku, wówczas wielkość woluminu jest najbardziej niewrażliwa na wielkość liter.

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

+0

Wow. Używam komputera Mac od 8 lat i nigdy nie zauważyłem, że w FS nie jest rozróżniana wielkość liter! – Zack

0

Nie ma tu błędu. To, co widzisz, jest spowodowane wyłącznie rozróżnianiem wielkości liter w systemie plików.

Podczas ładowania klasy dLExceptionType w systemie plików niewrażliwym na wielkość znaków JVM może znaleźć plik dLException.class. Jednak klasa, którą zawiera, nie ma nazwy dLException, a to powoduje, że NoClassDefFoundError. Podczas próby załadowania tej klasy w systemie plików wrażliwym na wielkość liter maszyna JVM w ogóle nie może znaleźć pliku.

A NoClassDefFoundError z (wrong name: ...) w wiadomości jest wysyłany przez maszynę JVM za każdym razem, gdy ładuje klasę, która wydaje się mieć inną nazwę do nazwy pliku, z której została odczytana. Możesz spróbować tego na dowolnym systemie plików, zmieniając nazwę pliku klasy i próbując go uruchomić.

Powiązane problemy