card.io-Android-SDK icon indicating copy to clipboard operation
card.io-Android-SDK copied to clipboard

java.lang.VerifyError when unit testing Card.IO with Robolectric

Open fcduarte opened this issue 9 years ago • 24 comments

Hey guys,

upgrading our app to 5.0.0 started to throw some errors during our unit testing (we use Robolectric and JDK 8):

java.lang.VerifyError: Expecting a stackmap frame at branch target 49
Exception Details:
  Location:
    io/card/payment/CreditCard.toString()Ljava/lang/String; @39: ifgt
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: bb00 1759 b700 3a12 0ab6 003d 2ab6 002c
    0x0000010: b600 3c12 08b6 003d 2ab6 002e b600 3db6
    0x0000020: 003e 4c2a b400 1d9d 000a 2ab4 001e 9e00
    0x0000030: 2abb 0017 59b7 003a 2bb6 003d 1204 b600
    0x0000040: 3d2a b400 1db6 003b 1207 b600 3d2a b400
    0x0000050: 1eb6 003b b600 3e4c 2ab4 0020 c600 1ebb
    0x0000060: 0017 59b7 003a 2bb6 003d 1205 b600 3d2a
    0x0000070: b400 20b6 003d b600 3e4c 2ab4 001c c600
    0x0000080: 2cbb 0017 59b7 003a 2bb6 003d 1203 b600
    0x0000090: 3d2a b400 1cc6 000d 2ab4 001c b600 37a7
    0x00000a0: 0004 03b6 003b b600 3e4c bb00 1759 b700
    0x00000b0: 3a2b b600 3d12 0bb6 003d b600 3e4c 2bb0
    0x00000c0:                 
java.lang.VerifyError: Expecting a stackmap frame at branch target 12
Exception Details:
  Location:
    io/card/payment/CardIOActivity.<clinit>()V @5: ifne
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: 126e b601 5a9a 0007 04a7 0004 03b3 0096
    0x0000010: 1204 b300 a0b2 00a0 5904 60b3 00a0 b300
    0x0000020: 98b2 00a0 5904 60b3 00a0 b300 9ab2 00a0
    0x0000030: 5904 60b3 00a0 b300 9bb2 00a0 5904 60b3
    0x0000040: 00a0 b300 9cb2 00a0 5904 60b3 00a0 b300
    0x0000050: 9912 6eb6 015d b300 9d07 bc0b 5903 0950
    0x0000060: 5904 1400 8d50 5905 1400 8950 5906 1400
    0x0000070: 8b50 b300 9e10 0ab3 00b0 b200 b059 0460
    0x0000080: b300 b0b3 0097 03b3 00ad 01b3 00ac b1  

Steps to reproduce:

  1. Clone this repository: https://github.com/fcduarte/deckard-gradle/tree/card-io
  2. On the root of the repo run ./gradlew testDebug
  3. Check the result at file:///<path-to-repo>/deckard-gradle/build/reports/tests/debug/index.html

fcduarte avatar May 12 '15 22:05 fcduarte

The changes:

https://github.com/fcduarte/deckard-gradle/pull/1

fcduarte avatar May 12 '15 22:05 fcduarte

This is odd. Did you try JDK 7?

braebot avatar May 18 '15 19:05 braebot

I've just forced JDK 7:

https://github.com/fcduarte/deckard-gradle/commit/41f524fbb19227df22dd419d3e8e1eddffa1e7b4

same error.

fcduarte avatar May 18 '15 20:05 fcduarte

Do you know which version of Java RoboElectric is compiled with? I did some investigations, and this SO post appears relevant. We compile with JDK7, but if other libraries are built with JDK 6, you might see this error.

braebot avatar May 26 '15 20:05 braebot

They use JDK 7:

https://github.com/robolectric/robolectric/pull/1218

Since I don't know in which version it started to be supported I changed Robolectric on my test project to the latest version (3.0-rc3) and I'm still seeing the same error.

fcduarte avatar May 26 '15 21:05 fcduarte

@tomwhipple when do you think that it's gonna be the fix?

matiasdelbel avatar Jul 28 '15 11:07 matiasdelbel

@braebot @tomwhipple any update on this? I'm seeing a crash using JUnit on android unit test framework as well.

bhaskarmurthy avatar Sep 30 '15 21:09 bhaskarmurthy

@braebot I'm seeing the same Exception in a Robolectric test. Interestingly, at first I was including card io as a submodule because I forked the library and there were no issues with the test, however, I just switched over to io.card:android-sdk:5.3.0 and that's when the test started failing.

This is what I'm doing in the test:

        CreditCard creditCard = new CreditCard("3457856586548252", 2, 2017, "123", "78877");
        Intent intent = new Intent();
        intent.putExtra(CardIOActivity.EXTRA_SCAN_RESULT, creditCard);
        activity.onActivityResult(activity.getRequestCodeCreditCard(), Activity.RESULT_OK, intent);

And here's the Exception:

java.lang.VerifyError: Expecting a stackmap frame at branch target 49
Exception Details:
  Location:
    io/card/payment/CreditCard.toString()Ljava/lang/String; @39: ifgt
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0000000: bb00 1759 b700 3a12 0ab6 003d 2ab6 002c
    0000010: b600 3c12 08b6 003d 2ab6 002e b600 3db6
    0000020: 003e 4c2a b400 1d9d 000a 2ab4 001e 9e00
    0000030: 2abb 0017 59b7 003a 2bb6 003d 1204 b600
    0000040: 3d2a b400 1db6 003b 1207 b600 3d2a b400
    0000050: 1eb6 003b b600 3e4c 2ab4 0020 c600 1ebb
    0000060: 0017 59b7 003a 2bb6 003d 1205 b600 3d2a
    0000070: b400 20b6 003d b600 3e4c 2ab4 001c c600
    0000080: 2cbb 0017 59b7 003a 2bb6 003d 1203 b600
    0000090: 3d2a b400 1cc6 000d 2ab4 001c b600 37a7
    00000a0: 0004 03b6 003b b600 3e4c bb00 1759 b700
    00000b0: 3a2b b600 3d12 0bb6 003d b600 3e4c 2bb0
    00000c0:                                        

    at com.yodle.servicetask.activity.paymentform.PaymentFormActivityTest.clickingDone_whenCreditResultOk_showsConfirmCreditDialogAndCallsPaymentService(PaymentFormActivityTest.java:158)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

PaymentFormActivityTest.java:158 refers to the new CreditCard("3457856586548252", 2, 2017, "123", "78877") line

dsn5ft avatar Jan 13 '16 16:01 dsn5ft

@dsn5ft, thanks for posting this info. We haven't made any significant changes to that class, so I don't know why it would not fail in your forked copy. Any more information you can provide will help us debug this when we have the bandwidth.

braebot avatar Jan 14 '16 20:01 braebot

@fcduarte Try: Run >> Edit Configurations >> JUnit >> [Class or package to be tested], in VM Options add -noverify (for JDK 8) or -UseSplitVerifier (for JDK 7) after -ea.

lenin-omar avatar Feb 19 '16 20:02 lenin-omar

how can add this to gradle for ci to work?

kibotu avatar Jul 04 '16 15:07 kibotu

@kibotu I found that if you add -noverify to VM Options to your Run Configuration for your JUnit test that you are currently executing, you will find the real reason why your test is failing. Once you fix the test, your test should pass without the need for -noverify VM Option and not throw exception shown above. Btw I am using JDK 8 with Robolectric & JUnit 4. Hope it works for you.

ghost avatar Jul 28 '16 17:07 ghost

I have the same issue. Works fine with -noverify tho

Dimezis avatar Aug 11 '16 11:08 Dimezis

@kibotu, I don't know what @KevinLeighCrain is talking about, but you can add testOptions inside the android in gradle:

    testOptions {
        unitTests.all {
            jvmArgs '-noverify'
        }
    }

Dimezis avatar Aug 11 '16 12:08 Dimezis

@Dimezis I am pretty much saying that the underlying cause is a test failing and that adding the -noverify test option will reveal the cause and once you fix it, there should be no need for -noverify

ghost avatar Aug 16 '16 14:08 ghost

@KevinLeighCrain That's not true for my case for sure. It just crashes on CreditCard object creation and that's it, even if I remove the rest of the code.

Dimezis avatar Aug 16 '16 18:08 Dimezis

I have also seen the VerifyError occur when using card.io 5.5.0, mockito 2.0, and JDK 8. mock(CreditCard.class) results in:

java.lang.VerifyError: Expecting a stackmap frame at branch target 49
Exception Details:
  Location:
    io/card/payment/CreditCard.toString()Ljava/lang/String; @39: ifgt

Was able to workaround the issue with jvmArgs '-noverify' as mentioned above.

justinmuller avatar Feb 02 '17 07:02 justinmuller

We're also seeing the same issue with 5.5.1, although workarounds previously mentioned do work (although have to configure per test in Android Studio which is rather tedious). I assume given the long time this bug has been open that this is the best we can hope for.

pbayfiel-ford avatar May 23 '17 13:05 pbayfiel-ford

can build library yourself can help to solve the problem?

kotya341 avatar Nov 20 '17 15:11 kotya341

Same problem for me

Vacxe avatar Apr 26 '18 10:04 Vacxe

android studio config

Android stuido->run->Edit Configurations->Edit Defaults->vm options ->add '-noverify'->OK

lotosbin avatar Apr 28 '18 03:04 lotosbin

@lotosbin This solution works for local build but I don't want to create any tricks for CI setup. And also I think that fix for problem is a better way than create additional unnecessary solution.

Vacxe avatar Apr 28 '18 07:04 Vacxe

@braebot this project still alive yet?

Vacxe avatar May 04 '18 03:05 Vacxe

@vacxe you can fix it either with jvmArgs '-noverify', or by moving away from Robolectric. This problem is 3 years old, there's nothing more to discuss. Card.io is not the only lib that triggers this bug.

Dimezis avatar May 04 '18 06:05 Dimezis