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

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

24 ответов


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

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

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


Я чувствую твою боль. Вы можете изучить программирование из книги, но когда дело доходит до работы с Eclipse или Visual Studio, его a ^&^& - Н-кошмар сделать что-то простое, как добавить библиотеку. Все ожидают, что вы знаете, как его использовать, и если вы этого не сделаете, они понизят ваш вопрос. Проблема в том, что если вы не работаете в офисе или не знаете никого, кому Вы можете задать эти вопросы, то это почти невозможно понять. В любом случае...

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

Если кто-нибудь знает более правильный способ добавления/обновления библиотеки, пожалуйста, перезвоните.

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

enter image description here

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

enter image description here

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

enter image description here


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


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

java -verbose:class <other args>

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

...

[загружен junit.рамки.Assert from file:/C:/Program%20Files / junit3.8.2 / junit.опарник]

...


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

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


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

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

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


Если вы используете maven или другой фреймворк, и вы получаете эту ошибку случайным образом, попробуйте "clean install", особенно если вы написали объект, и вы знаете, что у него есть метод. Работать на меня.


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

например

  • tomcat / common / lib
  • mywebapp/WEB-INF / lib

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

ex:

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 здесь шлюз.jar)


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

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

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


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


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

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


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


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


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

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

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

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

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


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

DISP_E_EXCEPTION [шаг] [] [Z-JAVA-105 исключение Java Ява.ленг.NoSuchMethodError (com.образец.yourmethod)]


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

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

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

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

большую часть времени java.ленг.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 ().

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

мой usecase был, что я создал .файл jar, который должен был использоваться в качестве исправления, не содержащий приложения.класс as this не был изменен. Это имело смысл для меня не включите его, поскольку я сохранил базовый класс начального аргумента через наследование.

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

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

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

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

надеюсь, что это помогает.


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

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

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

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


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


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

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

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

  3. перезапущен tomcat

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


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