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


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

24 116

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.рамки.Утверждение из файла:/C:/Program%20Files/junit3.8.2 / junit.опарник]

...

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

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

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

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

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

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

Если вы пишете веб-приложение, убедитесь, что у вас нет конфликтующих версий 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 здесь-шлюз.банку)

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

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

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

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

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

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

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

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

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

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. Я должен был включить в банке, чтобы решить эту проблему.

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

DISP_E_EXCEPTION [step] [] [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 ().

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

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

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

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

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

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

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

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

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

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

после переименования теста в правильное имя " ProjectionTest.Ява" в исключение ушло.

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

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

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

  2. mvn clean install

  3. перезапустить сервер Tomcat

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

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