Uzroci i izbjegavanje java.lang.VerifyError

1. Uvod

U ovom uputstvu pogledat ćemo uzrok java.lang.VerifyError pogreške i više načina da se to izbjegne.

2. Uzrok

The Java virtualni stroj (JVM) ne vjeruje svim učitanim bajt-kodovima kao osnovno načelo Java sigurnosnog modela. Tijekom izvođenja, JVM će se učitati .razred datoteke i pokušati ih povezati kako bi stvorili izvršnu datoteku - ali valjanost je učitana .razred datoteke su nepoznate.

Kako bi se osiguralo da je učitan .razred datoteke ne predstavljaju prijetnju konačnoj izvršnoj datoteci, JVM vrši provjeru na .razred datoteke. Uz to, JVM osigurava dobro oblikovanje binarnih datoteka. Na primjer, JVM će provjeriti da klase nemaju podtip konačni razreda.

U mnogim slučajevima provjera ne uspije na važećem, nenamjernom bajt kodu jer novija verzija Jave ima stroži postupak provjere od starijih verzija. Na primjer, JDK 13 možda je dodao korak provjere koji nije proveden u JDK 7. Dakle, ako pokrenemo aplikaciju s JVM 13 i uključimo ovisnosti kompajlirane sa starijom verzijom Java Compilera (javac), JVM može uzeti u obzir zastarjele ovisnosti biti nevaljane.

Dakle, prilikom povezivanja starijih .razred datoteke s novijim JVM-om, JVM može baciti a java.lang.VerifyError slično sljedećem:

java.lang.VerifyError: Očekivanje okvira stackmape na cilju grane X Pojedinosti o iznimci: Mjesto: com / example / baeldung.Foo (Lcom / example / baeldung / Bar: Baz;) Lcom / example / baeldung / Foo; @ 1: infonull Razlog: Očekivani okvir mape na ovom mjestu. Bytecode: 0000000: 0001 0002 0003 0004 0005 0006 0007 0008 0000010: 0001 0002 0003 0004 0005 0006 0007 0008 ...

Postoje dva načina za rješavanje ovog problema:

  • Ažurirajte ovisnosti na verzije sastavljene s ažuriranim javac
  • Onemogući provjeru Java

3. Proizvodno rješenje

Najčešći uzrok pogreške u verifikaciji je povezivanje binarnih datoteka pomoću novije verzije JVM kompajlirane sa starijom verzijom javac. To je češće kada ovisnosti imaju bytecode generiran alatima kao što je Javassist, koji je možda generirao zastarjeli bytecode, ako je alat zastario.

Da biste riješili ovaj problem, ažurirati ovisnosti na averzija izrađena pomoću verzije JDK koja se podudara s verzijom JDK koja se koristi za izgradnju aplikacije. Na primjer, ako gradimo aplikaciju pomoću JDK 13, ovisnosti bi se trebale graditi pomoću JDK 13.

Da biste pronašli kompatibilnu verziju, pregledajte Build-Jdk u datoteci JAR Manifest ovisnosti kako bi se osiguralo da se podudara s verzijom JDK koja se koristi za izgradnju aplikacije.

4. Rješenje za otklanjanje pogrešaka i razvoj

Pri otklanjanju pogrešaka ili razvoju aplikacije možemo potvrdu onemogućiti kao brzo rješenje.

Ne koristite ovo rješenje za proizvodni kod.

Onemogućavanjem provjere, JVM može povezati zlonamjerni ili neispravni kôd s našim aplikacijama, što rezultira sigurnosnim kompromisima ili padovima prilikom izvršenja.

Također imajte na umu da je od JDK 13 ovo rješenje zastarjelo i ne bismo trebali očekivati ​​da će to rješenje funkcionirati u budućim izdanjima Java. Onemogućavanje provjere rezultirat će sljedećim upozorenjem:

Upozorenje za Java HotSpot (TM) 64-bitni poslužitelj VM: Opcije -Xverify: none i -noverify zastarjeli su u JDK 13 i vjerojatno će biti uklonjeni u budućem izdanju.

Mehanizam za onemogućavanje provjere bajt koda razlikuje se ovisno o načinu na koji pokrećemo naš kôd.

4.1. Naredbeni redak

Da biste onemogućili provjeru na naredbenom retku, dodajte noverificirati zastava za Java naredba:

java -noverify Foo.class

Imajte na umu da -novirificirati je prečac za-Xverify: nema a obje se mogu koristiti naizmjenično.

4.2. Maven

Da biste onemogućili provjeru u Mavenovoj gradnji, dodajte noverificirati označi bilo koji željeni dodatak:

 com.example.baeldung primjer-dodatak -noverify 

4.3. Gradle

Da biste onemogućili provjeru u gradnji Gradle, dodajte noverificirati označi bilo koji željeni zadatak:

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

5. Zaključak

U ovom smo brzom vodiču saznali zašto JVM izvodi provjeru bajt koda i što uzrokuje java.lang.VerifyError pogreška. Također smo istražili dva rješenja: proizvodno i neproizvodno.

Kad je moguće, koristite najnovije verzije ovisnosti umjesto da onemogući provjeru.


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