Перейти к основному содержимому

NoSuchFieldError в Java

· 3 мин. чтения

1. Обзор

В этой статье мы покажем причину NoSuchFieldError и узнаем, как ее устранить.

2. Ошибка НоСучФилд

Как следует из названия, NoSuchFieldError возникает, когда указанное поле не существует. NoSuchFieldError расширяет класс IncompiledClassChangeError и вызывается, когда приложение пытается получить доступ или изменить поле объекта или статическое поле класса, но в объекте или классе больше нет этого поля .

` Класс IncompileClassChangeError расширяет класс [LinkageError](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/LinkageError.html) и возникает, когда мы вносим несовместимые изменения в определение класса. Наконец, LinkageError расширяет Error` и показывает, что класс имеет некоторую зависимость от другого несовместимо измененного класса.

Давайте посмотрим на эту ошибку в действии на примере. В качестве первого шага давайте создадим класс зависимостей :

public class Dependency {
public static String message = "Hello ForEach!!";
}

Затем мы создадим класс FieldErrorExample , который ссылается на поле нашего класса Dependency :

public class FieldErrorExample {
public static String getDependentMessage() {
return Dependency.message;
}
}

Давайте также добавим код, чтобы проверить, получаем ли мы сообщение от класса Dependency :

public static void fetchAndPrint() {
System.out.println(getDependentMessage());
}

Теперь мы можем скомпилировать эти файлы с помощью команды javac , и после выполнения класса FieldErrorExample с помощью команды java он напечатает указанное сообщение .

Однако если мы закомментируем, удалим или изменим имя атрибута в классе Dependency и перекомпилируем его, то мы столкнемся с нашей ошибкой .

Например, давайте изменим имя атрибута в нашем классе Dependency :

public class Dependency {
public static String msg = "Hello ForEach!!";
}

Теперь, если мы перекомпилируем только наш класс Dependency , а затем снова выполним FieldErrorExample , мы столкнемся с NoSuchFieldError :

Exception in thread "main" java.lang.NoSuchFieldError: message

Вышеупомянутая ошибка произошла из-за того, что класс FieldErrorExample по- прежнему ссылается на сообщение статического поля класса Dependency , но его больше не существует — мы внесли несовместимое изменение в класс Dependency .

3. Устранение ошибки

Чтобы избежать этой ошибки, нам нужно очистить и скомпилировать существующие файлы . Мы можем сделать это с помощью команды javac или с помощью Maven, запустив mvn clean install. Выполнив этот шаг, мы получим все последние скомпилированные файлы и избежим ошибки.

Если ошибка не устранена, проблема может заключаться в нескольких файлах JAR: один во время компиляции, а другой во время работы. Это часто происходит, когда приложение зависит от внешних файлов JAR. Здесь мы должны проверить порядок файлов JAR в пути сборки, чтобы определить несогласованный файл JAR.

Если нам нужно продолжить расследование, полезно запустить приложение с параметром -verbose: class, чтобы проверить загруженные классы. Это может помочь нам определить устаревший класс.

Иногда сторонний JAR может внутренне ссылаться на другую версию, что приводит к NoSuchFieldError . Если это произойдет, мы можем использовать зависимость mvn:tree -Dverbose. Это создает дерево зависимостей maven и помогает нам идентифицировать несовместимый JAR.

4. Вывод

В этом кратком руководстве мы показали, почему возникает NoSuchFieldError , и рассмотрели, как мы можем решить эту проблему.

Как всегда, код доступен на GitHub .