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

Andriod API < 24 -> NoClassDefFoundError: Failed resolution of: Ljava/util/Optional; #2075

Closed
yogurtearl opened this issue Oct 23, 2020 · 4 comments

Comments

@yogurtearl
Copy link

yogurtearl commented Oct 23, 2020

With mockito-android 3.5.15 on Android API 23 we are getting this error below, it works fine with 3.4.6

Turning on coreLibraryDesugaring would likely fix this for API 23, but that might not be a viable option for all builds.
https://developer.android.com/studio/releases/gradle-plugin#j8-library-desugaring

java.util.Optional wasn't added to Android until API 24 (see the Android docs for which API level a given class or method was added in):
https://developer.android.com/reference/java/util/Optional

Stacktrack.

at org.mockito.plugins.MockMaker$-CC.$default$createSpy(MockMaker.java:93)
at com.android.dx.mockito.DexmakerMockMaker.createSpy(DexmakerMockMaker.java)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:45)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:61)
at org.mockito.Mockito.spy(Mockito.java:2033)
at com.nhaarman.mockitokotlin2.SpyingKt.spy(Spying.kt:52)

...

Caused by: java.lang.ClassNotFoundException: Didn't find class "java.util.Optional" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.example.test-1/base.apk", 6, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
... 46 more
Suppressed: java.lang.ClassNotFoundException: java.util.Optional
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 47 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
@TimvdLippe
Copy link
Contributor

Is this a duplicate of #2007?

@alsutton
Copy link

alsutton commented Nov 6, 2020

I think it's something different because we're seeing a very similar issue and have pinned the version of objenesis to 2.6.

We have the following hierarchy; InterfaceA -> InterfaceB -> InterfaceC<Type>, using 3.5.13 we see;

Run all tests in project; Two test classes fail to create mocks of InterfaceA, with NoClassDefFoundError for InterfaceA$MockitoMock$1225627330
Run all test methods in both classes; All tests pass
Run individual test methods; All tests pass

Using 3.4.6 all tests pass in all three scenarios.

We've create a workaround which is to create a fake class which implements InterfaceA and then mock that, which works in 3.5, but it seems a nasty hack.

When I was creating the fake I did see a NoClassDefFoundError for InterfaceC, which comes from a different gradle project, but I ruled out dependency path issues because the individual classes and methods complete their run, it's only running all the tests in the main project that causes those classes and methods to fail.

@yogurtearl
Copy link
Author

@TimvdLippe this is because Mockmaker is using java.util.Optional.

If you want to support API 23 and older on Android, with coreLibraryDesugaring turned off (which is the default), you can't use java.util.Optional at all.

cmonfortep added a commit to duckduckgo/Android that referenced this issue Jul 24, 2021
* bump libraries

* Mockito fix: spy not supported for api < 24 (mockito/mockito#2075 (comment))

* Remove duplicated kotlin_version

* reference kotlin version from versions.properties file
@TimvdLippe
Copy link
Contributor

I am closing this as WontFix, since Android API level 23 was released over 6 years ago. For older Android APIs, we suggest users to stick to Mockito 2. With Mockito 3, we require Java 8, which has similar limitations to the Android ecosystem with respect to API level.

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

No branches or pull requests

3 participants