Jak naprawić błąd NoSuchMethodError?


178

NoSuchMethodErrorPodczas uruchamiania programu Java pojawia się błąd. Co jest nie tak i jak to naprawić?


11
W Netbeans: Kliknij prawym przyciskiem myszy projekt w zakładce Projekty, użyj "Wyczyść i zbuduj". Rozwiązałem to dla mnie.
Heinzlmaen

3
Również w Intellij Idea przebudowa czasami rozwiązuje problem
Jastrząb

1
Ten artykuł jest bardzo pomocny w tym problemie reflectoring.io/nosuchmethod
Michael Smith

Odpowiedzi:


228

Bez dodatkowych informacji trudno jest określić problem, ale główną przyczyną jest to, że najprawdopodobniej skompilowałeś klasę z inną wersją klasy, w której brakuje metody, niż ta, której używasz podczas jej uruchamiania.

Spójrz na ślad stosu ... Jeśli wyjątek pojawia się podczas wywoływania metody na obiekcie w bibliotece, najprawdopodobniej korzystasz z oddzielnych wersji biblioteki podczas kompilowania i uruchamiania. Upewnij się, że masz odpowiednią wersję w obu miejscach.

Jeśli wyjątek pojawia się podczas wywoływania metody na obiektach utworzonych przez utworzone przez Ciebie klasy , oznacza to, że proces kompilacji wydaje się być wadliwy. Upewnij się, że pliki klas, które faktycznie uruchamiasz, są aktualizowane podczas kompilacji.


3
Niedawno odkryliśmy przyczynę jednego z nich i okazało się, że proces budowania polegał na umieszczaniu plików klas na miejscu przed zamknięciem serwera java. Udało nam się to, ponieważ serwer java nie załadował niektórych klas, a następnie załadował się niektóre ale dostał te nowe, a ponieważ nowy kod odnosił się do metod, których nie miały stare klasy ... bingo, NoSuchMethodError
vazor

„Spójrz na ślad stosu…” - Cóż, prawie zawsze sprawdzam ostatnią Caused bysekcję w
raporcie

108

Miałem twój problem i tak go naprawiłem. Poniższe kroki stanowią roboczy sposób dodawania biblioteki. Pierwsze dwa kroki wykonałem poprawnie, ale nie wykonałem ostatniego, przeciągając plik „.jar” bezpośrednio z systemu plików do folderu „lib” w moim projekcie eclipse. Dodatkowo musiałem usunąć poprzednią wersję biblioteki zarówno ze ścieżki budowania, jak iz folderu „lib”.

Krok 1 - Dodaj .jar do ścieżki budowania

wprowadź opis obrazu tutaj

Krok 2 - Powiązane źródła i javadocs (opcjonalnie)

wprowadź opis obrazu tutaj

Krok 3 - Właściwie przeciągnij plik .jar do folderu „lib” (nie opcjonalne)

wprowadź opis obrazu tutaj


75
+1 za „Wszyscy oczekują, że umiesz go używać, a jeśli tego nie zrobisz, odrzucą Twoje pytanie”.
Vikram

73

Zwróć uwagę, że w przypadku odbicia otrzymujesz NoSuchMethodException, podczas gdy z nieodblaskowym kodem otrzymujesz NoSuchMethodError. Mam tendencję do szukania w bardzo różnych miejscach, kiedy konfrontuje się jedno z drugim.


Innymi słowy, mówisz, że jeśli używasz odbicia w celu pobrania metody dla klasy, a metoda nie zostanie znaleziona, otrzymasz NoSuchMethodException. Ale jeśli jesteś w scenariuszu, w którym kompilowałeś swój kod dla niektórych bibliotek, a na serwerze masz inne biblioteki (może nowsze, może starsze), otrzymasz NoSuchMethodError. Popraw mnie, jeśli się mylę.
Victor

Zgadza się, @Victor
KrishPrabakar

51

Jeśli masz dostęp do zmiany parametrów maszyny JVM, dodanie szczegółowych danych wyjściowych powinno umożliwić sprawdzenie, jakie klasy są ładowane z których plików JAR.

java -verbose:class <other args>

Po uruchomieniu programu JVM powinna zrzucić do standardowych informacji, takich jak:

...

[Załadowano junit.framework.Assert z pliku: / C: /Program%20Files/junit3.8.2/junit.jar]

...


3
+1 Genialny! Dzięki tej metodzie rozwiązałem mały, nieprzyjemny problem. To doskonały sposób, aby dowiedzieć się, kiedy klasy w jakiś sposób przedarły się na ścieżkę klas.
Duncan Jones

1
+1 Uratowałeś mój dzień! Była to tylko jedna biblioteka, która zawierała w swoich źródłach stare klasy o takich samych nazwach.
Andrii Nemchenko

12

Jest to zwykle spowodowane korzystaniem z systemu kompilacji, takiego jak Apache Ant, który kompiluje pliki java tylko wtedy, gdy plik java jest nowszy niż plik klasy. Jeśli sygnatura metody ulegnie zmianie, a klasy używały starej wersji, to może się nie udać skompilować. Zwykłą poprawką jest wykonanie pełnej przebudowy (zwykle „ant clean”, a następnie „ant”).

Czasami może to być również spowodowane kompilacją z jedną wersją biblioteki, ale uruchomioną na innej wersji.


1
W rzeczywistości wydaje się to bardziej problemem, który pojawia się u programistów Java, którzy używają dowolnego środowiska programistycznego Java: Maven, NetBeans i Apache Ant, jak widać na podstawie wszystkich odpowiedzi tutaj.
HoldOffHunger

8

Jeśli używasz Maven lub innego frameworka i otrzymujesz ten błąd prawie losowo, spróbuj czystej instalacji, takiej jak ...

clean install

Jest to szczególnie prawdopodobne, jeśli napisałeś obiekt i wiesz, że ma metodę. Pracował dla mnie.


Dotyczy to również kompilacji Gradle.
Jonathan Landrum

4

Może to również wynikać z zastosowania refleksji. Jeśli masz kod, który odzwierciedla klasę i wyodrębnia metodę według nazwy (np .: with Class.getDeclaredMethod("someMethodName", .....)), to za każdym razem, gdy nazwa metody ulegnie zmianie, na przykład podczas refaktoryzacji, będziesz musiał pamiętać o zaktualizowaniu parametrów do metody odbicia, aby pasowały do nowa sygnatura metody lub getDeclaredMethodwywołanie wyrzuci plik NoSuchMethodException.

Jeśli jest to powód, ślad stosu powinien wskazywać punkt wywołania metody odbicia, a wystarczy zaktualizować parametry, aby pasowały do ​​rzeczywistej sygnatury metody.

Z mojego doświadczenia wynika, że ​​pojawia się to czasami, gdy testujemy jednostki prywatne metody / pola i używam TestUtilitiesklasy do wyodrębniania pól w celu weryfikacji testów. (Zwykle w przypadku starszego kodu, który nie został zaprojektowany z myślą o testach jednostkowych).


3

Jeśli piszesz aplikację internetową, upewnij się, że nie masz sprzecznych wersji pliku jar w globalnym katalogu biblioteki kontenera, a także w aplikacji. Możesz nie wiedzieć, który plik jar jest używany przez program ładujący klasy.

na przykład

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

2

Te problemy są spowodowane użyciem tego samego obiektu w tych samych dwóch klasach. Używane obiekty nie zawierają nowej metody, którą zawiera nowa klasa obiektów.

dawny:

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$ 

Te problemy są spowodowane przez współistniejącą podobną klasę 02 (1 w src, 1 w pliku jar tutaj to gateway.jar)


2

Oznacza to, że w klasie nie ma odpowiedniej metody:

  1. Jeśli używasz jar, zdekompiluj i sprawdź, czy odpowiednia wersja jar ma odpowiednią klasę.
  2. Sprawdź, czy skompilowałeś odpowiednią klasę ze swojego źródła.

2

U mnie stało się tak, ponieważ zmieniłem typ argumentu w funkcji z Object a na String a. Mogłem to rozwiązać za pomocą czyszczenia i budowania ponownie


2

Właśnie rozwiązałem ten błąd, ponownie uruchamiając Eclipse i uruchamiając aplikację. Przyczyną mojego przypadku może być zastąpienie plików źródłowych bez zamykania projektu lub Eclipse. Co spowodowało inną wersję zajęć, z których korzystałem.


2

Spróbuj w ten sposób: usuń wszystkie pliki .class w katalogach twojego projektu (i oczywiście wszystkie podkatalogi). Odbudować.

Czasami mvn clean(jeśli używasz maven) nie czyści plików .class ręcznie utworzonych przez javac. A te stare pliki zawierają stare podpisy, prowadzące do NoSuchMethodError.


2

Po prostu dodając do istniejących odpowiedzi. Miałem do czynienia z tym problemem z kocurem w zaćmieniu. Zmieniłem jedną klasę i wykonałem następujące kroki,

  1. Oczyszczono i zbudowano projekt w eclpise

  2. mvn clean install

  3. Zrestartowałem kocur

Nadal miałem ten sam błąd. Następnie wyczyściłem tomcat, wyczyściłem katalog roboczy tomcat i zrestartowałem serwer i mój problem zniknął. Mam nadzieję, że to komuś pomoże


1

Aby odpowiedzieć na pierwotne pytanie. Według dokumentów java tutaj :

„NoSuchMethodError” Zgłaszane, jeśli aplikacja próbuje wywołać określoną metodę klasy (statyczną lub instancję), a ta klasa nie ma już definicji tej metody.

Zwykle ten błąd jest wychwytywany przez kompilator; ten błąd może wystąpić w czasie wykonywania tylko wtedy, gdy definicja klasy uległa zmianie w sposób niezgodny.

  1. Jeśli tak się dzieje w czasie wykonywania, sprawdź, czy klasa zawierająca metodę znajduje się w ścieżce klasy.
  2. Sprawdź, czy dodałeś nową wersję JAR i metoda jest kompatybilna.

1

Naprawiłem ten problem w Eclipse, zmieniając nazwę pliku testowego Junit.
W mojej przestrzeni roboczej Eclipse mam projekt aplikacji i projekt testowy.
Projekt testowy ma projekt aplikacji jako wymagany projekt w ścieżce kompilacji.

Rozpoczęto pobieranie NoSuchMethodError.
Potem zdałem sobie sprawę, że klasa w projekcie testowym ma taką samą nazwę jak klasa w projekcie aplikacji.

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

Po zmianie nazwy testu na poprawną nazwę „ProjectionTest.java” wyjątek zniknął.


Miałem podobny problem. Miałem klasę zależności o tej samej pełnej nazwie kanonicznej. Po zmianie nazwy wyjątek zniknął.
moralejaSinCuentoNiProverbio

1

Miałem ten sam błąd:

  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)

Aby go rozwiązać, najpierw sprawdziłem Diagram zależności modułów ( click in your POM the combination -> Ctrl+Alt+Shift+Ulub right click in your POM -> Maven -> Show dependencies), aby zrozumieć, gdzie dokładnie był konflikt między bibliotekami (Intelij IDEA). W moim przypadku miałem różne wersje zależności Jacksona.

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

1) Czyli dodałem bezpośrednio w moim POM projektu jednoznacznie najwyższą wersję - 2.8.7 z tych dwóch.

W nieruchomościach:

<jackson.version>2.8.7</jackson.version>

I jako zależność:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

2) Ale można to również rozwiązać za pomocą wykluczeń zależności .

Na tej samej zasadzie, co w przykładzie poniżej:

  <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>

Zależność od niechcianej wersji zostanie wykluczona z twojego projektu.


1

W moim przypadku miałem projekt wielomodułowy i scenariusz był taki jak com.xyz.TestClassw module, Aa także w module Bi moduł Abył zależny od modułu B. Więc podczas tworzenia pliku asemblera myślę, że tylko jedna wersja klasy została zachowana, jeśli nie ma wywoływanej metody, wtedy otrzymywałemNoSuchMethodError wyjątek runtime, ale kompilacja była w porządku.

Powiązane: https://reflectoring.io/nosuchmethod/


0

Podobny problem napotkałem podczas zmiany sygnatur metod w mojej aplikacji. Po wyczyszczeniu i odbudowaniu mojego projektu rozwiązano problem „NoSuchMethodError”.


0

Powyższa odpowiedź wyjaśnia bardzo dobrze ... wystarczy dodać jedną rzecz Jeśli używasz eclipse użyj ctrl + shift + T i wprowadź strukturę pakietu klasy (np: gateway.smpp.PDUEventListener), znajdziesz wszystkie jars / projekty, w których jest obecny . Usuń niepotrzebne pliki słoików ze ścieżki klas lub dodaj powyżej w ścieżce klas. Teraz wybierze właściwy.


0

Wpadłem na podobny problem.

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

W końcu zidentyfikowałem podstawową przyczynę zmiany typu danych zmiennej.

  1. Employee.java-> Zawiera zmienną ( EmpId), której typ danych został zmieniony z intna String.
  2. ReportGeneration.java-> Pobiera wartość przy użyciu getter, getEmpId().

Powinniśmy uzupełnić słoik, uwzględniając tylko zmodyfikowane klasy. Ponieważ nie było żadnej zmiany w ReportGeneration.javaByłem w tym tylko Employee.classw pliku jar. Musiałem umieścić ReportGeneration.classplik w słoiku, aby rozwiązać problem.


0

Miałem ten sam problem. Dzieje się tak również wtedy, gdy w klasach występuje niejednoznaczność. Mój program próbował wywołać metodę, która była obecna w dwóch plikach JAR znajdujących się w tej samej lokalizacji / ścieżce klasy. Usuń jeden plik JAR lub wykonaj kod tak, aby używany był tylko jeden plik JAR. Sprawdź, czy nie używasz tego samego pliku JAR lub różnych wersji tego samego pliku JAR, które zawierają tę samą klasę.

DISP_E_EXCEPTION [krok] [] [Z-JAVA-105 wyjątek Java java.lang.NoSuchMethodError (com.example.yourmethod)]


0

W większości przypadków java.lang.NoSuchMethodError jest przechwytywany przez kompilator, ale czasami może się to zdarzyć w czasie wykonywania. Jeśli ten błąd wystąpi w czasie wykonywania, jedynym powodem może być zmiana struktury klasy, która spowodowała, że ​​była ona niekompatybilna.

Najlepsze wyjaśnienie: https://www.journaldev.com/14538/java-lang-nosuchmethoderror


0

Napotkałem również ten błąd.

Mój problem polegał na tym, że zmieniłem sygnaturę metody, na przykład

void invest(Currency money){...}

w

void invest(Euro money){...}

Ta metoda została wywołana z kontekstu podobnego do

public static void main(String args[]) {
    Bank myBank = new Bank();

    Euro capital = new Euro();
    myBank.invest(capital);
}

Kompilator milczał na temat ostrzeżeń / błędów, ponieważ kapitał jest zarówno walutą, jak i euro.

Problem wynikał z tego, że skompilowałem tylko klasę, w której została zdefiniowana metoda - Bank, a nie klasę, z której wywoływana jest metoda, która zawiera metodę main ().

Ten problem nie jest czymś, co możesz napotkać zbyt często, ponieważ najczęściej projekt jest odbudowywany ręcznie lub akcja kompilacji jest wyzwalana automatycznie, zamiast tylko kompilować jedną zmodyfikowaną klasę.

Moim przypadkiem było to, że wygenerowałem plik .jar, który miał być użyty jako poprawka, który nie zawierał App.class, ponieważ nie został zmodyfikowany. Miałem sens dla mnie, aby go nie włączać, ponieważ zachowałem klasę bazową początkowego argumentu przez dziedziczenie.

Rzecz w tym, że kiedy kompilujesz klasę, wynikowy kod bajtowy jest trochę statyczny , innymi słowy, jest to twarde odniesienie .

Oryginalny zdemontowany kod bajtowy (wygenerowany za pomocą narzędzia javap) wygląda następująco:

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

Po załadowaniu przez ClassLoader nowo skompilowanego pliku Bank.class nie znajdzie takiej metody, wygląda na to, że została usunięta, a nie zmieniona, stąd nazwany błąd.

Mam nadzieję że to pomoże.


0

Problem w moim przypadku polegał na tym, że w ścieżce kompilacji znajdowały się dwie wersje tej samej biblioteki. Starsza wersja biblioteki nie miała tej funkcji, a nowsza tak.


0

Miałem podobny problem z moim projektem Gradle przy użyciu Intelij. Rozwiązałem to, usuwając pakiet .gradle (patrz zrzut ekranu poniżej) i przebudowując projekt. Pakiet .gradle


0

NoSuchMethodError: Spędziłem kilka godzin na naprawie tego problemu, w końcu naprawiłem go, zmieniając nazwę pakietu, wyczyść i zbuduj ... Najpierw wypróbuj czystą kompilację, jeśli nie działa, spróbuj zmienić nazwę klasy lub nazwę pakietu i wyczyść kompilację. . to powinno zostać naprawione. Powodzenia.


-2

Jeśli nazwa twojego pliku jest inna niż nazwa klasy, która zawiera metodę główną, może to być przyczyną tego błędu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.