JDK 1.7 fails on JIBX: java.lang.VerifyError error

This is what I got when running WSO2 AS JiBX sample on JDK 1.7. By the way What is JiBX???
JiBX differs from other data binding techniques supported by Axis2 in that it allows you to use your own Java data objects (as opposed to Java data objects generated from a schema definition). JiBX also provides a nicer form of an unwrapped Web services interface than is supported by the other data binding techniques[1].
     [bind] Error running binding compiler
     [bind] java.lang.VerifyError: Expecting a stackmap frame at branch target 12
     [bind] Exception Details:
     [bind]   Location:
     [bind]     org/wso2/appserver/jibx/library/beans/Book.JiBX_jibx_unwrapped_newinstance_1_0(Lorg/wso2/appserver/jibx/library/beans/Book;Lorg/jibx/runtime/impl/UnmarshallingContext;)Lorg/wso2/appserver/jibx/library/beans/Book; @1: ifnonnull
     [bind]   Reason:
     [bind]     Expected stackmap frame at this location.
     [bind]   Bytecode:
     [bind]     0000000: 2ac7 000b bb00 0a59 b700 744b 2ab0     
     [bind] at java.lang.Class.getDeclaredMethods0(Native Method)
     [bind] at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
     [bind] at java.lang.Class.getDeclaredMethods(Class.java:1860)
     [bind] at org.jibx.binding.Compile.compile(Compile.java:278)
     [bind] at org.jibx.binding.ant.CompileTask.execute(CompileTask.java:248)
     [bind] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
     [bind] at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
     [bind] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     [bind] at java.lang.reflect.Method.invoke(Method.java:606)
     [bind] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
     [bind] at org.apache.tools.ant.Task.perform(Task.java:348)
     [bind] at org.apache.tools.ant.Target.execute(Target.java:435)
     [bind] at org.apache.tools.ant.Target.performTasks(Target.java:456)
     [bind] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
     [bind] at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
     [bind] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
     [bind] at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
     [bind] at org.apache.tools.ant.Main.runBuild(Main.java:851)
     [bind] at org.apache.tools.ant.Main.startAnt(Main.java:235)
     [bind] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
     [bind] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

The hardest sentence that a developer ever don't want to see on `ant` is the "BUILD FAILED" message. So, we have lost in a java.lang.VerifyError.

Root Problem?

Let's dig into the problem. We are getting a java.lang.VerifyError error. Why we getting such a thing?

Because JVM class loader checks the byte codes of the class for various purposes;
  • Variables are initialized before they are used.
  • Method calls match the types of object references.
  • Rules for accessing private data and methods are not violated.
  • Local variable accesses fall within the runtime stack.
  • The runtime stack does not overflow.

If one of the above is failed, JVM will think the class is corrupted and/or the class will not be loaded. This strict verification is an important security consideration. It avoids unexpected errors that breaks the execution of the program ad injecting malicious codes into the Java programs.

Java 7 introduced a strict verification and changed the class format slightly to contain a stackmap, used to verify the code is correct. As a result; on the exception details, it says; `Expected stackmap frame at this location`.

So What is the Solution?

If you are using ANT builders; you can use ANT_OPTS environment variable to following;

export ANT_OPTS=-noverify

Or as a workaround you can add -noverify to the JVM arguments in order to disable verification. In Java 7 it was also possible to use -XX:-UseSplitVerifier to use the less strict verification method, but that option was removed in Java 8.

Additional Note:

In Java world, dynamic java code is protected with the three line of protection layers as shown in below image. The first line on defense is ByteCode Verifier. The verifier reads the bytecodes before it is run and make sure it is well behaved according to the basic rules of the java language.

Niemeyer P., Leuck, D., "Learning Java, Fourth Edition", O'REILLY Atlas online version[1]
A trusted java compiler will not produce such malicious bytecodes, but it is possible to an outsider to malform the bytecodes of a class and it is java verifier's  job to detect such certain instances. For additional readings please refer [2].


[1]  WSO2 AS Documentation, Available Online: https://docs.wso2.com/display/AS521/JiBX+Data+Binding [2] Niemeyer P., Leuck, D., "Learning Java, Fourth Edition",chapter 1,  O'REILLY Atlas, Available Online: http://chimera.labs.oreilly.com/books/1234000001805/ch01.html#learnjava3-CHP-1-SECT-5.1

Rasika Perera

  • Image
  • Image
  • Image
  • Image
  • Image
    Blogger Comment
    Facebook Comment