A java.lang.VerifyError okai és elkerülése

1. Bemutatkozás

Ebben az oktatóanyagban megvizsgáljuk az okát java.lang.VerifyError hibák és többféle módon elkerülhető.

2. Ok

A A Java virtuális gép (JVM) bizalmatlan az összes betöltött bájtkóddal szemben, mint a Java biztonsági modell alaptétele. Futás közben a JVM betöltődik .osztály fájlokat, és megpróbálja összekapcsolni őket egy futtatható fájl létrehozásával - de ezek érvényességét betöltötték .osztály fájlok ismeretlenek.

Annak érdekében, hogy a betöltött .osztály fájlok nem jelentenek veszélyt a végső futtatható fájlra, a JVM ellenőrzést végez a .osztály fájlokat. Ezenkívül a JVM biztosítja a bináris fájlok megfelelő formálását. Például a JVM ellenőrzi, hogy az osztályok nem adnak-e altípust végső osztályok.

Sok esetben az érvényes, nem rosszindulatú bytecode ellenőrzése sikertelen, mert a Java újabb verziójának szigorúbb ellenőrzési folyamata van, mint a régebbi verzióknak. Például a JDK 13 hozzáadhat egy ellenőrzési lépést, amelyet a JDK 7 nem hajtott végre. Ha tehát egy alkalmazást futtatunk a JVM 13 alkalmazással, és a Java Compiler (javac) régebbi verziójával állítottunk össze függőségeket, akkor a JVM figyelembe veheti a az elavult függőségek érvénytelenek.

Így, ha összekapcsolja az idősebbeket .osztály fájlok egy újabb JVM-mel, a JVM dobhat a java.lang.VerifyError hasonló a következőkhöz:

java.lang.VerifyError: stackmap keret várása az elágazási célnál X Kivétel részletei: Hely: com / example / baeldung.Foo (Lcom / example / baeldung / Bar: Baz;) Lcom / example / baeldung / Foo; @ 1: infonull Ok: Várható stackmap keret ezen a helyen. Bytecode: 0000000: 0001 0002 0003 0004 0005 0006 0007 0008 0000010: 0001 0002 0003 0004 0005 0006 0007 0008 ...

Kétféle módon lehet megoldani ezt a problémát:

  • Frissítse a függőségeket a frissítéssel lefordított verziókra javac
  • Tiltsa le a Java ellenőrzését

3. Termelési megoldás

Az ellenőrzési hiba leggyakoribb oka a bináris fájlok összekapcsolása a JVM egy újabb verziójával, amely a javac. Ez gyakoribb, amikor a függőségek bytecode-ját olyan eszközök generálják, mint a Javassist, amely elavult bájtkódot generálhatott, ha az eszköz elavult.

A probléma megoldásához frissítse a függőségeket aAz alkalmazás felépítéséhez használt JDK verzióval megegyező verzió. Például, ha egy alkalmazást a JDK 13 segítségével készítünk, akkor a függőségeket a JDK 13 segítségével kell felépíteni.

Kompatibilis változat megtalálásához ellenőrizze a Build-Jdk a függőség JAR Manifest fájljában annak biztosítására, hogy megfeleljen az alkalmazás felépítéséhez használt JDK verziónak.

4. Hibakeresés és fejlesztési megoldás

Hibakereséskor vagy egy alkalmazás fejlesztésekor letilthatjuk az igazolást gyors javításként.

Ne használja ezt a megoldást gyártási kódként.

Az ellenőrzés letiltásával a JVM rosszindulatú vagy hibás kódot kapcsolhat alkalmazásunkhoz, ami biztonsági kompromisszumokat vagy összeomlást eredményezhet végrehajtásukkor.

Vegye figyelembe azt is, hogy a JDK 13-tól kezdődően ez a megoldás már elavult, és nem szabad elvárnunk, hogy ez a megoldás a jövőbeni Java-kiadásokban is működjön. Az ellenőrzés letiltása a következő figyelmeztetést eredményezi:

A Java HotSpot (TM) 64 bites kiszolgáló virtuális gép figyelmeztetése: Az -Xverify: none és -noverify opciókat elavulták a JDK 13-ban, és valószínűleg egy későbbi kiadásban eltávolítják.

A bájtkód-ellenőrzés letiltásának mechanizmusa attól függ, hogy hogyan futtatjuk a kódunkat.

4.1. Parancs sor

A parancssorban történő ellenőrzés letiltásához adja át a noverify zászló a Jáva parancs:

java -noverify Foo.class

Vegye figyelembe, hogy -újítsa meg a parancsikon a-Xverify: nincs és mindkettő felcserélhetően használható.

4.2. Maven

Ha le szeretné tiltani az ellenőrzést egy Maven-összeállításban, adja át a noverify jelöli a kívánt plugint:

 com.example.baeldung example-plugin -noverify 

4.3. Gradle

Ha le szeretné tiltani az ellenőrzést egy Gradle buildben, adja át a noverify jelölje be a kívánt feladatot:

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

5. Következtetés

Ebben a gyors bemutatóban megtudtuk, hogy a JVM miért végez bájtkód-ellenőrzést, és mi okozza azt java.lang.VerifyError hiba. Két megoldást is feltártunk: egy gyártási és egy nem termelési megoldást.

Amikor lehetséges, használja a függőségek legújabb verzióit ahelyett, hogy letiltaná az ellenőrzést.