14

I am using latest Facebook Android SDK and getting that error from dozens of users in my remote crash control app in my latest released apk. I have looked here for such error, but most of the answers are too outdated for last FB SDK, and in this case there are two weird circumstances:

a) The error seems to happen randomly. I have been unable to reproduce it at all on none of my devices.

b) There were no changes in FB logic at all between that release and the previous one, and in the previous release I have never had such error.

Since I couldn't find any relevant difference in the code between such versions, I thought the problem was something wrong could have happened with Android Tools while generating the last apk, but giving the fact that very same apk is the one I am using and have been unable to reproduce the problem and, despite dozens or users are affected, hundreds using the same apk aren't, I discarded also such hypothesis.

Any ideas on how to solve or just debug this thing are welcome.

More info that could be relevant:

  • All crashes happened in Android 4.0.3 or older. The highest percentage is for 2.3.6 with 48% of all the crashes.
  • That class is actually exported in the APK. I have checked it by unzipping the apk and using dexdump to see what is inside classes.dex. I couldn't expected other thing, since it works perfectly in all my devices and if the class weren't there, it would not.

    $ ~/android-sdks/build-tools/21.1.1/dexdump classes.dex | grep 'com.facebook.internal.Utility$1' Class descriptor : 'Lcom/facebook/internal/Utility$1;' #0 : (in Lcom/facebook/internal/Utility$1;) #1 : (in Lcom/facebook/internal/Utility$1;) #2 : (in Lcom/facebook/internal/Utility$1;) #0 : (in Lcom/facebook/internal/Utility$1;) #0 : (in Lcom/facebook/internal/Utility$1;) #1 : (in Lcom/facebook/internal/Utility$1;) #2 : (in Lcom/facebook/internal/Utility$1;) #3 : (in Lcom/facebook/internal/Utility$1;)

  • It seems to fail after an invocation of a Utility's static method from loadAppSettingsAsync, that happens to be a static method within the same class. So, if the com.facebook.internal.Utility class does not exist or couldn't be loaded, how it is possible that com.facebook.internal.Utility.loadAppSettingsAsync is executed in first place? and if it exists and it is loaded, why is NoClassDefFoundError thrown on com.facebook.internal.Utility? I am so f* lost...

Here the stack from splunk mint (formerly known as bugsense), I just changed the name of the app. I retraced it with the proguard map file, but it seems it missed some line numbers anyway:

java.lang.NoClassDefFoundError: com.facebook.internal.Utility$1
    at com.facebook.internal.Utility.void loadAppSettingsAsync(android.content.Context,java.lang.String)(Unknown Source)
    at com.facebook.Settings.void sdkInitialize(android.content.Context)(Unknown Source)
    at com.facebook.UiLifecycleHelper.<init>(Unknown Source)
    at net.iberdroid.androidgames.framework.impl.AndroidGame.void onCreate(android.os.Bundle)(Unknown Source)
    at com.marzoa.ruletafree.xmas2012.RuletaAfortunadaGame.void onCreate(android.os.Bundle)(Unknown Source)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1050)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1623)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675)
    at android.app.ActivityThread.access$1500(ActivityThread.java:121)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3770)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: com.facebook.internal.Utility$1 in loader dalvik.system.PathClassLoader[/data/app/com.marzoa.ruletafree.xmas2012-2.apk]
    at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    ... 18 more
Fran Marzoa
  • 4,293
  • 1
  • 37
  • 53

2 Answers2

5

As the NoClassDefFoundError occurs in loadAppSettingsAsync at an anonymous implementation of AsyncTask it seems to be the same problem like this NoClassDefFoundError - Android 2.3.X

Its a bug in google play services. (https://code.google.com/p/android/issues/detail?id=81083)

Try to add following into your Application#onCreate() method as described in the answer of the referred issue.

try {
    Class.forName("android.os.AsyncTask");
}
catch(Throwable ignore) {
    // ignored
}
Community
  • 1
  • 1
Udo
  • 302
  • 2
  • 11
  • This seems to make some sense. Let me try to release a new version with that workaround to see what happen. Anyway, wouldn't it have side effects? I meant, ignoring the exception will not change the fact that such class is needed and it is not downloadable... – Fran Marzoa Dec 22 '14 at 16:37
  • 1
    There should be no side effect. This workaround simply assures that the classloader loads this class explicitly into memory to avoid the play services bug. `AsyncTask` is a component of the android system and definitely available on every device. – Udo Dec 29 '14 at 08:04
  • Hello, I am getting issue because of the FacebookSdk. What should i have to do to resolved this issue? I have try above method but it is not working. – Shreyash Mahajan Jul 20 '15 at 10:13
  • @Fran Hi, how is the result? do you fix it? I met the same problem, cause it not AsyncTask can't found, so I think maybe that's not the case "Udo" said. – Michael Jan 13 '17 at 09:37
  • Where can I find Application#onCreate() this method? – S. M. Asif May 28 '22 at 07:03
3

Firstly, be sure that you are checking for the right class. According to the error message, the "missing" class is com.facebook.internal.loadAppSettingsAsync$1. Note the $1!! That means we are talking about an anonymous inner class that is declared within the Utility.loadAppSettingsAsync.

Second, java.lang.NoClassDefFoundError can have a number of causes:

  • The class may be missing.

  • The class could be present but unloadable for some reason.

  • The class could be loadable, but a previous attempt to initialize it ... or some dependent class ... has failed.

The last case typically happens if a static initialization or static initializer block throws an unchecked exception the first time it was run. (You will typically a log message for this exception.) Once the class initialization has failed once, the class is marked as broken. This stops the class and any other classes that depends on it from being initialized.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Actually that's not the "missing" class, but com.facebook.internal.Utility$1, and I am sure about having checked for it (I have edited the question to add the result of a dexdump with a grep). – Fran Marzoa Dec 16 '14 at 11:38
  • As far as I have been able to reproduce the crash, whatever reason the class maybe unloadable is beyond my debugger. I don't have access to the log of my users remotely neither... :-| – Fran Marzoa Dec 16 '14 at 11:43
  • Ask one of your users to send you the log file. Or buy an old Android phone and try to reproduce the problem yourself. – Stephen C Dec 16 '14 at 12:18
  • Actually I have one Galaxy Y older than my grandfather, but it does not fail. Not that phone, not every emulator I have run. On the other hand I do not collect information from my users, so I have no way to associate a crash with an user so I can contact him/her. Anyway, I am looking at the code of that library right now. – Fran Marzoa Dec 16 '14 at 12:37
  • Where it says before "As far as I have been able to reproduce the crash" I actually mean "As far as I have NOT been able to reproduce the crash", although I think it was clear due context. – Fran Marzoa Dec 16 '14 at 16:38
  • You say "Once the class initialization has failed once, the class is marked as broken." Is there anyway I could check inside the code if that's the case? I think I could add that information to my bugsense report together with the stack dump. – Fran Marzoa Dec 18 '14 at 11:30
  • In loadAppSettingsAsync the only anonymous inner class is an anonymous implementation of AsyncTask without any static initialization. As an anonymous class is only used locally the crash should occur on first run. So I would exclude the third option, because this anonymous class could not be initialized at any other place. – Udo Dec 19 '14 at 10:42
  • @Fran - I don't think so. In fact, I think it is impossible for application code to get hold of a `Class` object for a class whose class initialization has failed. – Stephen C Dec 19 '14 at 14:17