Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.VerifyError: Stack map does not match the one at exception handler

Faced this java.lang.VerifyError with code snippet as below during JVM loading bytecode.

try{
-----
}  catch (NumberFormatException|CalculationException e) {

}

Here CalculationException is custom exception which extends java.lang.RuntimeException, while NumberFormatException is standard Java RuntimeException. While the code compile and run fine locally windows machine.

It fails with VerifyError on one of the QA/prod/Dev unix node, and works fine on other unix node. While both unix nodes have the same config (using RedHat 6.2 and 1.8 jdk and same version jar files) also compared the bytecode generated on both nodes by javap -c and found this same.

I found two ways to resolve this on erroneous node also.

1) As this error is coming at byte-code verification step, tried by disabling the bytecode verification on dev unix box as -Xverify:none (Also tried -XX:-UseSplitVerifier but dint work, as i think its disabled from jdk 8) However as we shall not disable bytecode verification in prod, have been looking for some other workaround.

2) Another workaround is by using the parent exception: RuntimeException in catch block instead of combining two exception.

What I am not able to understand if Java does have issue with this way of catching, why compiler dint complained it and why it works on one machine and not on other which have same config. Also the error reason is not making sense which says: CalculationException (current frame, stack[0]) is not assignable to 'java/lang/RuntimeException While its actually assignable as tested by

if (RuntimeException.class.isAssignableFrom(CalculationException.class)){
    System.out.println("Assisgnable");
}

Full Exception Details: Location:

    com/markit/valuations/marketdata/snapper/domain/credit/BeanWrapperBuilder_CDXOCompositeVolSurface.getSpreadVol(Lcom/markit/valuations/dates/ImmutableDate;Lcom/markit/valuations/marketdata/data/indexeddata/IndexedData;DLcom/markit/valuations/dates/ImmutableDate;Lcom/markit/valuations/dates/ImmutableDate;Ljava/lang/String;Ljava/lang/String;Lcom/markit/qag/analytics/credit/indexpv/swaption/CreditIndexSwaptionCalculator;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Double; @51: astore
  Reason:
    Type 'com/markit/valuations/common/CalculationException' (current frame, stack[0]) is not assignable to 'java/lang/RuntimeException' (stack map, stack[0])
  Current Frame:
    bci: @0
    flags: { }
    locals: { 'com/markit/valuations/marketdata/snapper/domain/credit/BeanWrapperBuilder_CDXOCompositeVolSurface', 'com/markit/valuations/dates/ImmutableDate', 'com/markit/valuations/marketdata/data/indexeddata/IndexedData', double, double_2nd, 'com/markit/valuations/dates/ImmutableDate', 'com/markit/valuations/dates/ImmutableDate', 'java/lang/String', 'java/lang/String', 'com/markit/qag/analytics/credit/indexpv/swaption/CreditIndexSwaptionCalculator', 'java/lang/String', 'java/lang/String' }
    stack: { 'com/markit/valuations/common/CalculationException' }
  Stackmap Frame:
    bci: @51
    flags: { }
    locals: { 'com/markit/valuations/marketdata/snapper/domain/credit/BeanWrapperBuilder_CDXOCompositeVolSurface', 'com/markit/valuations/dates/ImmutableDate', 'com/markit/valuations/marketdata/data/indexeddata/IndexedData', double, double_2nd, 'com/markit/valuations/dates/ImmutableDate', 'com/markit/valuations/dates/ImmutableDate', 'java/lang/String', 'java/lang/String', 'com/markit/qag/analytics/credit/indexpv/swaption/CreditIndexSwaptionCalculator', 'java/lang/String', 'java/lang/String' }
    stack: { 'java/lang/RuntimeException' }
  Bytecode:
    0x0000000: 2c19 0ab9 0015 0200 b800 cb2b 1906 ba00
    0x0000010: cc00 00b6 00cd ba00 ce00 00b6 00cf 1909
    0x0000020: ba00 d000 00b6 00cf 0eb8 003b b600 d1c0
    0x0000030: 0091 b03a 0cbb 0048 59b7 0049 12d3 b600
    0x0000040: 4b19 0ab6 004b 12d4 b600 4b2c 1254 b900
    0x0000050: 1502 00b6 004b 12d5 b600 4b29 b600 4c12
    0x0000060: d6b6 004b 1907 b600 4b12 d7b6 004b 1905
    0x0000070: b600 5b12 d8b6 004b 1906 b600 5b12 d9b6
    0x0000080: 004b 190b b600 4b12 dab6 004b 1908 b600
    0x0000090: 4bb6 004d 3a0d b200 4719 0d19 0cb9 0081
    0x00000a0: 0300 0eb8 003b b0
  Exception Handler Table:
    bci [0, 50] => handler: 51
    bci [0, 50] => handler: 51
  Stackmap Table:
  same_locals_1_stack_item_frame(@51,Object[#535])
like image 987
tarunk Avatar asked Feb 21 '19 10:02

tarunk


1 Answers

Cause

This happened to me when there were conflicting versions of the same library (Jar) in my dependencies. To be more specific, I was importing different versions of Jackson library v2.9.10 and v2.11.0.

Troubleshooting

Start your application in verbose mode and make java log all the classes it is loading to see where the conflicting class is coming from. This can be done by passing the flag -verbose:class

Fix

  • Remove conflicting versions of dependencies and make sure all related dependencies/libraries are of the same major version (at the least) and preferably the same minor version too.
  • Remove dependencies that transitively import conflicting version of direct dependencies.
  • If you are not seeing any conflicting dependencies even after using mvn dependency:tree or Maven Helper plugins, the conflicting dependency could have been imported by one of the libraries' classpath. I know this sounds weird, since only applications should have classpath, but if someone added <addClasspath>true</addClasspath> in their library pom file, it could lead to this.
like image 122
Aditya Vikas Devarapalli Avatar answered Oct 24 '22 10:10

Aditya Vikas Devarapalli