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 .