3

I just turned on ProGuard on my build and now I'm getting a

java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.chimera.GmsModuleInitializer" on path: DexPathList[[zip file "/system/app/PlayGames.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

The docs say that everything that I need to use Proguard with Play Services should be included by the Android Gradle plugin:

Note: ProGuard directives are included in the Play services client libraries to preserve the required classes. The Android Plugin for Gradle automatically appends ProGuard configuration files in an AAR (Android ARchive) package and appends that package to your ProGuard configuration. During project creation, Android Studio automatically creates the ProGuard configuration files and build.gradle properties for ProGuard use. To use ProGuard with Android Studio, you must enable the ProGuard setting in your build.gradle buildTypes. For more information, see the ProGuard guide.

This the important part of my app module build.gradle file:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
        ...
    }
    ...
    buildTypes {
        ...{
            applicationIdSuffix ".debug"
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
        }
    }
}


dependencies {
    ...

    //google play services
    compile 'com.google.android.gms:play-services-gcm:8.4.0'
    compile 'com.google.android.gms:play-services-analytics:8.4.0'
    compile 'com.google.android.gms:play-services-location:8.4.0'
}

This is my top level build.gradle file:

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
    }
}

allprojects {
    repositories {
        jcenter()
        mavenCentral()
    }
}

What am I missing?

tir38
  • 9,810
  • 10
  • 64
  • 107

2 Answers2

7

ClassNotFoundException usually occurs when an application tries to load in a class through its string name but no definition for the class with the specified name could be found.

From this forum, you can fix it by adding com.google.android.gms.** { *; }.

Just add to your proguard-project.txt:

  • keep class com.google.android.gms.** { *; }
  • dontwarn com.google.android.gms.**

You can also check on the suggested comment in this SO question.

Google Play Services aars contain proguard.txt with the necessary clauses. So the setting shouldn't really be necessary. You can investigate what happened with the fragment in ProGuard output files. Check app/build/output/mapping/{buildVariant}/usage.txt and mapping.txt. The fragment should be mentioned in one of those.

Hope this helps!

Community
  • 1
  • 1
abielita
  • 13,147
  • 2
  • 17
  • 59
  • Thanks. I had added those keep/dontwarn flags. Glad to know that they "shouldn't" be needed like I thought. I'll investigate the output mappings. – tir38 Sep 05 '16 at 19:54
0

I know this is a rather old post but I would like to highlight the following should it help someone in the future.

Like @abielita mentioned, the ClassNotFoundException is caused by an unhandled case of reflection.

When using broad -keep options (ending with .** { *; }), you will instruct ProGuard not to shrink, optimize or obfuscate all classes and classmembers for the package name mentioned before the wildcards. This will eventually lead in a poorly optimized project. Therefore, it's better to narrow down such -keep option to only target the missing class. In OP's example, adding a -keep option for the missing class like shown below will tackle this particular issue;

-keep class com.google.android.gms.chimera.GmsModuleInitializer

ProGuard can help you set up narrowed down -keep options if you add -addconfigurationdebugging to the configuration file, more details on this feature is documented in the ProGuard manual, here.

Recently the ProGuard Playground was released, you can quickly visualise the effect of the broad -keep options vs the narrowed down ones. A nice benefit here is that you do not need to continuously (re-)build the project.

TrueStory
  • 552
  • 6
  • 13