NoSuchFieldError Java

Я получаю NoSuchFieldError в своем коде, теперь oracle не очень-то разбирается в том, почему эта ошибка возникает только из-за того, что эта ошибка может возникать только во время выполнения, если определение classа несовместимо изменилось.

Может ли кто-нибудь объяснить мне, как можно «несовместимо изменить» class? Класс, о котором я говорю, расширяет довольно много classов, поэтому я подозреваю, что это может быть связано с этим, но я не знаю, с чего начать искать или что я ищу.

Эта ошибка обычно возникает, если вы только частично перекомпилируете свой код. У вас есть старый код, который ссылается на поле, которое больше не существует в перекомпилированных файлах classов.

Решение состоит в том, чтобы очистить все файлы classов и скомпилировать все из свежего.

Обновление. Если вы все равно получите такую ​​же ошибку после повторной компиляции всего, то вы, вероятно, компилируете против одной версии внешней библиотеки и используете другую во время выполнения.

Теперь вам нужно сначала определить class, который вызывает проблему (похоже, что вы это уже сделали), а затем запустите приложение с помощью опции командной строки -verbose:class . Он выгрузит много информации о загрузке classов на ваш стандарт, и вы сможете узнать, от чего загружен проблемный class.

Когда компилятор скомпилировал код, который выбрасывает ошибку, появился еще один class с полем, и ваш class мог получить доступ к этому полю (считывая или изменяя значение).

Во время выполнения другой class каким-то образом не имеет поля с этим именем, что приводит к указанной ошибке.

Одна из причин может заключаться в том, что второй class изменился без перекомпиляции первого. Перекомпилируйте все свои classы, и вы должны либо получить ошибку компилятора (которая даст вам больше информации о том, как это решить), либо class будет ссылаться на правильный class.

Другая причина может заключаться в том, что у вас есть некоторый class в более чем одном файле jar (или каталоге) в пути к classу (в разных версиях), в результате чего другой class использует неправильный. Проверьте все ваши банки на повторяющихся classах.

Это означает, что вы, вероятно, перекомпилировали class, на который зависел другой уже скомпилированный class, и не перекомпилировали соответствующий class.

Например:

 public class MyClass { public int num; public MyClass() { num = 1; } } public class MyDependingClass { private int foo; public MyDependingClass(MyClass init) { foo = init.num; } } 

Таким образом, вы перекомпилируете два classа, предположительно вручную (среда IDE обычно обновляет рабочую область проекта для вас, так что обрабатывайте classы).

И это сработало.

Позже вы решите реорганизовать MyClass:

 public class MyClass { private int innernum; public int getNum() { return innernum; } public MyClass() { innernum = 1; } } 

Если вы компилируете MyClass, а не MyDependingClass, когда вы запускаете свою программу и создаете экземпляр MyDependingClass, вы получите свой NoSuchFieldError .

Краткосрочное исправление, вероятно, должно перекомпилировать все classы в вашей рабочей области, что должно показать ошибку.

Долгосрочное исправление заключается в использовании Eclipse или NetBeans или другой IDE, которая обрабатывает это для вас.

Что-то, чтобы быть осторожным при отслеживании этих ошибок в среде IDE (Eclipse в моем случае), – это следить за зависимостями проектов, от которых может зависеть ваш проект. Если вы используете разные версии библиотеки в разных зависимых проектах, загрузчик classpath может забрать неправильный. Это включает в себя проект, зависящий от банки, созданной из проекта Eclipse, и имеющий другой проект, зависящий от этого проекта и проекта, из которого была создана банка. Устаревшие classы в банке потенциально могут быть загружены вместо classов из проекта.

Пример:

project1 зависит от project3 и project3

project3 зависит от project2.jar , jar, созданный из файлов classов в project2

Конечное статическое поле добавляется к classу в project2 , который перекомпилируется, а project2.jar не перестраивается

Запуск project1 может вызвать исключение, поскольку classы из project2 могут быть загружены непосредственно из проекта или в банку, у которой нет поля

Это было довольно сложно для меня, поэтому я пишу свое решение.

Я работал в IntelliJ с Boot, все было в порядке, все версии Java 8 были настроены соответствующим образом.

Через несколько часов я как-то проверил на терминале javac -версию и угадал, что было, она была установлена ​​в версии 9. Поэтому обязательно посмотрите на javac, я знаю его контрапункт, но предположительно, так как я установил jdk на профиль bash, на IntelliJ и т. д., я не должен был это беспокоиться.

Надеюсь, поможет!

  • Где узнать о VS отладчике «волшебные имена»
  • Как просмотреть необработанный HTTP-запрос, отправляемый classом HttpWebRequest?
  • Как использовать условную точку останова в Eclipse?
  • Шаг через исходный код JDK в IntelliJ IDEA
  • Как избежать доступа к изменяемой переменной из закрытия
  • Почему я не могу редактировать метод, содержащий анонимный метод в отладчике?
  • Простой способ отладки службы Windows
  • Android: Как отслеживать происхождение InflateException?
  • Что такое отладчик и как он может помочь мне диагностировать проблемы?
  • Как я могу отлаживать приложения в Java Web Start (JNLP)?
  • Расшифровка информации о переменной при отладке Java
  • Давайте будем гением компьютера.