Как исправить NoSuchMethodError?

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

Ответ 1

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

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

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

Ответ 2

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

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

enter image description here

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

enter image description here

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

enter image description here

Ответ 3

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

Ответ 4

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

java -verbose:class <other args>

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

...

[Загружено junit.framework.Assert из файла:/C:/Program%20Files/junit3.8.2/junit.jar]

...

Ответ 5

Это обычно возникает при использовании системы сборки, например Apache Ant, которая компилирует только java файлы, когда java файл является более новым, чем класс файл. Если подписи метода изменяются, а классы используют старую версию, вещи не могут быть скомпилированы правильно. Обычным решением является полная перестройка (обычно "ant clean", затем "ant" ).

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

Ответ 6

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

clean install

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

Ответ 7

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

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

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

Ответ 8

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

например.

  • кот/общее/Библиотека
  • mywebapp/WEB-INF/Lib

Ответ 9

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

Пример:

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)

Ответ 10

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

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

Ответ 11

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

Ответ 12

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

Ответ 13

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

Иногда mvn clean (если вы используете maven) не очищает файлы.class, созданные вручную javac. И эти старые файлы содержат старые подписи, что приводит к NoSuchMethodError.

Ответ 14

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

  1. Убирали и строили проект в эклипсе

  2. mvn clean install

  3. Перезаряженный кот

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

Ответ 15

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

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

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

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

Ответ 16

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

"NoSuchMethodError" Брошено, если приложение пытается вызвать указанный метод класса (статический или экземпляр), и этот класс больше не имеет определения этого метода.

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

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

Ответ 17

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

Ответ 18

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

DISP_E_EXCEPTION [шаг] [] [Z-JAVA-105 Исключение Java java.lang.NoSuchMethodError(com.example.yourmethod)]

Ответ 19

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

Ответ 20

У меня возникла аналогичная проблема.

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

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

  • Employee.java → Содержит переменную (EmpId), тип данных которой изменен с int на String.
  • ReportGeneration.java → Извлекает значение, используя getter, getEmpId().

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

Ответ 21

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

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

Ответ 22

Я тоже столкнулся с этой ошибкой.

Моя проблема заключалась в том, что я изменил подпись метода, что-то вроде

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().

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

Мой usecase заключался в том, что я создал файл.jar, который должен был использоваться как исправление, которое не содержало App.class, поскольку это не было изменено. Мне было разумно не включать его, так как я сохранил исходный класс базового класса через наследование.

Дело в том, что когда вы компилируете класс, полученный байт-код является своего рода статичным, другими словами, он является жесткой ссылкой.

Оригинальный дизассемблированный байт-код (сгенерированный с помощью инструмента javap) выглядит так:

 #7 = Methodref          #2.#22         // Bank.invest:(LCurrency;)V

После того, как ClassLoader загружает новый скомпилированный Bank.class, он не найдет такого метода, он выглядит так, как будто он был удален и не изменен, таким образом, именованная ошибка.

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

Ответ 23

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

Ответ 24

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

Ответ 25

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

Ответ 26

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

  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). В моем конкретном случае у меня были разные версии зависимостей Джексона.

enter image description here enter image description here

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>

Зависимость от нежелательной версии будет исключена из вашего проекта.

Ответ 27

В моем случае у меня был многомодульный проект, и сценарий был похож на com.xyz.TestClass был в модуле A а также в модуле B и модуль A зависел от модуля B Поэтому при создании jar-сборки я думаю, что была сохранена только одна версия класса, если у нее нет вызванного метода, тогда я получал NoSuchMethodError времени выполнения NoSuchMethodError, но компиляция прошла хорошо.

Связанный: https://reflectoring.io/nosuchmethod/

Ответ 28

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