Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackWalker.Option not found on Mockito 5.1.0 #2890

Closed
4 tasks done
sergiandreplace opened this issue Jan 30, 2023 · 12 comments · Fixed by #2891
Closed
4 tasks done

StackWalker.Option not found on Mockito 5.1.0 #2890

sergiandreplace opened this issue Jan 30, 2023 · 12 comments · Fixed by #2891

Comments

@sergiandreplace
Copy link

sergiandreplace commented Jan 30, 2023

We have an Android project using Mockito and we tried to upgrade from 5.0.0 to 5.1.0.

When running the Android tests we always receive an error like this:

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/StackWalker$Option;
	at org.mockito.internal.debugging.LocationImpl.stackWalker(LocationImpl.java:138)
	at org.mockito.internal.debugging.LocationImpl.<clinit>(LocationImpl.java:40)
	at org.mockito.internal.debugging.LocationFactory.create(LocationFactory.java:17)
	at org.mockito.internal.debugging.LocationFactory.create(LocationFactory.java:13)
	at org.mockito.internal.matchers.LocalizedMatcher.<init>(LocalizedMatcher.java:19)
	at org.mockito.internal.progress.ArgumentMatcherStorageImpl.reportMatcher(ArgumentMatcherStorageImpl.java:30)
	at org.mockito.ArgumentMatchers.reportMatcher(ArgumentMatchers.java:1036)
	at org.mockito.ArgumentMatchers.any(ArgumentMatchers.java:177)
	...

After some investigation we found that:

  • StackWalker is only available from Java 9. All our modules are setup to use Java 11.
  • We can't see StackWalker class from the IDE
  • This only happens on Android instrumental tests, not in "normal" java tests
  • The class StackWalker is not available in Android SDK java implementation: https://github.com/AndroidSDKSources/android-sdk-sources-for-api-level-33/tree/master/java/lang (that would explain why is not working only for instrumental tests, as they are executed on an Android device). Checked for latest android versions.

It looks like a very specific Android issue.

For the meantime, we will halt the upgrade, but any help will be great.

Thanks in advance

  • The mockito message in the stacktrace have useful information, but it didn't help
  • [N/A] The problematic code (if that's possible) is copied here;
    Note that some configuration are impossible to mock via Mockito
  • Provide versions (mockito / jdk / os / any other relevant information)
  • Provide a Short, Self Contained, Correct (Compilable), Example of the issue
    (same as any question on stackoverflow.com)
  • Read the contributing guide
@TimvdLippe
Copy link
Contributor

Two questions:

  1. Are you using mockito-android?
  2. Does a later version of Android ship the API?

@zsoltvilagos
Copy link

@TimvdLippe I hope @sergiandreplace doesn't mind if I answer.

We're also using Mockito and ran into the very same problem.

  1. Are you using mockito-android?
    We're using mockito-android, same version 5.1.0 as mockito-core.
  1. Does a later version of Android ship the API?

Nope. API 33 is the latest version, Android 13.

@SmasSive
Copy link

@TimvdLippe a colleague of Sergi here! Yes, we are using mockito-android (5.1.0 same version of core).
And as @zsoltvilagos said, no... The latest version of Android (SDK 33) does not include the API.

@TimvdLippe
Copy link
Contributor

@reta if I understand correctly, we would have to revert the StackWalker change, but that would break your integration with the SecurityManager. Can we figure out a solution that would satisfy both?

@reta
Copy link
Contributor

reta commented Jan 30, 2023

@TimvdLippe unexpected, but I agree, we probably have to revert at least the StackWalker changes and use the reflection for Android, sorry about that. I could look into it tonight if that is fine with you. Thank you.

Can we figure out a solution that would satisfy both?

Yes, I believe we can

TWiStErRob added a commit to TWiStErRob/repros that referenced this issue Jan 30, 2023
@TWiStErRob
Copy link
Contributor

Here's a minimal repro in case you want to test things out (or add an integration test for a basic case):

  1. https://github.com/TWiStErRob/repros/tree/master/mockito/mockito5_StackWalkerOption
  2. Unit Tests: gradlew testDebugUnitTest
    report: ./build/reports/tests/testDebugUnitTest/index.html
  3. Instrumentation Tests: gradlew connectedCheck
    report: ./build/reports/androidTests/connected/index.html
  4. Instrumentation Tests (alternative): gradlew pixel2api33DebugAndroidTest
    report: ./build/reports/androidTests/managedDevice/allDevices/index.html

Note: connectedCheck and pixel2api33DebugAndroidTest are almost equivalent, but pixel2api33DebugAndroidTest only needs an SDK installed, it will download and set up the emulator automatically.

I used a realistic but pointless mocking setup, also it repros using just mock() too.

Results

Mockito 5.1.0 (committed to repro):

  • gradlew testDebugUnitTest: ✅ passes
  • gradlew connectedCheck: ❌ fails
    NoClassDefFoundError: Failed resolution of: Ljava/lang/StackWalker$Option;
  • gradlew pixel2api33DebugAndroidTest: ❌ fails
    NoClassDefFoundError: Failed resolution of: Ljava/lang/StackWalker$Option;

Mockito 5.0.0 (for control, change def mockito in build.gradle):

  • gradlew testDebugUnitTest: ✅ passes
  • gradlew connectedCheck (API 21): ❌ fails
    NoClassDefFoundError: org.mockito.internal.invocation.TypeSafeMatching$$ExternalSyntheticLambda0
  • gradlew connectedCheck (API 31): ✅ passes
  • gradlew pixel2api33DebugAndroidTest (API 33): ✅ passes

Mockito 4.11.0 (for control, change def mockito in build.gradle):

  • gradlew testDebugUnitTest: ✅ passes
  • gradlew connectedCheck (API 21): ❌ fails
    NoClassDefFoundError: org.mockito.internal.invocation.TypeSafeMatching$$ExternalSyntheticLambda0
  • gradlew connectedCheck (API 31): ✅ passes
  • gradlew pixel2api33DebugAndroidTest (API 33): ✅ passes

For reference: https://developer.android.com/reference/classes doesn't have StackWalker.

@TimvdLippe
Copy link
Contributor

FWIW we started an effort to set up some basic Android tests for us: https://github.com/mockito/mockito/tree/main/subprojects/androidTest However, this stalled as we couldn't get it to work on CI. If anybody affected here would like to dedicate some time to prevent these kind of issues from happening, please take a look at the existing test suite and infrastructure and submit a PR to get it passing on CI.

reta added a commit to reta/mockito that referenced this issue Jan 30, 2023
Signed-off-by: Andriy Redko <drreta@gmail.com>
reta added a commit to reta/mockito that referenced this issue Jan 30, 2023
Signed-off-by: Andriy Redko <drreta@gmail.com>
TimvdLippe pushed a commit that referenced this issue Jan 30, 2023
Fixes #2890 

Signed-off-by: Andriy Redko <drreta@gmail.com>
@zsoltvilagos
Copy link

@TimvdLippe @reta Thanks a lot of the awesome fast reaction & fix. Great.

@sergiandreplace
Copy link
Author

Wow, that was fast. Thanks a lot for the solution!

@TWiStErRob
Copy link
Contributor

TWiStErRob commented Jan 31, 2023

Confirmed working on the PR I had linked above.
Thanks for the quick turnaround.

Is there a tracking issue for Android CI?
I have a working GHA with Espresso tests (the key was running on Mac):
https://github.com/TWiStErRob/net.twisterrob.colorfilters/blob/master/.github/workflows/CI.yml#L177

@reta
Copy link
Contributor

reta commented Jan 31, 2023

@TWiStErRob thank you!

Is there a tracking issue for Android CI?

Yes, #2892

@TWiStErRob
Copy link
Contributor

A quick update for watchers and posterity.

The above problem was caused by removing Java 8 support in this PR, and the fix was to partially revert the removal.

After the fix and patch release, we added Android CI with reta (reviewed by TimvdLippe):


@Androids, could you please take a look if you agree the these are sufficient to prevent future breakages like this issue?

CI:

#
# Android build job
#
android:
runs-on: macos-latest
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
# Definition of the build matrix
strategy:
matrix:
include:
# Minimum supported
- android-api: 26
android-image-type: default
# Maximum available
- android-api: 33
android-image-type: google_apis
# All build steps
steps:
- name: 1. Check out code
uses: actions/checkout@v3
with:
fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci
- name: 2. Set up Java 11
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 11
- name: 3. Run Android tests on Android API level ${{ matrix.android-api }}
uses: reactivecircus/android-emulator-runner@v2
with:
arch: x86_64
api-level: ${{ matrix.android-api }}
target: ${{ matrix.android-image-type }}
script: ./gradlew :androidTest:connectedCheck --no-daemon --no-build-cache

Android Integration test project: https://github.com/mockito/mockito/tree/main/subprojects/androidTest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants