Android ProGuard + MultiDex throws a ClassNotFoundException

I have MultiDex enabled in my Android project. It worked fine until I tried to enable proguard. I can successfully create a project, but when I get it I get an exception at runtime. It cannot find the Application class and MainActivity . Before turning on MultiDex , I had the same problem. Now I think that for some reason MultiDex is not working properly with ProGuard . Here is what I get in logcat -

 02-17 19:01:09.749: I/MultiDex(2079): VM with version 2.1.0 has multidex support 02-17 19:01:09.749: I/MultiDex(2079): install 02-17 19:01:09.749: I/MultiDex(2079): VM has multidex support, MultiDex support library is disabled. 02-17 19:01:09.750: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<android.support.v4.app.FragmentActivity> 02-17 19:01:09.750: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<android.support.v4.app.FragmentActivity> 02-17 19:01:09.751: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<mypackage.activities.MainActivity> 02-17 19:01:09.751: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<mypackage.activities.MainActivity> 02-17 19:01:09.751: D/AndroidRuntime(2079): Shutting down VM 02-17 19:01:09.751: D/AndroidRuntime(2079): --------- beginning of crash 

and after that the rest of the stack trace refers to a ClassNotFoundException for MainActivity:

 02-17 19:01:09.752: E/AndroidRuntime(2079): FATAL EXCEPTION: main 02-17 19:01:09.752: E/AndroidRuntime(2079): Process: com.mypackage, PID: 2079 02-17 19:01:09.752: E/AndroidRuntime(2079): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/mypackage/activities/MainActivity; 02-17 19:01:09.752: E/AndroidRuntime(2079): at cmypackage.application.ApplicationContextProvider.onCreate(Unknown Source) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread.access$1500(ActivityThread.java:144) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.os.Handler.dispatchMessage(Handler.java:102) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.os.Looper.loop(Looper.java:135) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread.main(ActivityThread.java:5221) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.reflect.Method.invoke(Native Method) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.reflect.Method.invoke(Method.java:372) 02-17 19:01:09.752: E/AndroidRuntime(2079): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 02-17 19:01:09.752: E/AndroidRuntime(2079): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 02-17 19:01:09.752: E/AndroidRuntime(2079): Caused by: java.lang.ClassNotFoundException: Didn't find class "mypackage.activities.MainActivity" on path: DexPathList[[zip file "/data/app/mypackage-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]] 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.ClassLoader.loadClass(ClassLoader.java:469) 02-17 19:01:09.752: E/AndroidRuntime(2079): ... 12 more 02-17 19:01:09.752: E/AndroidRuntime(2079): Suppressed: java.lang.NoClassDefFoundError: mypackage.activities.MainActivity 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexFile.defineClassNative(Native Method) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexFile.defineClass(DexFile.java:226) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexPathList.findClass(DexPathList.java:321) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54) 02-17 19:01:09.752: E/AndroidRuntime(2079): ... 14 more 02-17 19:01:09.752: E/AndroidRuntime(2079): Suppressed: java.lang.ClassNotFoundException: mypackage.MainActivity 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.Class.classForName(Native Method) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.BootClassLoader.findClass(ClassLoader.java:781) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 02-17 19:01:09.752: E/AndroidRuntime(2079): ... 13 more 02-17 19:01:09.752: E/AndroidRuntime(2079): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available 

Edit - Here is my proguard rule file:

 -libraryjars libs # We only want obfuscation -keepattributes InnerClasses,Signature -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -dontoptimize -verbose # Sdk -keep public interface com.zendesk.sdk.** { *; } -keep public class com.zendesk.sdk.** { *; } # Appcompat and support #-keep interface android.support.v7.** { *; } #-keep class android.support.v7.** { *; } #-keep interface android.support.v4.** { *; } #-keep class android.support.v4.** { *; } # Gson -keep interface com.google.gson.** { *; } -keep class com.google.gson.** { *; } # Retrofit #-keep class com.google.inject.** { *; } #-keep class org.apache.http.** { *; } #-keep class org.apache.james.mime4j.** { *; } #-keep class javax.inject.** { *; } #-keep class retrofit.** { *; } #-keep interface retrofit.** { *; } # Retrofit -keep class com.squareup.okhttp.** { *; } -keep interface com.squareup.okhttp.** { *; } -dontwarn com.squareup.okhttp.** -dontwarn rx.** -dontwarn retrofit.** -dontwarn okio.** -keep class retrofit.** { *; } -keepclasseswithmembers class * { @retrofit.http.* <methods>; } # Jackson -keepattributes *Annotation*,EnclosingMethod,Signature -keepnames class com.fasterxml.jackson.** { *; } -dontwarn com.fasterxml.jackson.databind.** -keep class org.codehaus.** { *; } -keepclassmembers public final enum org.codehaus.jackson.annotate.JsonAutoDetect$Visibility { public static final org.codehaus.jackson.annotate.JsonAutoDetect$Visibility *; } -keep public class mypackage.parsers.JacksonParser.** { public void set*(***); public *** get*(); } #Picasso -dontwarn com.squareup.okhttp.** #-dontwarn javax.management.** #-dontwarn java.lang.management.** #-dontwarn org.apache.log4j.** #-dontwarn org.apache.commons.logging.** #-dontwarn org.json.* #-dontwarn org.apache.commons.codec.binary.Base64 #-keep class javax.** {* ; } #-keep class org.** { *; } -dontwarn org.mortbay.** -dontwarn org.slf4j.** -dontwarn org.apache.log4j.** -dontwarn org.apache.commons.logging.** -dontwarn org.apache.commons.codec.binary.** 
+6
source share
1 answer

This page says:

The proguard.cfg file by default tries to cover common cases, but you may encounter exceptions, such as ClassNotFoundException , which occurs when ProGuard deletes the entire class that calls applications.

You can fix errors when ProGuard deletes your code by adding proguard.cfg file. For instance:

 -keep public class <MyClass> 

There are many options and considerations when using the -keep option, so it is highly recommended that you read the ProGuard Guide for more information on setting up a configuration file. Overview The "Parameters" and "Examples" sections are especially useful. The Troubleshooting section of the ProGuard Guide describes other common problems that you may encounter when your code is deleted.

Solution 1

You can try the following proguard.cfg I used to obfuscate the code without optimizing, and therefore do not remove the classes / methods from your APK.

 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -dontoptimize -verbose 

Decision 2

You asked to keep some classes, but not for MainActivity . Therefore, you should add this line:

 -keep class com.mypackage.activities.MainActivity { *; } 
+4
source

Source: https://habr.com/ru/post/982663/


All Articles