Why Java.lang.VerifyError occurs in Java and how to solve this?


Java.lang.VerifyError is a runtime error which is ceated by JVM(Java virtual machine). During runtime a verification process happens to check the validity of loaded . class files, and if .class file violates any constraint then JVM will give Java.lang.VerifyError error. The following error is present in Java 1.0 version and onwards.

java.lang.LinkageError extends Java.lang.VerifyError which refers to when there is a problem with the linking process of the program.

Java.lang.VerifyError in the output will be look like:

Exception in thread "main" java.lang.VerifyError: (class: com/example/Way2Class, method: myMethod signature: ()V) Incompatible argument to function
   at com.example.MyClass.main(MyClass.java:10)

This output contains name of the class that caused the error (Way2class), classpath(com/example/Way2Class), Line of error(10), method name(myMethod) and error message(Exception in thread "main" java.lang.VerifyError)

This error can occur for various reasons which are as follows:

  • Mismatch of versions: It is important to note that a VerifyError may ensue if the class file was compiled using a different version of the Java compiler than that which is being utilized to execute the code.

Example

public class VerifyErrorVersionExample {
   public static void main(String[] args) {
      System.out.println("Hello, program!");
   }
}

In a scenario whereby this particular program is compiled using Java 9 and run on an earlier version such as Java 8, the output will display the subsequent error explanation:

Output

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
   Location:
      VerifyErrorVersionExample.main([Ljava/lang/String;)V @2: invokestatic
   Reason:
      Type 'java/lang/invoke/StringConcatFactory' (current frame, stack[0]) is not assignable to 'java/lang/invoke/MethodHandle'
   Current Frame:
      bci: @2
      flags: { }
      locals: { '[Ljava/lang/String;' }
      stack: { 'java/lang/invoke/StringConcatFactory' }
   Bytecode:
      0x0000000:  getstatic    #2   // Field java/lang/System.out:Ljava/io/PrintStream;
      0x0000003:  ldc          #3   // String Hello, world!
      0x0000005:  invokestatic #4   // Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
      0x000000a:  ldc          #5   // String 
      0x000000c:  iconst_1
      0x000000d:  anewarray   #6   // class java/lang/Object
      0x0000010:  dup
      0x0000011:  iconst_0
      0x0000012:  ldc          #7   // String !!!
      0x0000014:  aastore
      0x0000015:  invokevirtual #8   // Method java/lang/invoke/MethodHandle.invokeExact:([Ljava/lang/Object;)Ljava/lang/Object;
      0x000001a:  checkcast   #9   // class java/lang/String
      0x000001d:  invokevirtual #10  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      0x0000020:  return  
  • Bytecode corruption: An error can emerge if alterations or corruption are made to the bytecode of a class file.

Example

public class VerifyErrorBytecodeExample {
   public static void main(String[] args) {
      int a = 10;
      int b = 20;
      int c = a + b;
      System.out.println("The sum of " + a + " and " + b + " is " + c);
   }
}

Output

Exception in thread "main" java.lang.VerifyError: (class: VerifyErrorBytecodeExample, method: main signature: ([Ljava/lang/String;)V) Illegal target of jump or branch
      at java.lang.Class.getDeclaredMethods0(Native Method)
      at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
      at java.lang.Class.getDeclaredMethod(Class.java:2128)
      at java.io.ObjectStreamClass.getPrivateMethod(ObjectStreamClass.java:1743)
      at java.io.ObjectStreamClass.access$1700(ObjectStreamClass.java:72)
      at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:513)
      at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:492)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:492)
      at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:389)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1134)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
      at VerifyErrorBytecodeExample.main(VerifyErrorBytecodeExample.java:6)
  • Class file inconsistency: if the class file violates certain constraints that are imposed by the Java Virtual Machine Specification.

Example

public class VerifyErrorExample {
   public static void main(String[] args) {
      Animal animal = new Cat();
      animal.speak();
   }
}
interface Animal {
   void speak();
}
class Dog implements Animal {
   public void speak() {
      System.out.println("Woof!");
   }
}
class Cat extends Dog {
   public void speak() {
      System.out.println("Meow!");
   }
}

This program defines an ‘Animal’ interface and two concrete classes that implement it: Dog and Cat. Cat extends Dog and overrides its speak method. In the main method, we create a Cat instance and invoke its speak method.

Assuming we choose to take out the Dog class from our current classpath then proceed with recompiling and running of our program there'll be a display of java.lang. VerifyError. This error will feature an error message like so:

Output

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
   Location:
      VerifyErrorExample.main([Ljava/lang/String;)V @2: invokevirtual
   Reason:
      Type 'Cat' (current frame, stack[0]) is not assignable to 'Dog'
   Current Frame:
      bci: @2
      flags: { }
      locals: { '[Ljava/lang/String;' }
      stack: { 'Cat' }
   Bytecode:
      0000000:  new           #2                  // class Cat
      0000003:  dup
      0000004:  invokespecial #3                  // Method Cat."":()V
      0000007:  astore_1
      0000008:  aload_1
      0000009:  invokevirtual #4                  // Method Animal.speak:()V
      000000c:  return

Conclusion

In summary, experiencing a java.lang.VerifyError can stem from various causes ranging from bytecode fluctuations through restrictions rooted in secure computing practices right over all inconsistent interdependent versions of Java components included within your codebase among others such as library compatibility issues at runtime. An incredibly important way of sidestepping this issue is by making certain that all libraries being used are compatible both with your system and other dependent libraries during runtime.Taking heed of those requirements will ensure adherence to Java’s bytecode stipulations steering you clear of problematic coding practices such as non-compliance with security protocols or submitting code with inconsistencies in class files which can cause errors further down the line. Whenever java.lang.VerifyError raises its head, it’s imperative to carefully inspect the associated error message together any stack traces you can obtain so you determine the exact issue at play and take the necessary corrective steps.

Updated on: 31-Jul-2023

234 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements