Sotirios-Efstathios Maneas

About Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a postgraduate student at the Department of Informatics and Telecommunications of The National and Kapodistrian University of Athens. His main interests include distributed systems, web crawling, model checking, operating systems, programming languages and web applications.

java.lang.VerifyError – How to solve VerifyError

In this tutorial we will discuss about the VerifyError in Java. This error indicates that the verifier, included in the Java Virtual Machine (JVM), detected a class file that despite well formed, it contains some type of internal inconsistency or faces a security problem.

The VerifyError class extends the LinkageError class, which is used to indicate those error cases, where a class has a dependency on some other class and that class has incompatibly changed after the compilation. Furthermore, the LinkageError class extends the Error class, which is used to indicate those serious problems that an application should not catch. A method may not declare such errors in its throw clause, because these errors are abnormal conditions that shall never occur.

Finally, the VerifyError exists since the 1.0 version of Java.

The Structure of VerifyError

Constructors

  • VerifyError()
  • Creates an instance of the VerifyError class, setting null as its message.

  • VerifyError(String s)
  • Creates an instance of the VerifyError class, using the specified string as message. The string argument indicates the name of the class that threw the error.

The VerifyError in Java

The Java Virtual Machine (JVM) contains a bytecode verifier that is responsible to verify all bytecode before it is executed. The purpose of the bytecode verifier is to verify the integrity of a sequence of bytecodes. The verification procedure consists mostly of the following checks:

  • Branches point to valid locations.
  • Data is initialized and references are type safe.
  • Access to private, or package private, data and methods is controlled.

The first two checks occur when a class is loaded and made eligible for use, while the third check takes place dynamically, when data items or methods of a class are first accessed by another class.

For a more detailed description about the Java Virtual Machine (JVM) verifier please refer to the following sources:

In Java, there are many common cases that throw a VerifyError. In the rest of this section, we will describe some of them in detail.

A class tries to extend a class declared as final:

Consider the following classes:

TestClassA.java:

public class TestClassA {
	public TestClassA() {
		System.out.println("Created a new instance of the TestClassA class");
	}
}

TestClassB.java:

public class TestClassB extends TestClassA {
	public TestClassB() {
		super();
		System.out.println("Created a new instance of the TestClassB class");
	}

	public static void main(String[] args) {
		TestClassB b = new TestClassB();
	}
}

Each class is stored in a separate file. We compile each class separately and then, execute:

$ javac TestClassA.java
$ javac TestClassB.java
$ java TestClassB

A sample execution is shown below:

Created a new instance of the TestClassA class
Created a new instance of the TestClassB class

However, if we change the definition of the class TestClassA to final, then re-compile only the class TestClassA and finally, execute the main method of class TestClassB, the following error is thrown:

Exception in thread "main" java.lang.VerifyError: Cannot inherit from final class
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

The cause of the error is that we changed the definition of class TestClassA, but class TestClassB was compiled using an older version of the class TestClassA.

A method tries to override a super method that is declared as final:

Consider the following classes:

TestClassA.java:

public class TestClassA {
	public TestClassA() {
		System.out.println("Created a new instance of the TestClassA class");
	}

	public void print() {
		System.out.println("TestClassA::print()");
	}
}

TestClassB.java:

public class TestClassB extends TestClassA {
	public TestClassB() {
		super();
		System.out.println("Created a new instance of the TestClassB class");
	}

	@Override
	public void print() {
                System.out.println("TestClassB::print()");
        }

	public static void main(String[] args) {
		TestClassB b = new TestClassB();
		b.print();
	}
}

Each class is stored in a separate file. We compile each class separately and then, execute:

$ javac TestClassA.java
$ javac TestClassB.java
$ java TestClassB

A sample execution is shown below:

Created a new instance of the TestClassA class
Created a new instance of the TestClassB class
TestClassB::print()

However, if we change the definition of the method print inside the class TestClassA to final, then re-compile only the class TestClassA and finally, execute the main method of class TestClassB, the following error is thrown:

Exception in thread "main" java.lang.VerifyError: class TestClassB overrides final method print.()V
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

Again, the cause of the error is that we changed a method’s definition of class TestClassA, but class TestClassB was compiled using an older version of the class TestClassA.

A wrong argument is passed to a method:

Consider the following classes:

TestClassA.java:

public class TestClassA {
	public TestClassA() {
		System.out.println("Created a new instance of the TestClassA class");
	}

	public void print() {
		System.out.println("TestClassA::print()");
	}
}

TestClassB.java:

public class TestClassB extends TestClassA {
	public TestClassB() {
		super();
		System.out.println("Created a new instance of the TestClassB class");
	}

	public void print() {
		System.out.println("TestClassB::print()");
        }
}

TestClassC.java:

public class TestClassC {
	public static void _print_(TestClassA a) {
		a.print();
	}

	public static void main(String[] args) {
		TestClassB b = new TestClassB();
		TestClassC._print_(b);
	}
}

Each class is stored in a separate file. We compile each class separately and then, execute:

$ javac TestClassA.java
$ javac TestClassB.java
$ javac TestClassC.java
$ java TestClassC

A sample execution is shown below:

Created a new instance of the TestClassA class
Created a new instance of the TestClassB class
TestClassB::print()

However, if we change the definition of the class TestClassB not to extend the class TestClassA, then re-compile only the class TestClassB and finally, execute the main method of class TestClassC, the following error is thrown:

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    TestClassC.main([Ljava/lang/String;)V @9: invokestatic
  Reason:
    Type 'TestClassB' (current frame, stack[0]) is not assignable to 'TestClassA'
  Current Frame:
    bci: @9
    flags: { }
    locals: { '[Ljava/lang/String;', 'TestClassB' }
    stack: { 'TestClassB' }
  Bytecode:
    0x0000000: bb00 0359 b700 044c 2bb8 0005 b1       

	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
	at java.lang.Class.privateGetMethodRecursive(Class.java:3035)
	at java.lang.Class.getMethod0(Class.java:3005)
	at java.lang.Class.getMethod(Class.java:1771)
	at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)

Again, the cause of the error is that we changed the definition of class TestClassB, but class TestClassC was compiled using an older version of the class TestClassB.

How to deal with the VerifyError

In order to avoid the VerifyError, you must compile all your classes using the same version of Java. Also, once you make a change to a class, then make sure that you re-compile your project from scratch. Finally, if your application makes use of external libraries, verify that you use the appropriate version of every library and of course, consult the corresponding javadocs, in order to be sure that everything is correct.

 
This was a tutorial about the VerifyError in Java.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.
Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Examples Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close