2011-11-12 18 views
5

Estoy viendo diferencias entre plataformas sobre cuándo Class.forName() arroja ClassNotFoundException y cuándo arroja NoClassDefFoundError. ¿Este comportamiento está bien definido en alguna parte o me he topado con un error?Mayúsculas y NoClassDefFoundError frente a ClassNotFoundException

considere el siguiente código (que es un archivo independiente de Java en el paquete por defecto):

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

El código produce la salida esperada en 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 una diferente, pero comprensible, salida en 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) 

La salida en Windows tiene sentido: Beca utilizar el sistema de archivos no distingue entre mayúsculas y minúsculas, JVM carga el archivo dLExceptionType.class, pero ese archivo contiene una clase con un nombre diferente: DLExceptionType

Sin embargo, cuando ejecuto el código en Mac (con mayúsculas y minúsculas) sistema de archivos y una JVM más reciente que la máquina Linux) consigo el mismo resultado que en 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

Tuve un problema de caso con un archivo git repo el otro día; en OS X estaba tratando 'foo.rb' y' Foo.rb' como el mismo archivo. Bash sabía la diferencia. –

Respuesta

3

HFS + (Mac ampliada) por lo general no distingue entre mayúsculas y minúsculas. Desde Mac OS 10.3, Apple introdujo HFSX, que puede ser sensible a mayúsculas y minúsculas (pero no es el valor predeterminado). Si no especificó la opción mediante la inicialización del disco, es probable que su volumen no sea sensible a las mayúsculas y minúsculas.

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

+0

Wow. ¡He estado usando una Mac durante 8 años y nunca me di cuenta de que la FS no era sensible a mayúsculas y minúsculas! – Zack

0

No hay error aquí. Lo que estás viendo está causado completamente por la sensibilidad de mayúsculas y minúsculas del sistema de archivos.

Al cargar la clase dLExceptionType en un sistema de archivos insensible a mayúsculas y minúsculas, la JVM puede encontrar un archivo dLException.class. Sin embargo, la clase que contiene no tiene el nombre dLException, y esto causa el NoClassDefFoundError. Al intentar cargar esta clase en un sistema de archivos sensible a mayúsculas y minúsculas, la JVM no puede encontrar el archivo en absoluto.

A NoClassDefFoundError con (wrong name: ...) en el mensaje se lanza por la JVM cada vez que carga una clase que parece tener un nombre diferente al nombre del archivo desde el que se leyó. Puede probar esto en cualquier sistema de archivos cambiando el nombre del archivo de clase e intentando ejecutarlo.

Cuestiones relacionadas