Я получаю сообщение NoSuchMethodError
об ошибке при запуске моей Java-программы. Что не так и как мне это исправить?
Я получаю сообщение NoSuchMethodError
об ошибке при запуске моей Java-программы. Что не так и как мне это исправить?
Ответы:
Без дополнительной информации трудно точно определить проблему, но основная причина заключается в том, что вы, скорее всего, скомпилировали класс для другой версии класса, в которой отсутствует метод, а не той, которую вы используете при его запуске.
Посмотрите на трассировку стека ... Если исключение появляется при вызове метода для объекта в библиотеке, вы, скорее всего, используете отдельные версии библиотеки при компиляции и запуске. Убедитесь, что у вас есть правильная версия в обоих местах.
Если исключение появляется при вызове метода для объектов, созданных созданными вами классами , то процесс сборки кажется неисправным. Убедитесь, что файлы классов, которые вы фактически используете, обновляются при компиляции.
Caused by
раздел в трассировке стека, чтобы найти класс виновника / jar
У меня была твоя проблема, и вот как я ее исправил. Следующие шаги являются рабочим способом добавления библиотеки. Первые два шага я сделал правильно, но последний шаг я не сделал, перетащив файл «.jar» прямо из файловой системы в папку «lib» в моем проекте eclipse. Кроме того, мне пришлось удалить предыдущую версию библиотеки как из пути сборки, так и из папки "lib".
Обратите внимание, что в случае отражения вы получаете NoSuchMethodException
, а с неотражающим кодом - NoSuchMethodError
. Я склонен искать в очень разных местах, когда сталкиваюсь с одним против другого.
Если у вас есть доступ для изменения параметров JVM, добавление подробного вывода должно позволить вам увидеть, какие классы загружаются из каких JAR-файлов.
java -verbose:class <other args>
Когда ваша программа запущена, JVM должна вывести на стандартную информацию, такую как:
...
[Загружено junit.framework.Assert из файла: / C: /Program%20Files/junit3.8.2/junit.jar]
...
Это обычно вызывается при использовании системы сборки, такой как Apache Ant, которая компилирует файлы Java только тогда, когда файл Java новее, чем файл класса. Если сигнатура метода изменяется и классы используют старую версию, вещи могут быть скомпилированы неправильно. Обычное исправление - полная перестройка (обычно "ant clean", затем "ant").
Иногда это также может быть вызвано при компиляции с одной версией библиотеки, но с другой версией.
Если вы используете Maven или другой фреймворк, и вы получаете эту ошибку почти случайно, попробуйте чистую установку, например ...
clean install
Это особенно вероятно, если вы написали объект и знаете, что у него есть метод. Работал на меня.
Это также может быть результатом использования отражения. Если у вас есть код, который отражает класс и извлекает метод по имени (например: with Class.getDeclaredMethod("someMethodName", .....)
), то каждый раз, когда имя этого метода изменяется, например, во время рефакторинга, вам нужно будет помнить об обновлении параметров в методе отражения, чтобы они соответствовали подпись нового метода, или getDeclaredMethod
вызов вызовет NoSuchMethodException
.
Если это причина, то трассировка стека должна показывать точку, в которой вызывается метод отражения, и вам просто нужно обновить параметры, чтобы они соответствовали фактической сигнатуре метода.
По моему опыту, это иногда встречается при модульном тестировании частных методов / полей и использовании TestUtilities
класса для извлечения полей для проверки теста. (Как правило, с устаревшим кодом, который не был разработан с учетом модульного тестирования.)
Если вы пишете веб-приложение, убедитесь, что у вас нет конфликтующих версий jar-файла в каталоге глобальной библиотеки вашего контейнера, а также в вашем приложении. Вы можете не обязательно знать, какой jar-файл используется загрузчиком классов.
например
Эти проблемы вызваны использованием одного и того же объекта в тех же двух классах. Используемые объекты не содержат новый метод, который был добавлен в новый класс объектов.
например:
filenotnull=/DayMoreConfig.conf
16-07-2015 05:02:10:ussdgw-1: Open TCP/IP connection to SMSC: 10.149.96.66 at 2775
16-07-2015 05:02:10:ussdgw-1: Bind request: (bindreq: (pdu: 0 9 0 [1]) 900 900 GEN 52 (addrrang: 0 0 2000) )
Exception in thread "main" java.lang.NoSuchMethodError: gateway.smpp.PDUEventListener.<init>(Lgateway/smpp/USSDClient;)V
at gateway.smpp.USSDClient.bind(USSDClient.java:139)
at gateway.USSDGW.initSmppConnection(USSDGW.java:274)
at gateway.USSDGW.<init>(USSDGW.java:184)
at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40)
-bash-3.00$
Эти проблемы вызваны сопутствующим 02 аналогичным классом (1 в src, 1 в jar-файле здесь - gateway.jar)
Я только что решил эту ошибку, перезапустив Eclipse и запустив приложение. Причиной моего дела может быть то, что я заменяю свои исходные файлы, не закрывая проект или Eclipse Что вызвало разные версии классов, которые я использовал.
Просто добавляю к существующим ответам. Я столкнулся с этой проблемой с котом в затмении. Я изменил один класс и сделал следующие шаги,
Очистили и построили проект в eclpise
mvn clean install
Тем не менее я столкнулся с той же ошибкой. Затем я очистил tomcat, очистил рабочий каталог tomcat и перезапустил сервер, и моя проблема исчезла. Надеюсь, это поможет кому-то
Чтобы ответить на оригинальный вопрос. Согласно документам Java здесь :
«NoSuchMethodError» Брошенный, если приложение пытается вызвать указанный метод класса (статический или экземпляр), и у этого класса больше нет определения этого метода.
Обычно эта ошибка отлавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение класса несовместимо изменилось.
Я исправил эту проблему в Eclipse, переименовав тестовый файл Junit.
В моем рабочем пространстве Eclipse у меня есть проект App и тестовый проект.
Тестовый проект имеет проект App как необходимый проект на пути сборки.
Начал получать NoSuchMethodError.
Затем я понял, что класс в проекте Test имеет то же имя, что и класс в проекте App.
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
После переименования теста на правильное имя «ProjectionTest.java» исключение исчезло.
У меня была такая же ошибка:
Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonGenerator.writeStartObject(Ljava/lang/Object;)V
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:151)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)
Чтобы решить эту проблему, я сначала проверил диаграмму зависимостей модуля ( click in your POM the combination -> Ctrl+Alt+Shift+U
или right click in your POM -> Maven -> Show dependencies
), чтобы понять, где именно был конфликт между библиотеками (Intelij IDEA). В моем конкретном случае у меня были разные версии зависимостей Джексона.
1) Итак, я прямо добавил в свой POM проекта самую высокую версию - 2.8.7 из этих двух.
В свойствах:
<jackson.version>2.8.7</jackson.version>
И как зависимость:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2) Но также это может быть решено с помощью исключения зависимостей .
По тому же принципу, что и в примере ниже:
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
Зависимость от нежелательной версии будет исключена из вашего проекта.
В моем случае у меня был многомодульный проект, и сценарий был как com.xyz.TestClass
в модуле, A
так и в модуле, B
а модуль A
зависел от модуля B
. Поэтому при создании jar-сборки я думаю, что была сохранена только одна версия класса, если у нее нет вызванного метода, тогда я получал NoSuchMethodError
исключение времени выполнения, но компиляция прошла хорошо.
Связанный: https://reflectoring.io/nosuchmethod/
Приведенный выше ответ очень хорошо объясняет. Просто добавьте одну вещь. Если вы используете eclipse, используйте ctrl + shift + T и введите структуру пакета класса (например, gateway.smpp.PDUEventListener), вы найдете все jar / проекты, в которых он присутствует. , Удалите ненужные фляги из пути к классам или добавьте выше в пути к классам. Теперь он подберет правильный.
Я столкнулся с подобной проблемой.
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
Наконец, я определил основную причину изменения типа данных переменной.
Employee.java
-> Содержит переменную ( EmpId
), тип данных которой был изменен с int
на String
.ReportGeneration.java
-> Получает значение , используя геттер, getEmpId()
.Мы должны восстановить банку, включив только модифицированные классы. Поскольку изменений ReportGeneration.java
не было, я включил только Employee.class
файл Jar. Мне пришлось включить ReportGeneration.class
файл в банку, чтобы решить проблему.
У меня была такая же проблема. Это также вызвано тем, что в классах есть неоднозначность. Моя программа пыталась вызвать метод, который присутствовал в двух файлах JAR, находящихся в одном и том же месте / пути к классам. Удалите один файл JAR или выполните свой код так, чтобы использовался только один файл JAR. Убедитесь, что вы не используете один и тот же JAR или разные версии одного и того же JAR, которые содержат один и тот же класс.
DISP_E_EXCEPTION [шаг] [] [Z-JAVA-105 Java-исключение java.lang.NoSuchMethodError (com.example.yourmethod)]
В большинстве случаев java.lang.NoSuchMethodError перехватывается компилятором, но иногда это может происходить во время выполнения. Если эта ошибка возникает во время выполнения, единственной причиной может быть изменение в структуре класса, которое сделало ее несовместимой.
Лучшее объяснение: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
Я тоже столкнулся с этой ошибкой.
Моя проблема заключалась в том, что я изменил подпись метода, что-то вроде
void invest(Currency money){...}
в
void invest(Euro money){...}
Этот метод был вызван из контекста, аналогичного
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
Компилятор молчал в отношении предупреждений / ошибок, поскольку капитал - это как валюта, так и евро.
Проблема возникла из-за того, что я скомпилировал только класс, в котором был определен метод - Bank, но не класс, из которого вызывается метод, который содержит метод main ().
С этой проблемой вы можете столкнуться не слишком часто, так как чаще всего проект перестраивается вручную или действие «Построение» запускается автоматически, а не просто компилирует один измененный класс.
Мой вариант использования состоял в том, что я сгенерировал файл .jar, который должен был использоваться в качестве исправления, который не содержал класс App.class, поскольку он не был изменен. Это имело смысл для меня, чтобы не включать его, так как я сохранил базовый класс через наследование корня.
Дело в том, что когда вы компилируете класс, результирующий байт-код является статическим , другими словами, это жесткая ссылка .
Исходный дизассемблированный байт-код (сгенерированный с помощью инструмента javap) выглядит следующим образом:
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
После того, как ClassLoader загрузит новый скомпилированный Bank.class, он не найдет такой метод, он выглядит так, как если бы он был удален и не изменен, то есть названная ошибка.
Надеюсь это поможет.
NoSuchMethodError: Я потратил пару часов на исправление этой проблемы, наконец исправил ее, просто переименовав имя пакета, очистив и собрав ... Сначала попробуйте очистить сборку, если она не работает, попробуйте переименовать имя класса или имя пакета и очистить сборку. .это должно быть исправлено. Удачи.