Badam następujące kwestie java.lang.VerifyError
java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/report/DisplayReportServlet, method: getMonthData signature: (IILjava/util/Collection;Ljava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;Lorg/apache/struts/util/MessageRe˜̴Mt̴MÚw€mçw€mp:”MŒŒ
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
at java.lang.Class.getConstructor0(Class.java:2671)
Występuje po uruchomieniu serwera jboss, na którym wdrożony jest serwlet. Jest skompilowany z jdk-1.5.0_11 i próbowałem go ponownie skompilować z jdk-1.5.0_15 bez powodzenia. Oznacza to, że kompilacja działa poprawnie, ale po wdrożeniu występuje błąd java.lang.VerifyError.
Kiedy zmieniłem nazwę metody i otrzymałem następujący błąd:
java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/report/DisplayReportServlet, method: getMD signature: (IILjava/util/Collection;Lj ava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;Lorg/apache/struts/util/MessageResources ØÅN|ØÅNÚw€mçw€mX#ÖM|XÔM
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357
at java.lang.Class.getConstructor0(Class.java:2671)
at java.lang.Class.newInstance0(Class.java:321)
at java.lang.Class.newInstance(Class.java:303)
Widać, że wyświetlana jest większa część sygnatury metody.
Rzeczywisty podpis metody to
private PgasePdfTable getMonthData(int month, int year, Collection dayTypes,
Collection calendarDays,
HashMap bcSpecialDays,
Collection activityPeriods,
Locale locale, MessageResources resources) throws Exception {
Próbowałem już na to patrzeć javap
i to daje metodzie podpis taki, jaki powinien być.
Kiedy moi inni koledzy sprawdzają kod, kompilują go i wdrażają, mają ten sam problem. Gdy serwer kompilacji pobiera kod i wdraża go w środowiskach programistycznych lub testowych (HPUX), występuje ten sam błąd. Również automatyczna maszyna testująca z systemem Ubuntu pokazuje ten sam błąd podczas uruchamiania serwera.
Reszta aplikacji działa poprawnie, tylko jeden serwlet nie działa. Przydałyby się pomysły, gdzie szukać.
źródło
Odpowiedzi:
java.lang.VerifyError
może być wynikiem kompilacji z inną biblioteką niż w środowisku wykonawczym.Na przykład przydarzyło mi się to podczas próby uruchomienia programu skompilowanego z Xerces 1, ale Xerces 2 został znaleziony w ścieżce klas. Wymagane klasy (w
org.apache.*
przestrzeni nazw) zostały znalezione w czasie wykonywania, więc nieClassNotFoundException
zostało to wynik. Wprowadzono zmiany w klasach i metodach, tak że podpisy metod znalezione w środowisku wykonawczym nie zgadzały się z tym, co było w czasie kompilacji.Zwykle kompilator oznaczy problemy, w których sygnatury metod nie są zgodne. JVM ponownie zweryfikuje kod bajtowy, gdy klasa zostanie załadowana, i zgłasza,
VerifyError
gdy kod bajtowy próbuje zrobić coś, co nie powinno być dozwolone - np. Wywołuje metodę, która zwraca,String
a następnie przechowuje tę zwracaną wartość w polu zawierającymList
.źródło
-verbose:class
a następnie poszukaj klasy tuż przed jej załadowaniemjava.lang.VerifyError
. Będzie to miało ścieżkę do pliku JAR. Użyjjavap
i porównaj to z klasą, z którą się kompilujesz. Uznałem to za przydatne, ponieważ klasa zgłoszona w błędzie nie była przyczyną, ponieważ był to jeden z argumentów.java.lang.VerifyError
są najgorsze.Ten błąd wystąpiłby, gdyby rozmiar kodu bajtowego metody przekraczał limit 64 kb; ale pewnie byście to zauważyli.
Czy jesteś w 100% pewien, że ta klasa nie jest obecna w ścieżce klas w innym miejscu twojej aplikacji, może w innym słoju?
Ponadto z twojego stacktrace jest kodowanie znaków w pliku źródłowym (
utf-8
?) Czy to prawda?źródło
Jak powiedział Kevin Panko, dzieje się tak głównie ze względu na zmiany w bibliotece. Tak więc w niektórych przypadkach „czyste” projektu (katalogu), a następnie kompilacja załatwia sprawę.
źródło
Jedną z rzeczy, które możesz wypróbować, jest
-Xverify:all
sprawdzenie kodu bajtowego przy ładowaniu, a czasem wyświetla pomocne komunikaty o błędach, jeśli kod bajtowy jest nieprawidłowy.źródło
Naprawiłem ten błąd na Androidzie, tworząc projekt, który importowałem bibliotekę, jak opisano tutaj http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject
Wcześniej po prostu odwoływałem się do projektu (nie robiłem z niego biblioteki) i otrzymywałem ten dziwny błąd VerifyError.
Mam nadzieję, że to komuś pomoże.
źródło
VerifyError oznacza, że plik klasy zawiera kod bajtowy, który jest poprawny składniowo, ale narusza pewne ograniczenia semantyczne, np. Cel skoku przekraczający granice metody.
Zasadniczo błąd VerifyError może wystąpić tylko wtedy, gdy wystąpi błąd kompilatora lub gdy plik klasy zostanie uszkodzony w inny sposób (np. Z powodu wadliwej pamięci RAM lub awarii HD).
Spróbuj skompilować z inną wersją JDK i na innym komputerze.
źródło
W moim przypadku mój projekt na Androida zależy od innego projektu Java skompilowanego dla Java 7.
java.lang.VerifyError
zniknął po zmianie poziomu zgodności kompilatora tego projektu Java na 6.0Później dowiedziałem się, że jest to problem Dalvik: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE
źródło
Dostawałem ten problem z powodu manglowania pliku klasy przez pack200. Trochę poszukiwań podniosło ten błąd java . Zasadniczo ustawienie
--effort=4
spowodowało, że problem zniknął.Używam java 1.5.0_17 (chociaż pojawił się w każdym wariancie java 1.5, w którym go wypróbowałem).
źródło
Rozwiązałem podobny problem java.lang.VerifyError, zastępując go
z
gdzie
MagickException
został zdefiniowany w projekcie bibliotecznym (od którego mój projekt jest zależny).Po tym mam
java.lang.NoClassDefFoundError
około klasy z tej samej biblioteki (naprawione zgodnie z https://stackoverflow.com/a/9898820/755804 ).źródło
Może się to zdarzyć na Androidzie, gdy próbujesz załadować bibliotekę skompilowaną z JDK Oracle.
Oto problem dla klienta HTTP Ning Async.
źródło
W moim przypadku musiałem usunąć ten blok:
Pokazuje błąd w pobliżu
Fragment.showDialog()
wywołania metody.źródło
Minimalny przykład generujący błąd
Jedną z prostych możliwości jest użycie Jasmin lub ręczna edycja kodu bajtowego za pomocą edytora plików binarnych.
Pozwala utworzyć
void
metodę bezreturn
instrukcji (wygenerowanej przezreturn;
instrukcję w Javie), która według JVMS jest nielegalna.W Jasmin możemy napisać:
Następnie robimy
javac Main.j
ijavap -v Main
mówimy, że skompilowaliśmy:tak naprawdę nie ma instrukcji powrotu.
Teraz, gdy spróbujemy uruchomić
java Main
, otrzymamy:Ten błąd nie może się zdarzyć w Javie normalnie, ponieważ kompilator Javy dodaje niejawna
return
dovoid
metod nas. Dlatego nie musimy dodawać areturn
do naszychmain
metod. Możesz to sprawdzić za pomocąjavap
.JVMS
Błąd VerifyError występuje, gdy próbujesz uruchomić niektóre typy nielegalnych plików klas, jak określono w JVMS 7 rozdział 4.5
JVMS mówi, że gdy Java ładuje plik, musi uruchomić serię kontroli, aby sprawdzić, czy plik klasy jest w porządku przed uruchomieniem.
Takie błędy nie mogą zostać wygenerowane w jednym cyklu kompilacji i uruchomienia kodu Java, ponieważ JVMS 7 4.10 mówi :
Aby zobaczyć przykład minimalnej awarii, będziemy musieli wygenerować kod źródłowy bez
javac
.źródło
Ta strona może dać ci kilka wskazówek - http://www.zanthan.com/itymbi/archives/000337.html
W tej metodzie może być subtelny błąd, którego javac nie wykryje. Trudno zdiagnozować, chyba że opublikujesz tutaj całą metodę.
Możesz zacząć od zadeklarowania jak największej liczby zmiennych, jak to tylko możliwe ..., które wychwyciłyby błąd wymieniony na stronie zanthan i często jest dobrą praktyką.
źródło
Cóż, w moim przypadku mój projekt A był zależny od innego, powiedzmy X (A używał niektórych klas zdefiniowanych w X). Więc kiedy dodałem X jako projekt referencyjny na ścieżce kompilacji A, dostałem ten błąd. Jednak gdy usunąłem X jako projekt, do którego się odwołałem, i umieściłem słoik X jako jedną z bibliotek, problem został rozwiązany.
źródło
Sprawdź, czy w ścieżce klasy znajduje się wiele wersji tego samego pliku jar.
Na przykład miałem ścieżkę opennlp-tools-1.3.0.jar i opennlp-tools-1.5.3.jar na mojej ścieżce klasy i otrzymałem ten błąd. Rozwiązaniem było usunięcie opennlp-tools-1.3.0.jar.
źródło
CGLIB <2.2 z JRE> 6 może powodować podobne błędy, patrz „Czy powinienem dokonać aktualizacji do CGLIB 3.0?” oraz komentarz na Spring SPR-9669 .
Jest to szczególnie prawdziwe, gdy wszystko działa dobrze w JRE 6 i po prostu przejście na JRE7 psuje wszystko.
źródło
Innym powodem tego błędu może być kombinacja AspectJ <= 1.6.11 z JRE> 6.
Zobacz Eclipse Bug 353467 i bilet Kieker 307 .
Jest to szczególnie prawdziwe, gdy wszystko działa poprawnie w JRE 6, a przejście do JRE7 psuje wszystko.
źródło
Może się to również zdarzyć, gdy masz wiele importów modułów za pomocą maven. Będą dwie lub więcej klas o dokładnie takiej samej nazwie (ta sama nazwa kwalifikowana). Ten błąd wynika z różnicy interpretacji czasu kompilacji i czasu wykonywania.
źródło
Jeśli przeprowadzasz migrację do java7 lub używasz java7, ogólnie można zauważyć ten błąd. Napotkałem powyższe błędy i bardzo się starałem, aby znaleźć podstawową przyczynę. Sugerowałbym, aby spróbować dodać argument JVM „-XX: -UseSplitVerifier” podczas uruchamiania aplikacji.
źródło
Po aktualizacji
Gradle
w Android Studio 3.6.1 doszło do awarii API 19 w kompilacji wydania.Wystąpił błąd
Glide
biblioteki . Rozwiązaniem jest przepisanie proguard-rules.txt .Również obniżenie
Gradle
działa (classpath 'com.android.tools.build:gradle:3.5.3'
), ale jest to przestarzałe rozwiązanie, nie używaj go.źródło
Chociaż powód wspomniany przez Kevina jest poprawny, ale zdecydowanie przejdę poniżej, zanim przejdę do czegoś innego:
cglibs
moją ścieżkę klasy.hibernate
wersje w mojej ścieżce klasy.Są duże szanse, że posiadanie wielu lub sprzecznych wersji któregokolwiek z powyższych może powodować nieoczekiwane problemy, takie jak ten, o którym mowa.
źródło
java.lang.VerifyError oznacza, że skompilowany kod bajtowy odnosi się do czegoś, czego Android nie może znaleźć. Ten błąd VerError wystawia mi tylko KitKat4.4 i mniejszą wersję, ale nie w powyższej wersji , nawet jeśli uruchomiłem tę samą kompilację na obu urządzeniach. kiedy użyłem parsera json json ze starszej wersji, pokazuje java.lang.verifyerror
Następnie zmieniłem Zależność na najnowszą wersję 2.2 na 2.7 bez biblioteki podstawowej , a następnie działa. co oznacza, że Metody i inna zawartość rdzenia jest migrowana do najnowszej wersji Databind2.7 . To rozwiązuje moje problemy.
źródło
usuń niepotrzebny plik jar i spróbuj uruchomić. i jego praca dla mnie dodałem plik jar jcommons, a także inny plik jar jcommons.1.0.14, więc usuń jcommons i działa dla mnie
źródło
zapisz w pliku:
w zależności następnie:
<module name="sun.jdk"/>
źródło
W moim przypadku otrzymywałem błąd weryfikacji ze śledzeniem poniżej stosu
Rozwiązałem problem poprzez usunięcie wpisu ścieżki klas dla commons-codec-1.3.jar, wystąpiła niezgodność wersji tego słoika z tym, który jest dostarczany z Jasperem.
źródło