1. Обзор
В этой статье мы продемонстрируем причину NoSuchFieldError и узнаем, как ее устранить.
2. NoSuchFieldError
Как следует из названия, NoSuchFieldError возникает, когда указанное поле не существует. NoSuchFieldError расширяет класс IncompatibleClassChangeError и выбрасывается , когда приложение пытается получить доступ или изменить поле объекта или статическое поле класса, но объект или класс больше не имеет этого поля .
Класс IncompatibleClassChangeError расширяет класс LinkageError и возникает, когда мы выполняем несовместимые изменения определения класса. Наконец, LinkageError расширяет Error и показывает, что класс имеет некоторую зависимость от другого несовместимо измененного класса.
Давайте рассмотрим эту ошибку в действии на примере. В качестве первого шага давайте создадим класс Dependency :
public class Dependency { public static String message = "Hello Baeldung!!"; }
Затем мы создадим Пример ошибки поля класс, который ссылается на поле нашего Зависимого класса:
public class FieldErrorExample { public static String getDependentMessage() { return Dependency.message; } }
Давайте также добавим код, чтобы проверить, получаем ли мы сообщение из класса Dependency :
public static void fetchAndPrint() { System.out.println(getDependentMessage()); }
Теперь мы можем скомпилировать эти файлы с помощью команды javac , и при выполнении примера Ошибки поля класса с помощью команды java он напечатает указанное сообщение .
Однако если мы закомментируем, удалим или изменим имя атрибута в классе Dependency и перекомпилируем его, то мы столкнемся с нашей ошибкой .
Например, давайте изменим имя атрибута в нашем классе Dependency :
public class Dependency { public static String msg = "Hello Baeldung!!"; }
Теперь, если мы перекомпилируем только нашу Зависимость класс , , а затем снова выполним Пример ошибки поля , мы столкнемся с NoSuchFieldError :
Exception in thread "main" java.lang.NoSuchFieldError: message
Приведенная выше ошибка произошла из — за того, что класс FieldErrorExample по-прежнему ссылается на статическое поле message класса Dependency , но он больше не существует-мы внесли несовместимое изменение в класс Dependency .
3. Устранение ошибки
Чтобы избежать этой ошибки, нам нужно очистить и скомпилировать существующие файлы . Мы можем сделать это с помощью команды javac или с помощью Maven, запустив mvn clean install. Выполнив этот шаг, мы получим все последние скомпилированные файлы и избежим ошибки.
Если ошибка сохраняется, то проблема может заключаться в нескольких файлах JAR: один во время компиляции, а другой во время выполнения. Это часто происходит, когда приложение зависит от внешних банок. Здесь мы должны проверить порядок банок в пути сборки , чтобы идентифицировать несогласованную банку.
Если нам нужно продолжить расследование, полезно запустить приложение с параметром -verbose: class , чтобы проверить загруженные классы. Это может помочь нам определить устаревший класс.
Иногда сторонний JAR может внутренне ссылаться на другую версию, что приводит к NoSuchFieldError . Если это произойдет, мы можем использовать зависимость mvn:tree -Dverbose. Это создает дерево зависимостей maven и помогает нам идентифицировать несогласованный JAR.
4. Заключение
В этом коротком уроке мы показали, почему возникает NoSuchFieldError , и рассмотрели, как мы можем это решить.
Как всегда, код доступен на GitHub .