Использование заглавных букв и NoClassDefFoundError против ClassNotFoundException - PullRequest
5 голосов
/ 12 ноября 2011

Я вижу различия между платформами в том, когда Class.forName () генерирует исключение ClassNotFoundException и когда он генерирует NoClassDefFoundError. Это поведение где-то четко определено или я наткнулся на ошибку?

Рассмотрим следующий код (который является автономным Java-файлом в пакете по умолчанию):

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

Код выдает ожидаемый результат в 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

Он производит другой, но понятный вывод для 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)

Вывод в Windows имеет смысл: поскольку файловая система не чувствительна к регистру, JVM загружает файл dLExceptionType.class, но этот файл содержит класс с другим именем: DLExceptionType

Однако, когда я запускаю код на Mac (с файловой системой с учетом регистра и более новой JVM, чем в Linux), я получаю тот же вывод, что и 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)

Ответы [ 2 ]

3 голосов
/ 12 ноября 2011

HFS + (Mac Extended) обычно не чувствителен к регистру.Начиная с Mac OS 10.3 Apple представила HFSX, которая может быть чувствительна к регистру (но не по умолчанию).Если вы не указали эту опцию при инициализации диска, скорее всего, ваш том не учитывает регистр.

См .: http://en.wikipedia.org/wiki/HFS_Plus

0 голосов
/ 12 ноября 2011

Здесь нет ошибки. То, что вы видите, полностью обусловлено чувствительностью к регистру файловой системы.

При загрузке класса dLExceptionType в файловой системе без учета регистра JVM может найти файл dLException.class. Однако класс, который он содержит, не имеет имени dLException, и это вызывает NoClassDefFoundError. При попытке загрузить этот класс в файловой системе, чувствительной к регистру, JVM вообще не может найти файл.

A NoClassDefFoundError с (wrong name: ...) в сообщении генерируется JVM всякий раз, когда он загружает класс, имя которого отличается от имени файла, из которого он был прочитан. Вы можете попробовать это на любой файловой системе, переименовав файл класса и попытавшись запустить его.

...