card.io-Android-SDK
card.io-Android-SDK copied to clipboard
java.lang.VerifyError when unit testing Card.IO with Robolectric
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:
- Clone this repository: https://github.com/fcduarte/deckard-gradle/tree/card-io
- On the root of the repo run
./gradlew testDebug
- Check the result at
file:///<path-to-repo>/deckard-gradle/build/reports/tests/debug/index.html
The changes:
https://github.com/fcduarte/deckard-gradle/pull/1
This is odd. Did you try JDK 7?
I've just forced JDK 7:
https://github.com/fcduarte/deckard-gradle/commit/41f524fbb19227df22dd419d3e8e1eddffa1e7b4
same error.
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.
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.
@tomwhipple when do you think that it's gonna be the fix?
@braebot @tomwhipple any update on this? I'm seeing a crash using JUnit on android unit test framework as well.
@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, 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.
@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.
how can add this to gradle for ci to work?
@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.
I have the same issue.
Works fine with -noverify
tho
@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 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
@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.
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.
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.
can build library yourself can help to solve the problem?
Same problem for me
android studio config
Android stuido->run->Edit Configurations->Edit Defaults->vm options ->add '-noverify'->OK
@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.
@braebot this project still alive yet?
@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.