Как исправить ошибку NoSuchMethodError?

Я получаю сообщение об ошибке NoSuchMethodError при запуске моей программы на Java. Что случилось и как мне это исправить?

В Netbeans: щелкните правой кнопкой мыши проект на вкладке «Проекты», используйте «Очистить и построить». Решил это за меня.

Heinzlmaen 20.01.2016 15:50

Также в Intellij Idea перестройка иногда решает проблему

Hawk 28.11.2018 16:57

Эта статья очень полезна для решения этой проблемы Refctoring.io/nosuchmethod

Michael Smith 22.07.2019 19:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
190
3
355 696
31
Перейти к ответу Данный вопрос помечен как решенный

Ответы 31

Обычно это происходит при использовании системы сборки, такой как Apache Ant, которая компилирует файлы Java, только если файл Java новее, чем файл класса. Если подпись метода изменилась и классы использовали старую версию, вещи могут быть скомпилированы некорректно. Обычное решение - выполнить полную перестройку (обычно «муравейник», затем «муравей»).

Иногда это также может быть вызвано компиляцией для одной версии библиотеки, но при работе с другой версией.

На самом деле, это больше похоже на проблему, которая возникает у Java-программистов, которые используют любую среду разработки Java: Maven, NetBeans и Apache Ant, как вы можете видеть из всех ответов здесь.

HoldOffHunger 17.03.2016 18:22
Ответ принят как подходящий

Без дополнительной информации трудно определить проблему, но основная причина заключается в том, что вы, скорее всего, скомпилировали класс для другой версии класса, в которой отсутствует метод, чем та, которую вы используете при его запуске.

Посмотрите на трассировку стека ... Если исключение возникает при вызове метода для объекта в библиотеке, вы, скорее всего, используете отдельные версии библиотеки при компиляции и запуске. Убедитесь, что у вас есть правильная версия в обоих местах.

Если исключение появляется при вызове метода для объектов, созданных классами ты made, то ваш процесс сборки кажется ошибочным. Убедитесь, что файлы классов, которые вы действительно выполняете, обновляются при компиляции.

Мы недавно обнаружили причину одного из них, и оказалось, что процесс сборки помещал файлы классов на место до того, как Java-сервер был выключен, и мы столкнулись с этим, потому что Java-сервер не загрузил некоторые классы, а затем он загрузился некоторые, но у него есть эти новые, и поскольку новый код ссылается на методы, которых не было в старых классах ... bingo, NoSuchMethodError

vazor 06.05.2015 19:30

«Посмотрите на трассировку стека ...» - Ну, я почти всегда хожу и проверяю последний раздел Caused by в трассировке стека, чтобы найти класс / банку виновника.

KrishPrabakar 14.07.2020 14:55

Это также может быть результатом использования отражения. Если у вас есть код, который отражает класс и извлекает метод по имени (например, с Class.getDeclaredMethod("someMethodName", .....)), тогда каждый раз, когда имя этого метода изменяется, например, во время рефакторинга, вам нужно будет не забыть обновить параметры метода отражения, чтобы они соответствовали подпись нового метода, или вызов getDeclaredMethod выдаст NoSuchMethodException.

Если это причина, то трассировка стека должна показать точку, в которой вызывается метод отражения, и вам просто нужно обновить параметры, чтобы они соответствовали фактической сигнатуре метода.

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

Обратите внимание, что в случае отражения вы получаете NoSuchMethodException, а с неотражающим кодом вы получаете NoSuchMethodError. Я обычно ищу в самых разных местах, когда сталкиваюсь с одним по сравнению с другим.

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

Victor 21.05.2020 11:32

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

например

  • кот / общий / библиотека
  • mywebapp / WEB-INF / lib

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

java -verbose:class <other args>

Когда ваша программа запущена, JVM должна выгружать стандартную информацию, такую ​​как:

...

[Loaded junit.framework.Assert from file:/C:/Program%20Files/junit3.8.2/junit.jar]

...

+1 Великолепно! Я решил небольшую неприятную проблему с помощью этого метода, спасибо. Это отличный способ обнаружить, когда классы каким-то образом прокрались на путь к классам.

Duncan Jones 15.10.2014 15:59

+1 Ты спас мне день! Это была всего лишь одна библиотека, которая включала в свои источники старые классы с такими же именами.

Andrii Nemchenko 08.08.2018 21:31

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

nenea 03.09.2020 14:44

У меня была твоя проблема, и вот как я ее исправил. Следующие шаги - рабочий способ добавления библиотеки. Я сделал первые два шага правильно, но я не сделал последнего, перетащив файл «.jar» прямо из файловой системы в папку «lib» в моем проекте eclipse. Кроме того, мне пришлось удалить предыдущую версию библиотеки как из пути сборки, так и из папки «lib».

Шаг 1 - Добавьте .jar для создания пути

Шаг 2. Свяжите источники и javadocs (необязательно)

Шаг 3 - Фактически перетащите файл .jar в папку "lib" (не обязательно)

+1 за «Все ожидают, что вы знаете, как его использовать, и если вы этого не сделаете, они проголосуют против вашего вопроса».

Vikram 20.06.2012 00:36

Чтобы ответить на исходный вопрос. Согласно java docs здесь:

"NoSuchMethodError" Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.

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

  1. Если это происходит во время выполнения, проверьте, что класс, содержащий метод, находится в пути к классам.
  2. Убедитесь, что вы добавили новую версию JAR и совместим ли метод.

Я столкнулся с аналогичной проблемой, когда менял сигнатуры методов в своем приложении. Очистка и восстановление моего проекта разрешили ошибку «NoSuchMethodError».

Если имя вашего файла отличается от имени класса, который содержит основной метод, возможно, эта ошибка может вызвать эту ошибку.

Нет, не будет. Это вызывает другую ошибку.

Stephen C 04.02.2021 17:39

Эти проблемы вызваны использованием одного и того же объекта в одних и тех же двух классах. Используемые объекты не содержат новый метод, который содержит новый класс объектов.

бывший:

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)

Если вы используете Maven или другой фреймворк, и вы получаете эту ошибку почти случайно, попробуйте чистую установку, например ...

clean install

Это особенно вероятно, если вы написали объект и знаете, что у него есть метод.

Это также относится к сборкам Gradle.

Jonathan Landrum 03.12.2019 22:45

У меня была такая же проблема. Это также вызвано неоднозначностью классов. Моя программа пыталась вызвать метод, который присутствовал в двух файлах JAR, находящихся в одном месте / пути к классу. Удалите один файл JAR или выполните свой код так, чтобы использовался только один файл JAR. Убедитесь, что вы не используете один и тот же JAR или разные версии одного и того же JAR, содержащие один и тот же класс.

DISP_E_EXCEPTION [step] [] [Z-JAVA-105 Java exception java.lang.NoSuchMethodError(com.example.yourmethod)]

Это означает, что соответствующий метод отсутствует в классе:

  1. Если вы используете jar, декомпилируйте и проверьте, имеет ли соответствующая версия jar правильный класс.
  2. Проверьте, правильно ли вы скомпилировали класс из исходного кода.

Приведенный выше ответ очень хорошо объясняет .. просто добавьте одну вещь Если вы используете eclipse, используйте ctrl + shift + T и введите структуру пакета класса (например, gateway.smpp.PDUEventListener), вы найдете все jar-файлы / проекты, в которых он присутствует. Удалите ненужные jar-файлы из пути к классам или добавьте выше в путь к классам. Теперь он подберет правильный.

Для меня это произошло потому, что я изменил тип аргумента в функции с Object a на String a. Я мог бы решить это с помощью очистки и снова построить

Я только что решил эту ошибку, перезапустив Eclipse и запустив приложение. Причина в моем случае может быть связана с тем, что я заменяю исходные файлы, не закрывая проект или Eclipse. Это вызвало разные версии классов, которые я использовал.

Я столкнулся с подобной проблемой.

Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I

Наконец, я определил основную причину изменения типа данных переменной.

  1. Employee.java -> Содержит переменную (EmpId), тип данных которой был изменен с int на String.
  2. ReportGeneration.java -> Получает значение с помощью геттера getEmpId().

Мы должны повторно собрать банку, включив только модифицированные классы. Поскольку в ReportGeneration.java не было изменений, я включил только Employee.class в файл Jar. Мне пришлось включить файл ReportGeneration.class в банку, чтобы решить проблему.

Most of the times java.lang.NoSuchMethodError is caught be compiler but sometimes it can occur at runtime. If this error occurs at runtime then the only reason could be the change in the class structure that made it incompatible.

Лучшее объяснение: https://www.journaldev.com/14538/java-lang-nosuchmethoderror

Попробуйте так: удалите все файлы .class из каталогов вашего проекта (и, конечно же, все подкаталоги). Восстановить.

Иногда mvn clean (если вы используете maven) не очищает файлы .class, созданные вручную javac. И эти старые файлы содержат старые подписи, ведущие к 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, он не найдет такой метод, он выглядит так, как если бы он был удален и не изменен, отсюда и названная ошибка.

Надеюсь это поможет.

Я исправил эту проблему в Eclipse, переименовав тестовый файл Junit. В моем рабочем пространстве Eclipse есть проект приложения и проект тестирования. Проект Test содержит проект приложения в качестве обязательного проекта на пути сборки.

Начато получение NoSuchMethodError.
Затем я понял, что класс в тестовом проекте имеет то же имя, что и класс в проекте приложения.

App/  
  src/
     com.example/  
       Projection.java
Test/  
  src/
     com.example/
       Projection.java

После переименования теста в правильное имя «ProjectionTest.java» исключение исчезло.

У меня была аналогичная проблема. У меня был класс зависимости с таким же полным каноническим именем. После переименования исключение ушло.

moralejaSinCuentoNiProverbio 08.11.2018 17:32

В моем случае проблема заключалась в наличии двух версий одной и той же библиотеки в пути сборки. В старой версии библиотеки этой функции не было, а в более новой.

Просто добавляю к существующим ответам. Я столкнулся с этой проблемой с котом в затмении. Я сменил один класс и сделал следующие шаги:

  1. Почистил и построил проект в эклиписе

  2. mvn чистая установка

  3. Перезапущенный кот

Тем не менее я столкнулся с той же ошибкой. Затем Я очистил tomcat, очистил рабочий каталог tomcat и перезапуск сервера, и моя проблема исчезла. Надеюсь, это кому-то поможет

У меня была аналогичная проблема с моим проектом Gradle с использованием Intelij. Я решил это, удалив пакет .gradle (см. Снимок экрана ниже) и перестроив проект. .gradle Пакет

NoSuchMethodError: Я потратил пару часов на исправление этой проблемы, наконец исправил ее, просто переименовав имя пакета, очистив и построив ... Сначала попробуйте чистую сборку, если она не работает, попробуйте переименовать имя класса или имя пакета и очистить сборку .. .это должно быть исправлено. Удачи.

У меня была такая же ошибка:

  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/

Спасибо, вы только что избавили меня от часов отладки!

Adam 08.11.2020 00:33

Один из таких случаев, когда возникает эта ошибка: Я совершил глупую ошибку, получив доступ к частным статическим переменным-членам нестатическим методом. Смена метода на статический решила проблему.

Я столкнулся с той же проблемой. Я изменил возвращаемый тип одного метода и запустил тестовый код этого одного класса. Именно тогда я столкнулся с этим NoSuchMethodError. В качестве решения я один раз запустил сборки maven для всего репозитория, прежде чем снова запустить тестовый код. Проблема была решена в следующем тестовом прогоне.

Почему никто не упоминает о конфликтах зависимостей? Эта общая проблема может быть связана с включенными jar-файлами зависимостей с разными версиями. Подробное объяснение и решение: https://dzone.com/articles/solving-dependency-conflicts-in-maven

Краткий ответ;

Добавьте эту зависимость maven;

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
    <rules>
        <dependencyConvergence />
    </rules>
</configuration>
</plugin>

Затем запустите эту команду;

mvn enforcer:enforce

Может быть, это причина вашей проблемы, с которой вы столкнулись.

Другие вопросы по теме