javassist icon indicating copy to clipboard operation
javassist copied to clipboard

BadBytecode exception when Android AAR code is shrinked with new R8 code shrinker.

Open NazarKacharaba opened this issue 5 years ago • 3 comments

We develop the SDK for Android, final product is aar package. After switching to new android R8 tool, some unit tests in clients' projects that are using PowerMock to mock some methods in our SDK started failing with following exception:

Caused by: javassist.bytecode.BadBytecode: getEta (ZLcom/here/android/mpa/routing/Route$TrafficPenaltyMode;)Ljava/util/Date; in com.here.android.mpa.guidance.NavigationManager: inconsistent stack height -1
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:119)
	at javassist.bytecode.MethodInfo.rebuildStackMap(MethodInfo.java:458)
	at javassist.bytecode.MethodInfo.rebuildStackMapIf6(MethodInfo.java:440)
	at javassist.CtBehavior.insertBefore(CtBehavior.java:800)
	... 65 more
Caused by: javassist.bytecode.BadBytecode: inconsistent stack height -1
	at javassist.bytecode.stackmap.Tracer.doOpcode(Tracer.java:81)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:195)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:207)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:172)
	at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:116)
	... 68 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
	at javassist.bytecode.stackmap.Tracer.doASTORE(Tracer.java:422)
	at javassist.bytecode.stackmap.Tracer.doOpcode54_95(Tracer.java:339)
	at javassist.bytecode.stackmap.Tracer.doOpcode(Tracer.java:75)
	... 83 more

Full stack trace.

When we recompile SDK with old ProGuard tool, everything works fine. SDK uses Java 7 code and source compatibility and does not have any Kotlin files. We tried latest Javassist 3.25.0-GA release.

To reproduce this issue run test in this project from within MSDKUIKit folder. To run tests you can use Android Studio or run these commands:

cd MSDKUIKit
./gradlew :MSDKUILib:testDebugUnitTest --tests=com.here.msdkui.guidance.GuidanceManeuverPresenterTest.testHandlePositionUpdate

NazarKacharaba avatar Aug 21 '19 10:08 NazarKacharaba

I run into a similar issue. Did you solve it?

igottime avatar Sep 15 '20 00:09 igottime

I'm also seeing this when using Android Gradle Plugin 4.+ and PowerMock 2.0.9. We aren't using Kotlin either.

Everything is fine with R8 disabled, but when I enable it this exact exception happens. It happens when using a minified AAR from another project in our unit tests.

I'm wondering if https://github.com/jboss-javassist/javassist/pull/351 is intended to fix this.

michelau avatar Mar 17 '21 05:03 michelau

Hey we have the same problem. It happens, when we use PowerMock and add to @PrepareForTest classes from Google Play. For example this one: ReviewManagerFactory

Per debugging I see that crash happens, when MapMaker recreate StackMapTable during instrumentation. Fail is on doOpcode->doOpcode54_95 because stackTop became less then zero (-1)

avartbaronov avatar Nov 09 '22 13:11 avartbaronov