Unexpected crash in BaseDexClassLoader
Asked Answered
I

1

11

This crash has happened to 1800 users of our app with 1.2 monthly active users (according to Google Developer Console). Quite rare, but it occurs.

Android 4.1 up to 6, but NO Android 7 in reports.

What might be the nature of this ClassNotFoundException in BaseDexClassLoader. Can we avoid it?

java.lang.RuntimeException: at android.app.LoadedApk.makeApplication(LoadedApk.java:572) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4831) at android.app.ActivityThread.access$1500(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531)
at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5637) at java.lang.reflect.Method.invoke(Method.java:0) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

Caused by: java.lang.ClassNotFoundException: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at android.app.Instrumentation.newApplication(Instrumentation.java:985)
at android.app.LoadedApk.makeApplication(LoadedApk.java:567)

Impede answered 31/5, 2017 at 7:39 Comment(12)
#15687093Laurenelaurens
post your gradle file if possibleLaurenelaurens
Do you have a <receiver> in the Manifest which listen for connectivity changes or one that can be started by the system automatically?Harmonie
No, we are not using custom class loader implementation.Impede
Unfortunately we cannot post gradle file due to security concerns.Impede
@MatPag, yes we do have receivers in Manifest. The one that is called on android.intent.action.BOOT_COMPLETED Also we are using proguard to cover most of our code. Could this be the cause?Impede
That's the problem probably. I will add an explanation when i go home but i think there is no real solutions for thisHarmonie
@Harmonie we are likely facing the same issue, could explain how receivers could possibly cause this. Will help us identify if that is indeed the reason, and how to handle it.Joan
btw, does it have anything to do with multidexing or build tool version 25?Joan
@Joan we are building with multidexing + build tool version 25.Impede
We started getting these errors after we switched to multidexing and build-tool version 25. So, it could be because of one of these two. Two days ago I started a rollout without mutidexing - the frequency seems lesser but have got a couple of exceptions there as well. So wondering if it is because of the build tool 25. @Pavel, how does your experience correlate to this?Joan
I've added the answer as promisedHarmonie
H
26

NOTE: The answer below could be inaccurate and not verifiable, because this Exception is pretty impossibile to simulate in a test environment. If someone has more informations on the topic or maybe a definitive solution please post it here. I apologize in advance if this informations will be proved to be false at all but they are based on my experience and understanding of the thing

There are multiple variants of the java.lang.ClassNotFoundException in Android, most of them are caused by a wrong Proguard configuration, IDE not closing correctly the previous launched instance of the device during build time etc...

All of this "normal" ClassNotFoundExceptions are distinguishable because in some part of the exception there is something related to the app itself like:

java.lang.RuntimeException: Unable to instantiate application com.my.package.CustomApplication: java.lang.NullPointerException

or

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.my.package/com.my.package.MyClass}: java.lang.ClassNotFoundException: Didn't find class "com.my.package.MyClass" on path: DexPathList[[zip file "/data/app/com.my.package-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.my.package-1, /vendor/lib, /system/lib]]

While the one you are facing it's something not related at all with your application because it's clear there are no references to your app components. It's a bug in how the system load the APKs and try to execute some of your code (like a Receiver) when your app is uninstalled and reinstalled because of an update.

What i think it's happening here is:

  1. The app is installed
  2. The system wants to start one of your components (for example a <receiver>)
  3. The app is uninstalled because of a new update (this step should last only few seconds)
  4. The system is not able to find anymore your app and throw the error you posted
  5. The update is installed and your app start working again

This combination of factors could explain why you have only "few" crashes considering the total active users.

What can you do about this? I think pretty nothing because it's a fault in how the system handle this special case. This comment in one of the multiple related issues has the same conclusion.

You could try to create a custom ClassLoader where you can handle the Exception by yourself and terminate the app process silently without crashing the app, in this way your users shouldn't noticing anything (i don't know if the user is really noticing this, maybe it's an internal exception handled by the system and the user doesn't see nothing)

The fact that you did not encounter reports for Android 7 could be a sign that they fixed the problem in the latest Android version of LoadedApk class

PS: Sincerely i don't think this is related to multidexing, but you can perform some tests to be sure

Harmonie answered 2/6, 2017 at 9:13 Comment(9)
Wow, just wow. Thank you for this a wonderful article. It all makes sense. I'm accepting the answer.Impede
Seems plausible.Joan
There is something unexplained though - if the explanation were correct, we would have seen more of these errors earlier, and a lot of google-play-apps would have been affected. The lack of this question earlier on stackoverflow, and the fact that I also started seeing this recently remains unexplained.Joan
Have you changed your manifest recently? Try using build tools 24 for the next update and see if something changes.Harmonie
Yes, it started after a few changes in manifest - mutidex and build too 25 included. I have switched to single-dex again, and the crashes have reduced about 8x, but that could also be because multidexed apps have longer installation time? Will try a different build tool version next time.Joan
Not sure if same issue. My app is crashing when it tries to run a second process (like from Firebase) while "dex2oat" of the first is running. When I run a build without minifying it, where "dex2oat" takes a lot of time, then it's guaranteed to crash. If I minify it, and "dex2oat" is fast, the app runs without any issues. Newer devices have a MUCH faster "dex2oat" ("dexopt"), so the issue is not common on them.Shipper
The stacktrace is the same as the question?Harmonie
@Harmonie Not exactly the same. But shares the "caused by ClassNotFoundException" part. I noticed that different devices throw different exceptions in different parts. But minifying solves the problem for all cases.Shipper
I think you've nailed this problem for non-multidex cases. Circumstantial evidence: my apps virtually never get this between updates - but when I push an update to Play, there's always a cluster of these. QED, it's something going wrong in the update process, and the explanation here is quite plausible. Bravo!Golgi

© 2022 - 2024 — McMap. All rights reserved.