I was using Powermockito to write my junit test cases. When i ran my test case it started throwing Verify Error.
Error
java.lang.VerifyError: Bad <init> method call from inside of a branch
Exception Details:
Location:
y/z/a/ABC.<init>(Lorg/powermock/core/IndicateReloadClass;)V @42: invokespecial
Reason:
Error exists in the bytecode
Bytecode:
0000000: 2a2b 4e4d 1300 c6b8 0051 04bd 0031 5903
0000010: 2d53 1303 f6b8 0043 b800 ca3a 0519 05b2
0000020: 005e a500 0e2a 01c0 00cc b700 cfa7 000a
0000030: 2c2d b700 cf01 57b1
Stackmap Table:
full_frame(@48,{UninitializedThis,Object[#204],UninitializedThis,Object[#204],Top,Object[#49]},{})
full_frame(@55,{Object[#2],Object[#204],Object[#2],Object[#204],Top,Object[#49]},{})
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at javassist.runtime.Desc.getClassObject(Desc.java:43)
at javassist.runtime.Desc.getClassType(Desc.java:152)
at javassist.runtime.Desc.getType(Desc.java:122)
at javassist.runtime.Desc.getType(Desc.java:78)
Error
java.lang.VerifyError: Bad <init> method call from inside of a branch
Exception Details:
Location:
y/z/a/ABC.<init>(Lorg/powermock/core/IndicateReloadClass;)V @42: invokespecial
Reason:
Error exists in the bytecode
Bytecode:
0000000: 2a2b 4e4d 1300 c6b8 0051 04bd 0031 5903
0000010: 2d53 1303 f6b8 0043 b800 ca3a 0519 05b2
0000020: 005e a500 0e2a 01c0 00cc b700 cfa7 000a
0000030: 2c2d b700 cf01 57b1
Stackmap Table:
full_frame(@48,{UninitializedThis,Object[#204],UninitializedThis,Object[#204],Top,Object[#49]},{})
full_frame(@55,{Object[#2],Object[#204],Object[#2],Object[#204],Top,Object[#49]},{})
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at javassist.runtime.Desc.getClassObject(Desc.java:43)
at javassist.runtime.Desc.getClassType(Desc.java:152)
at javassist.runtime.Desc.getType(Desc.java:122)
at javassist.runtime.Desc.getType(Desc.java:78)
My application was running on java "1.7.0_67" and using power mockito "1.6.2". I was not knowing what is the wrong with my test cases.
Root Cause
The VM in JDK 7 uses the new verifier for code compiled in Java 7 mode, but falls back to the old one for code compiled in Java 6 mode. Thus, in theory there should be no problem.
They basically read the bytecode, tagged as Java 7 bytecode, and perform changes in Java 6 mode, saving the results still tagged in Java 7 mode. Thus, the VM in JDK 7 sees Java 7 bytecode and activates the new Java 7 verifier, which fails (or can fail) when it meet the bytecode manipulated in Java 6 mode.
Solution
We can solve this problem by 2 ways:
- >By changing java version to older version (1.7.0_25)
- By adding this VM runtime option: -XX:-UseSplitVerifier.