Príčiny a vyhýbanie sa java.lang.VerifyError

1. Úvod

V tomto návode sa pozrieme na príčinu java.lang.VerifyError chyby a rôzne spôsoby, ako sa tomu vyhnúť.

2. Príčina

The Java Virtual Machine (JVM) nedôveruje všetkým načítaným bajtkódom ako jadru princípu bezpečnostného modelu Java. Počas behu sa JVM načíta .trieda súbory a pokúsiť sa ich navzájom spojiť, aby vytvorili spustiteľný súbor - ale platnosť týchto súborov bola načítaná .trieda súbory nie sú známe.

Aby sa zabezpečilo, že naložené .trieda súbory nepredstavujú hrozbu pre konečný spustiteľný súbor, JVM vykoná overenie na .trieda súbory. Okrem toho JVM zaisťuje, aby boli binárne súbory správne tvarované. Napríklad JVM overí, či triedy nepodtypujú konečné triedy.

V mnohých prípadoch overenie zlyhá kvôli platnému nezávadnému bajtkódu, pretože novšia verzia Java má prísnejší proces overovania ako staršie verzie. Napríklad JDK 13 možno pridal krok overenia, ktorý nebol vynútený v JDK 7. Ak teda spustíme aplikáciu s JVM 13 a zahrnieme závislosti skompilované so staršou verziou kompilátora Java (javac), môže JVM zvážiť zastarané závislosti sú neplatné.

Teda pri prepájaní starších .trieda súbory s novším JVM, JVM môže hodiť a java.lang.VerifyError podobné tomuto:

java.lang.VerifyError: Očakáva sa rámec stackmap na cieľ pobočky X Podrobnosti o výnimke: Umiestnenie: com / example / baeldung.Foo (Lcom / example / baeldung / Bar: Baz;) Lcom / example / baeldung / Foo; @ 1: infonull Dôvod: Očakávaný rámec stackmap na tomto mieste. Bytecode: 0000000: 0001 0002 0003 0004 0005 0006 0007 0008 0000010: 0001 0002 0003 0004 0005 0006 0007 0008 ...

Existujú dva spôsoby riešenia tohto problému:

  • Aktualizujte závislosti na verzie skompilované s aktualizovaným javac
  • Zakázať overenie Java

3. Výrobné riešenie

Najbežnejšou príčinou chyby pri overovaní je prepojenie binárnych súborov pomocou novšej verzie JVM skompilovanej so staršou verziou javac. Toto je bežnejšie, keď závislosti majú bytecode generovaný nástrojmi ako Javassist, ktoré mohli vygenerovať zastaraný bytecode, ak je nástroj zastaraný.

Ak chcete vyriešiť tento problém, aktualizovať závislosti na averzia vytvorená pomocou verzie JDK, ktorá sa zhoduje s verziou JDK použitou na zostavenie aplikácie. Napríklad, ak zostavujeme aplikáciu pomocou JDK 13, závislosti by sa mali vytvárať pomocou JDK 13.

Kompatibilnú verziu nájdete, keď skontrolujete Build-Jdk v súbore manifestu JAR závislosti, aby sa zabezpečilo, že sa zhoduje s verziou JDK použitou na zostavenie aplikácie.

4. Riešenie ladenia a vývoja

Pri ladení alebo vývoji aplikácie môžeme deaktivovať overenie ako rýchlu opravu.

Toto riešenie nepoužívajte na produkčný kód.

Zakázaním overenia môže server JVM prepojiť škodlivý alebo chybný kód s našimi aplikáciami, čo pri jeho vykonaní spôsobí bezpečnostné kompromisy alebo zlyhania.

Upozorňujeme tiež, že od verzie JDK 13 je toto riešenie zastarané a nemali by sme očakávať, že toto riešenie bude fungovať v budúcich vydaniach Java. Zakázanie overenia bude mať za následok nasledujúce varovanie:

Varovanie 64-bitového servera Java HotSpot (TM) na serveri: Možnosti -Xverify: v JDK 13 sa nepodporili žiadne a -noverify a pravdepodobne budú v budúcom vydaní odstránené.

Mechanizmus zakázania overenia bytecode sa líši v závislosti od toho, ako spustíme náš kód.

4.1. Príkazový riadok

Ak chcete zakázať overovanie na príkazovom riadku, odovzdajte znak noverifikovať vlajka k java príkaz:

java - oceniť Foo.class

Poznač si to -zmeniť je skratka pre-Xverify: žiadny a obidve možno zameniť.

4.2. Maven

Ak chcete zakázať overenie v zostave Maven, odovzdajte znak noverifikovať nahlásiť ľubovoľný požadovaný doplnok:

 com.example.baeldung priklad-plugin -obnovit 

4.3. Gradle

Ak chcete zakázať overenie v zostave Gradle, odovzdajte znak noverifikovať príznak na požadovanú úlohu:

someTask {// ... jvmArgs = jvmArgs << "-noverify"}

5. Záver

V tomto rýchlom výučbe sme sa dozvedeli, prečo JVM vykonáva overenie bytecode a čo spôsobuje java.lang.VerifyError chyba. Preskúmali sme tiež dve riešenia: výrobné a nevýrobné.

Ak je to možné, používať najnovšie verzie závislostí namiesto deaktivácie overenia.


$config[zx-auto] not found$config[zx-overlay] not found