How do I fix VerifyError when running PowerMock in

2019-09-19 06:14发布

问题:

I want to use PowerMockerRule in my unit tests so that I can use PowerMockito in them while I run them with Spring's JUnit Runner. However, when I add the rule to my test, I get java.lang.VerifyError.

java.lang.VerifyError: Expecting a stackmap frame at branch target 47
Exception Details:
  Location:
    com/sample/package/MyClass.<init>(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V @25: if_icmpge
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: 2a2b 2c01 c000 32b7 0050 2d3a 0419 04be
    0x0000010: 3605 0336 0615 0615 05a2 0016 1904 1506
    0x0000020: 323a 072a 1907 b600 4984 0601 a7ff e9b1
    0x0000030:

What I've done so far has been to update my javassist dependency to 3.20.0-GA as according to my initial searches, it's usually the problem. However, it still doesn't resolve the issues for me. Any other ideas?

回答1:

First about root cause of your problem. JVM verifies user classes to ensure that class is "safe" and that it will not violate some rules. Now in hotspot there are 2 verifiers: ClassVerifier (SplitVerifier) and old verifier. New verifier (SplitVerifier) was added in java 6 and was optional. This new verifier needs some more information in class file (StackMapTable attribute). This attribute is added by compiler and it tracks types of local variables.

Problem is that some instrumentation libraries can modify your code and don't update StackMapTable ( because of bugs or libraries are old and don't know about this attribute)

How to solve (choose one):

  1. Disable verification -Xverify:none
  2. Update\choose another instrumentation library
  3. Exclude class from been modified
  4. Downgrade class major version to 50 (java 6) and below (in this case old verifier will be used)