Java 7 enforces bytecode verification

I had some issues lately when migrating to Java 7. As you may know if you read this blog, I’ve been playing these past few weeks with test framework and more precisely PowerMock. I also had to mess with the bytecode a bit myself because some libraries from ICN have dependencies missing and can not be hot recompiled by PowerMock (rebuilding the byte code during Runtime).

Well what I did with the bytecode didn’t work with Java 7. After some researches, I discovered than the byte code verification has been enforced with Java 7, to avoid injection of malicious code via bytecode modification. This is good for production, but in test when we like to mess with bytecode to allow us some tricks, that’s not really helpful. Anyway after a while I discovered the option to disabled this bytecode verification. Of course I wouldn’t recommend using that in production, but it can be useful for test.

For IBM JDK, I didn’t find yet a way to fall back to the old verification engine, so for now I just disable it. Add this to your JVM arguments when running test.

-Xverify:none

For SUN JDK, there is an option to fall back to the old verification engine. Alternatively you can also disable the verification the same way that we do for IBM JDK. Here is the option:

-XX:-UseSplitVerifier


And for your curiosity, here are the error you will get if you keep the new verification. With IBM JDK:

Exception in thread "main" java.lang.VerifyError: JVMVRFY012 stack shape inconsistent; class=TestA, method=main([Ljava/lang/String;)V, pc=31
	at java.lang.J9VMInternals.prepareClassImpl(Native Method)
	at java.lang.J9VMInternals.prepare(J9VMInternals.java:450)
	at java.lang.Class.getMethod(Class.java:1159)
	at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:507)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:499)

With SUN JDK:

Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 57
Exception Details:
  Location:
    TestA.main([Ljava/lang/String;)V @31: goto
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0000000: b800 154c 2b12 17b6 001b 4d2c b600 214e
    0000010: 2db6 0027 3a04 1904 b900 2d01 003a 06a7
    0000020: 001a 1906 b900 3301 00c0 0035 3a05 b200
    0000030: 3b19 05b6 003f b600 4519 06b9 0049 0100
    0000040: 9aff e2b2 003b 124b b600 45b1          

	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
	at java.lang.Class.getMethod0(Unknown Source)
	at java.lang.Class.getMethod(Unknown Source)
	at sun.launcher.LauncherHelper.getMainMethod(Unknown Source)
	at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

 

 

One thought on “Java 7 enforces bytecode verification

Leave a Reply