NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
Asked Answered
B

10

170

There is an issue with the Android appcompat v7 library on Samsung devices running Android 4.2. I keep getting crashes with the following stack trace in my Developer Console:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
    at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:66)
    at com.[my-package-name].CustomActivity$5.onClick(CustomActivity.java:215)
    at android.view.View.performClick(View.java:4222)
    at android.view.View$PerformClick.run(View.java:17620)
    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(Native Method)
    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(Native Method)

This is line 215 of CustomActivity.java:

PopupMenu popup = new PopupMenu(CustomActivity.this, mImageViewMenu);

The crashes come from an array of devices, but always Samsung, and always Android 4.2.

A quick web search leads me to believe that many people have the same issue, some of the steps I have tried to solve the issue are:

  • Check the Android project properties, make sure the appcompat library is added properly.
  • Check the Java Build Path Order and Export project properties, make sure Android Dependencies and Android Private Libraries is checked.
  • Confirm the class is included in the library (android.support.v7.internal.view.menu.MenuBuilder).
  • Confirm R.java is located in gen directory for android.support.v7.appcompat.
  • Confirm the AppCompat theme is included in the Manifest.xml activity.
  • Clean and rebuild project.

Despite these steps, and despite it working on all other devices and Android versions the crash reports still come through.

Backspin answered 17/7, 2014 at 17:7 Comment(5)
Note: I have also seen this occur on the QMobile X25 which a low end phone out of Pakistan. So it looks like oythers have take the same approach or same ROM as the failed Samsung ROM.Spica
Since both Google and Samsung are not helpful in resolving this HUGE issue, can anyone think of a solution that does not involve Proguard (which raises other issues)?Sleight
Google isn't going to do anything about it since it's Samsung that seems to have made additional modifications causing a name collision between libraries. Proguard avoids the collision. Haven't seen any better solutions on the Android Issue Tracker forum either.Backspin
I can add a QMobile A290, out of Pakistan as well.Bachman
same issue [QMobile X30 - Android 4.4.2]Alfy
E
100

EDIT:

The solution that worked for me was (Using Proguard) to replace this:

-keep class android.support.v4.** { *; } 
-keep interface android.support.v4.** { *; }

-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

with this:

# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}

Credit goes to the google group, #138.

Old answer (Temporary Workaround): It happens in a project where I use an spinner in the ActionBar. My solution was to check for those conditions and change the app flow:

public static boolean isSamsung_4_2_2() {
    String deviceMan = Build.MANUFACTURER;
    String deviceRel = Build.VERSION.RELEASE;
    return "samsung".equalsIgnoreCase(deviceMan) && deviceRel.startsWith("4.2.2");
}

Then in the activity's onCreate method:

if (isSamsung_4_2_2()) {
    setContentView(R.layout.activity_main_no_toolbar);
} else {
    setContentView(R.layout.activity_main);
}

As pointed out this is not a definitive solution, it is just a way to allow users to have access to limited functionality while a more permanent solution is found.

Elum answered 29/10, 2014 at 21:58 Comment(30)
+1 to you. Obviously not ideal, but it works. I'm implementing a similar solution until a permanent fix is in place (not holding my breath).Gammer
What do you mean by "changing the app flow"? Remove the ActionBar?Keyboard
Updated my answer, yes, basically I made a (limited-functionality) version with no ActionBar in the meantimeElum
Can anyone else verify this answer? I don't have access to a Samsung and the app I was working on is no longer active so I can't test it out.Backspin
@JaredBurrows You don't remove the library, you just tell proguard to ignore it by default, with the fix you ignore everything under android.support except for android.support.v7.internal.view.menuElum
@Elum Alright, I am just trying to get some clarity. Thank you!Culbertson
@Elum I'm trying to apply the proguard solution. Is it correct that the goal is to obfuscate the class name of the MenuBuilder class. I've tried to apply it, but only the members end up obfuscated, not the class name.Delindadelineate
@DaveCameron Yes, the goal is to rename the classes under android.support.v7.internal.view.menu. Make sure you don't have conflicting rules in your scriptElum
If no one objects I'm going to mark this as the solution, since I can't test it myself at the moment.Backspin
Does this work if you use the v7 support library from maven? I don't see any reference to android.support.v7 in my mapping.txt. Thus this solution has no effect...Abhorrence
While this obfuscates the MenuBuilder and SubMenuBuidler classes, it also obfuscates ActionMenuItemView which is used by the Toolbar resources in appcompat-v7:21 so you get XML inflation and ClassNotFoundErrorsSpica
@Elum I hate creating new questions, especially when this is exactly the problem I'm having. But none of these suggestions has worked for me, I've tried both the workaround as well as the proguard solution. Is there a way to ensure that the proguard script is running as intended? Why would it not be working?Gaulin
Ok, for those who are trying to use this solution, while in debug mode, you must add minify true, proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' , and zipAlignEnabled true to the debug build type in your gradle file. This will allow you to at least test locally prior to deploying although it is admittedly harder to debug.Gaulin
i have that kind of android phone which have the same samsung ROM which have this issue, it crashes when i start my app upon calling the setSupportedToolbar() method. I am trying to create Slide able Tabs. So how come apps like Whatsapp have tabs and don't crash on my phone?Walczak
I actually got this error on a non-Samsung device: "QMobile i9"Dora
I've been using a solution from that issue report for months now and all of the sudden after updating to the latest support libraries and sdk 23 I've started getting this new report on crashlytics: java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.iEtrem
according to the end of code.google.com/p/android/issues/detail?id=78377, this issue seems to be resurfacing in SDK23Bergstrom
@AdamJ this has supposedly been resolved in support v23.1.1Venita
The issue returned in my app when II upgraded to AppCompat v23. I analyzed the AppCompat v.23.1.1 jar file, and see that they have removed the "internal" directory inside v7, so it seems the Proguard instruction line should be now: [ -keep class !android.support.v7.view.menu.**,android.support.** {*;} ] I still don't have a confirmation from tests on a real device where the problem happened. Could anyone with such a device test this? Or maybe the removal of 'internal' dir is actually the fix for the issue and we don't need to mess with Proguard class renaming anymore?Emmaline
Add this to your proguard settings, it will solve the problem: FOR APPCOMPAT 23.1.1: -keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { ; } -keep interface android.support.v7.* { ; } FOR OLDER APPCOMPAT VERSION: -keep class !android.support.v7.internal.view.menu.*MenuBuilder, android.support.v7.** { ; } -keep interface android.support.v7.* { *; }Griffin
@AndreaBellitto Why do we still need to add such things?Dora
@AndreaBellitto I think you missed a "*" in your code. It's supposed to be : -keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; } -keep interface android.support.v7.** { *; }Dora
Chris Banes recently commented that the next support library release will include a change that should fix the underlying problem, obviating the need for ProGuard: code.google.com/p/android/issues/detail?id=78377#c336 ... Fingers crossed!Wende
@markproxy later in those comments people are saying it's fixed in v24-alpha but he won't commit to saying that the change will actually make it into that version or that it will indeed fix the issue if it does.Gaulin
In my app I am accessing MenuBuilder with reflection so I need to tell Proguard to keep it. Is there a known solution for this case? I can try isSamsung_4_2_2() but I don't think that'll work because I still have to keep the class in proguardAdrienneadrift
@Elum It has not helped me. I am getting the same crashes. Can you help me. I have written these lines in proguard -keep class !android.support.v7.internal.view.menu.**,android.support.** {;} -keep class !android.support.v7.internal.view.menu.*MenuBuilder, android.support.v7.** { ; } -keep interface android.support.v7.* { *; }Hattiehatton
@Gaulin Our testing confirms that the root issue was fixed in support lib 24.0.0. (The official release, not just alpha.) We upgraded to 24.0.0, removed the ProGuard obfuscation workaround, tested on a Samsung device where we previously saw the crash, and we no longer see it.Wende
If others can confirm that support lib 24.0.0 fixes the crash (as it did for me), please upvote https://mcmap.net/q/143278/-noclassdeffounderror-android-support-v7-internal-view-menu-menubuilderWende
That issue also happened to me with a Samsung tablet with Android 5.1.1 and supportLibraryVersion = '27.0.2', and your solution was the only working one. Thank you very much @ElumChamois
damn guys! the exclamation mark before the package name tell Proguard to KEEP everything except android.support.v7.internal.view.menu.**,android.support.** {*;} That mean *no more code obuscation"...that's crazy XDReifel
C
26

As #150 from google groups said

Because careful with -keep class !android.support.v7.internal.view.menu.**. There are a number of classes in there which are referenced from the appcompat's resources.

The better solution is add the following lines instead:

-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
Canaveral answered 25/12, 2014 at 5:55 Comment(14)
In my tests, based on a review of the generated proguard mapping file, this suggested proguard config does not result in obfuscating the MenuBuilder class name, although it does obfuscate SubMenuBuilder.Caxton
see my answer for a rule that obfuscates both classes.Caxton
@AndyDennie where's your answer that obfuscates both classes?Spica
Doesn't matter, worked it out and updated this answer with the solution.Spica
@Spica Someone deleted it, don't know why. Anyway, here's my solution: -keep class !android.support.v7.internal.view.menu.* implements android.support.v4.internal.view.SupportMenu, android.support.v7.** {*;}Caxton
Any solution for gradle builds?Coronograph
The above line should be add to proguard.txt. It has nothing to do with gradle buildsCanaveral
This worked for me where the -keep class !android.support.v7.internal.view.menu.**,** {*;} wasn't working anymore with v23 of app compat.Timmons
@QuentinKlein So what are you using now?Culbertson
-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; } -keep interface android.support.v7.** { *; } as the answer :)Timmons
This still isn't working for me with v23 of app compat.Turbosupercharger
This has supposedly been resolved in support v23.1.1Venita
on 23.1.1 support library the internal package paths were modified, so now the correct proguard setting is: -keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { ; } -keep interface android.support.v7.* { *; }Griffin
@AndreaBellitto are you missing an *? I think it should be android.support.v7.** { *; }Crystallography
P
23

On which device you are facing this problem ? (Samsung/HTC etc.)

If it is Samsung,

Various Samsung phones are included older versions of the android support library in the framework or classpath. If you use the new material support library, you'll see this crash on those Samsung devices:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder

To fix this, you must rename that class. Easiest way to do that is by running proguard. If you don't want to obfuscate, here's a 1 liner to rename just the offending classes:

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

There's an issue tracking this problem, but since it's really a Samsung bug, it's never going to get fixed on their end. Only way to fix it on the Google/AOSP side is to rename these internal classes.

https://code.google.com/p/android/issues/detail?id=78377

Pandowdy answered 2/12, 2014 at 16:25 Comment(9)
Do you use proguard for support v4?Culbertson
@JaredBurrows I have tried for support v7. But for v4 also it will work.Pandowdy
@Android007: thank you for pointing that work-around which actually works. However, no one seems to be able to explain why the faulty ROMs embedding the old Android Support Library in their bootclasspath causes this exception since the missing "android.support.v7.internal.view.menu.MenuBuilder" class is available in the .apk DEX code of the application which suffers from this issue. Would you have any pointer at hand which explains how the Android runtime loads the classes taken from the bootclasspath jar/dex files and the application's, please? Or any precise explanation, please?Phebephedra
@ÉdouardMercier Sorry for late reply. Currently I don't have any answer for your question but I will get back to you soon. :)Pandowdy
Thank you @Android007, as any programmer, I do not like very much witchcraft ;) One hint: would the embedded bootclasspath contain "sealed" .jar/.dex, which would account for the behavior?Phebephedra
@ÉdouardMercier if it's the same as the default Java classloader then it will always delegate loading to the root most classloader. So if these devices are adding old versions of those libraries to the bootclassloader they will be seen first. Ie they are shading the classes in the APK.Spica
@William: thank you for this explanation. "Shading" is the magic word! I.e. the bootclasspath ships on those faulty ROMs the faulty Android Support Library v7, which shades the one embedded in the .apk.Phebephedra
The solution in @Android007's answer is the best one I have found. Other solutions have caused weird problems preventing the app from building.Pitapat
Does anyone know if this bug is fixed by installing newer support libraries?Roughish
B
15

This issue returned in AppCompat 23.1.1 where the .internal package was removed from the library jar.

As suggested in the comments above (credits to the people who suggested it there), now also the proguard configuration has to change.

To get the answer suggested above working again, try adding these lines to your proguard files:

#FOR APPCOMPAT 23.1.1:
-keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.* { *; }

In stead of the old fix:

#FOR OLDER APPCOMPAT VERSION:
-keep class !android.support.v7.internal.view.menu.*MenuBuilder, android.support.v7.** { ; }
-keep interface android.support.v7.* { *; }
Bac answered 20/1, 2016 at 9:12 Comment(1)
!android.support.v7.view.menu.** is safer because of other classes such as SubMenuBuilderClientele
D
12

According to the last posts of the bug-report, this should be fixed on the new version of the support library (24.0.0) : https://code.google.com/p/android/issues/detail?id=78377#c374

Someone even claimed it fixed it.

This version is available since last month, so you should update to it.

Dora answered 11/7, 2016 at 8:5 Comment(1)
Our testing confirms that 24.0.0 fixes the issue. We upgraded the support library to 24.0.0 (not alpha), removed the obfuscation we were using as a workaround, and saw no crashes on a Samsung test device where we've previously seen the crash.Wende
H
4

Yes. Samsung already knows about this problem. I can suggest you try to using same implementation of Popup from GitHub. It is not best way, but will be works.

Huron answered 17/7, 2014 at 17:39 Comment(1)
Yes I saw that on the Samsung forum but it doesn't seem like they're interested since none of their representatives or support have replied.Backspin
P
4

I was having the same problem of this MenuBuilder class not found in USB debugging mode. I solved this problem by simply setting the minifyEnabled to true in both release and debug buildTypes block of build.gradle . like this:

buildTypes {

    debug {

        minifyEnabled true
    }

    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

I set the minifyEnabled to true in debug type to prevent app from crashing via USB debugging to a live handset.

Personnel answered 8/6, 2015 at 2:10 Comment(0)
T
0

I enabled proguard with the default proguard properties provided with an eclipse project and the problem was fixed for me. Based on some comments here https://code.google.com/p/android/issues/detail?id=78377 , some people might have to repackage using: -repackageclasses "android.support.v7"

Templetempler answered 12/11, 2014 at 23:19 Comment(2)
Looks like that's not working for most people in the forum. Seems like going back to appcompat-20 is a more reliable option.Backspin
This has supposedly been resolved in support v23.1.1Venita
D
0

I got the same error when trying to run a 'Hello World' app on my Samsung Galaxy Tab 3 tablet via Android Studio. The app would appear to launch and then it would crash instantly and that error would show in the console in Android Studio. I did a system update on the tablet and now I am able to run the 'Hello World' app and I'm not getting the error anymore. I hope this helps someone to resolve their issue.

Note: The system update I performed on the tablet did not update the Android OS version, because it still says that the version is 4.2.2.

Devoice answered 18/9, 2015 at 3:48 Comment(0)
S
-4

Change the Compile Sdk Version of your project to "API 18:(JellyBean)"

The default is set to "Lollipop

STEPS

  1. Right Click on your project and select Open Module Settings (or press F4)
  2. In the properties tab Compiled Sdk Version
Starstarboard answered 4/8, 2015 at 5:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.