NoSuchMethodError
Podczas uruchamiania programu Java pojawia się błąd. Co jest nie tak i jak to naprawić?
NoSuchMethodError
Podczas uruchamiania programu Java pojawia się błąd. Co jest nie tak i jak to naprawić?
Odpowiedzi:
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.
Caused by
sekcję w
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”.
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.
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]
...
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.
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.
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 getDeclaredMethod
wywoł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 TestUtilities
klasy 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).
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
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)
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.
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
.
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,
Oczyszczono i zbudowano projekt w eclpise
mvn clean install
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
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.
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 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+U
lub 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.
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.
W moim przypadku miałem projekt wielomodułowy i scenariusz był taki jak com.xyz.TestClass
w module, A
a także w module B
i moduł A
był 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/
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.
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.
Employee.java
-> Zawiera zmienną ( EmpId
), której typ danych został zmieniony z int
na String
.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.java
Byłem w tym tylko Employee.class
w pliku jar. Musiałem umieścić ReportGeneration.class
plik w słoiku, aby rozwiązać problem.
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)]
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
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.
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
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.
Jeśli nazwa twojego pliku jest inna niż nazwa klasy, która zawiera metodę główną, może to być przyczyną tego błędu.