Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Once again getting java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i after updating to Support Tools 23

I had implemented one of the many solutions listed on https://code.google.com/p/android/issues/detail?id=78377 for this issue with 4.2.2 phones but now that I've updated to support tools 23 the issue has come back. If you look at that issue report you'll see there are a lot of people with that same issue since updating. The solutions on NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder also don't work because they come from https://code.google.com/p/android/issues/detail?id=78377

This is the exception I'm getting:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
       at android.support.v7.widget.ActionMenuView.getMenu(ActionMenuView.java:643)
       at android.support.v7.widget.Toolbar.ensureMenu(Toolbar.java:876)
       at android.support.v7.widget.Toolbar.getMenu(Toolbar.java:847)
       at android.support.v7.internal.widget.ToolbarWidgetWrapper.getMenu(ToolbarWidgetWrapper.java:702)
       at android.support.v7.internal.app.ToolbarActionBar.getMenu(ToolbarActionBar.java:583)
       at android.support.v7.internal.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:441)
       at android.support.v7.internal.app.ToolbarActionBar$1.run(ToolbarActionBar.java:65)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
       at android.view.Choreographer.doCallbacks(Choreographer.java:579)
       at android.view.Choreographer.doFrame(Choreographer.java:547)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
       at android.os.Handler.handleCallback(Handler.java:800)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:194)
       at android.app.ActivityThread.main(ActivityThread.java:5391)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:525)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
       at dalvik.system.NativeStart.main(NativeStart.java)

My proguard has this:

-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}

Any solutions? getting lots of complaints from users.

like image 817
casolorz Avatar asked Oct 15 '15 18:10

casolorz


1 Answers

Your ProGuard "keep class" rule needs to be updated, as the targeted classes are no longer being obfuscated. In version 23 of the support tools, Google moved the menu-related classes out of the internal package. I can confirm that the following ProGuard rules eliminated the NoClassDefFoundError that was being seen on certain Samsung devices running Android 4.2.2.

# Workaround for conflict with certain OEM-modified versions of the Android appcompat
# support libs, especially Samsung + Android 4.2.2
# See this thread for more info:
#   https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=78377
-keepattributes **
# Keep all classes except the ones indicated by the patterns preceded by an exclamation mark
-keep class !android.support.v7.view.menu.**,!android.support.design.internal.NavigationMenu,!android.support.design.internal.NavigationMenuPresenter,!android.support.design.internal.NavigationSubMenu,** {*;}
# Skip preverification
-dontpreverify
# Specifies not to optimize the input class files
-dontoptimize
# Specifies not to shrink the input class files
-dontshrink
# Specifies not to warn about unresolved references and other important problems at all
-dontwarn **
# Specifies not to print notes about potential mistakes or omissions in the configuration, such as
# typos in class names or missing options that might be useful
-dontnote **

I strongly recommend that you use dex2jar and jd to confirm that the desired obfuscation has happened (described here: https://stackoverflow.com/a/10191338/315702). Unfortunately, this should be done each time you upgrade the support tools, in case packages are moved or renamed again.

Google moved the classes out of the "internal" package in the hope that this would avoid the classpath conflict that causes the NoClassDefFoundError. However, as Chris Banes stated on the thread for this bug (https://code.google.com/p/android/issues/detail?id=78377), they did not test to verify the fix -- and lots of people have since reported the same crash you're seeing:

Right, we've decided to do a one-time rename of the internal classes which should fix this. I have done no testing on those devices though, and don't plan on doing any either.

like image 103
Mark McClelland Avatar answered Oct 01 '22 19:10

Mark McClelland