Lambda call on Android randomly fails - android

Just started using lambdas in a new project and stuck with the issue when app crashes with the following stack trace:
I/art: Rejecting re-init on previously-failed class java.lang.Class<com.test.-$Lambda$3>
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test, PID: 18852
java.lang.NoClassDefFoundError: com.test.-$Lambda$3
... method which calls lambda ...
The interesting thing is it works sometimes but I still can't figure out what makes it work and what breaks.
jackOptions and 1.8 compatibility are both enabled in build.gradle. compileSdkVersion is 25. Device is running Android 5.0. The resulting apk has this com.test.-$Lambda$3class defined.
Is there anything that should be done in addition to completely enable lambdas? How to debug this issue to find out the real root cause?
Update 1:
It sounds pretty strange but looks like compiler messes with lambda calls. Say the resulting APK has $Lambda$1:Runnable and $Lambda$2:Consumer defined and I see particular method calls $Lambda$1 while it has to be $Lambda$2.

Related

Issues running obfuscated DEX modules - AbstractMethodError

I'm developing an Android application based on a main APK installed on the mobile device, and some android modules that are compiled to a .dex file. These files are loaded at runtime by the main application and the classes inside the .dex files are instantiated via Dynamic Dex Loading.
I'm facing some issues related to proguard, as even if I use the #Keep annotation on exposed methods in the modules and the main APK and I tell to proguard to keep interfaces methods, when I call one of the methods implemented in a module i get:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.myproject, PID: 13893
java.lang.AbstractMethodError: abstract method "z.a com.android.myproject.MyClass.mymethod()"
at com.android.myproject.MainService.H(:784)
at com.android.myproject.MainService.M(:258)
at com.android.myproject.MainService.a0(:198)
at com.android.myproject.MainService.U(:148)
at com.android.myproject.MainService.C(:133)
at com.android.myproject.MainService.onServiceConnected(:90)...
If i try to debug, and i place a breakpoint right on the method call, using the "Evaluate Expression" tool in Android Studio I'm able to call the method with success, but if I let it execute on its own it crashes with the previous exception.
Can someone help me please? Thank you very much

NoClassDefFoundError ObjenesisStd on Android API 19

I'm getting the following crashing during an instrumentation test ONLY on emulators running API v19. If I run on newer versions everything works fine.
03-01 20:26:18.781 2878-2878/? E/MonitoringInstrumentation: Exception
encountered by: Thread[main,5,main]. Dumping thread state to outputs
and pining for the fjords.
java.lang.NoClassDefFoundError: org.objenesis.ObjenesisStd
at org.mockito.internal.creation.jmock.ClassImposterizer.(ClassImposterizer.java:36)
at org.mockito.internal.creation.jmock.ClassImposterizer.(ClassImposterizer.java:29)
at org.mockito.internal.util.MockCreationValidator.isTypeMockable(MockCreationValidator.java:17)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:21)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:133)
at org.mockito.internal.creation.MockSettingsImpl.confirm(MockSettingsImpl.java:127)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:50)
at org.mockito.Mockito.mock(Mockito.java:1243)
at org.mockito.Mockito.mock(Mockito.java:1120)
The problem is this line:
java.lang.NoClassDefFoundError: org.objenesis.ObjenesisStd
My app is multi-dex, and I'm using dexmaker-mockito for androidTestCompile. I'm at a complete loss why this only breaks on an older API. It started happening when I added another module to my project, which is a pure java module with no dependency on mockito.
This exception (ClassNotFoundException) tells you about a unmet dependency at runtime: the JVM needs to load a class; which is not present in the class path.
Here it is Mockito that needs Objenesis. Normally that library should be pulled automatically when you a system like maven and give the correct dependency to Mockito.

java.lang.noclassdeffounderror with libgdx and Android studio on the androidLauncher

I imported a package of my own called server (the logic of my program) and was going to use libgdx for the graphics/cross platform. The desktop launcher works fine but when I run the android launcher I get this nasty error referring to my own library.
E/AndroidRuntime: FATAL EXCEPTION: GLThread 187
Process: com.mygdx.game, PID: 8093
java.lang.NoClassDefFoundError: server.Point
at server.Shape.<init>(Shape.java:9)
at server.T.<init>(T.java:7)
at server.Stack.<init>(Stack.java:28)
at server.Logic.<init>(Logic.java:14)
at com.mygdx.game.GameLoop.create(GameLoop.java:43)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:275)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1511)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
any help would be great
I solved it!
It was because I was using java.awt.point in the android build. So I basically wrote a new point class, replace it, and then cleaned my project. Everything works now

VerifyError in multidex app when injecting dependency with Dagger

A sample app for library has ~67k methods. It has multidex enabled to overcome the 65k method limit. Unfortunately with multidex enabled the app crashes on VerifyError when trying to inject EndpointAdapter in main activity.
This issue doesn't occur when the app is proguarded and the multidex is disabled, so it must be caused by multidex and Dagger 1 problems.
I'm sure EndpointAdapter is in the main dex file, but some classes generated by Dagger are located in the second dex file generated by multidex. This issue occurs on devices with API < 21 (eg. on genymotion with KitKat 4.4.4).
Any idea why it crashes with VerifyError?
FATAL EXCEPTION: main
Process: pl.toro.libsample.debug, PID: 11775
java.lang.VerifyError: pl/toro/lib/network/EndpointAdapter
at java.lang.Class.getDeclaredConstructors(Native Method)
at java.lang.Class.getDeclaredConstructors(Class.java:574)
at dagger.internal.loaders.ReflectiveAtInjectBinding.getConstructorsForType(ReflectiveAtInjectBinding.java:232)
at dagger.internal.loaders.ReflectiveAtInjectBinding.create(ReflectiveAtInjectBinding.java:168)
at dagger.internal.FailoverLoader.getAtInjectBinding(FailoverLoader.java:74)
at dagger.internal.Linker.createBinding(Linker.java:224)
at dagger.internal.Linker.linkRequested(Linker.java:141)
at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:309)
at dagger.ObjectGraph$DaggerObjectGraph.inject(ObjectGraph.java:279)
at pl.toro.lib.app.BaseApplication.inject(BaseApplication.java:135)
...
Here's output of the MultiDex tag
VM with version 1.6.0 does not have multidex support
install
MultiDexExtractor.load(/data/app/pl.toro.libsample.debug-1.apk, false)
Detected that extraction must be performed.
Extraction is needed for file /data/data/pl.toro.libsample.debug/code_cache/secondary-dexes/pl.toro.libsample.debug-1.apk.classes2.zip
Extracting /data/data/pl.toro.libsample.debug/code_cache/secondary-dexes/pl.toro.libsample.debug-1.apk.classes-1477675005.zip
Renaming to /data/data/pl.toro.libsample.debug/code_cache/secondary-dexes/pl.toro.libsample.debug-1.apk.classes2.zip
Extraction success - length /data/data/pl.toro.libsample.debug/code_cache/secondary-dexes/pl.toro.libsample.debug-1.apk.classes2.zip: 187777
load found 1 secondary dex files
install done
EDIT
I've switched to Dagger 2 and this issue is resolved as of now. Dagger 2 no longer uses reflection which is the major factor of this issue.
As pointed out in this blog post[1], are you creating the dagger graph after installing the multi-dex. So in MultiDexApplication#attachBaseContext after the call to super (or calling MultiDex.install() yourself).
[1] https://developers.soundcloud.com/blog/congratulations-you-have-a-lot-of-code-remedying-androids-method-limit-part-2

NoClassDefFoundError - Rejecting re-init on previously-failed class

Please somebody explain me what this error means and how to avoid it.
After a while my app Force Closes because of this error:
09-28 12:53:45.746 I/dalvikvm(29489): Rejecting re-init on previously-failed class Lcom/bartat/android/ui/task/AsyncTaskExt; v=0x0
09-28 12:53:45.748 D/AndroidRuntime(29489): Shutting down VM
09-28 12:53:45.755 I/am_crash( 1146): [29489,com.bartat.android.secret,572996,java.lang.NoClassDefFoundError,com.bartat.android.ui.task.AsyncTaskExt,CommandsActivity.java,726]
09-28 12:53:45.755 I/am_finish_activity( 1146): [1079225264,123,com.bartat.android.secret/.CommandsActivity,crashed]
09-28 12:53:45.750 W/dalvikvm(29489): threadid=1: thread exiting with uncaught exception (group=0x40015560)
09-28 12:53:45.752 E/AndroidRuntime(29489): FATAL EXCEPTION: main
09-28 12:53:45.752 E/AndroidRuntime(29489): java.lang.NoClassDefFoundError: com.bartat.android.ui.task.AsyncTaskExt
This problem couldn't be solved by reinstalling the app.
If I rename the AsyncTaskExt to AsyncTaskExt2 for example then it works again for long. But after a few weeks/months it started to get this error again.
What does it mean? Why it is thrown and how to avoid it without renaming the class?
Please help me,
Tamás
Happens for me only if instant run is enabled.
This happens when a class couldn't be loaded for a variety of reasons. Unfortunately the new ART runtime doesn't log sufficient information as to the cause of this. If you can get hold of an older android device with Dalvik you'll see different logging, usually revealing the offence with more precision.
Last time I saw it live I had to deal with a JAR file that didn't actually include or list its dependencies, so adding the right dependent library to the gradle file solved it. The biggest issue is to figure which classes went missing - something dalvik logs/decompilation/documentation might be able to tell you.
There are many other reasons why classes can't be loaded in the entirety of the Java language so this specific cause might not apply universally.
I started having this problem after building another project with New Relic analytics enabled. Gradle daemon then cached the New Relic agent and it couldn't launch the other app.
What helped was
./gradlew --stop
you must add uses-library in your AndroidManifest.xml
Are you sure is this the first exception you are getting after running your application?
There may be some uncaught exceptions previously.

Categories

Resources