dmSherazi dmSherazi - 3 months ago 31
Java Question

How to exempt a library module from pro-guard in android gradle

Release version of my Android app crashes with the following exception

java.lang.NoSuchMethodError: no static or non-static method "Lcom/mm/android/dhproxy/client/DHProxyClient;.InitWithName(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)I"


This error is not found in debug version and hence is because of the proguard I guess.

The above mentioned class is in one of the modules which also use JNI libraries.
My proguard-rules for the app module file is below

-keepattributes InnerClasses
-dontoptimize
-keep class com.mm.android.dhproxy.client.DHProxyClient
-keepclasseswithmembernames class * {
native <methods>;
}
-keep class mypackage.MyCallbackClass {
void myCallbackMethod(java.lang.String);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-printmapping build/outputs/mapping/release/mapping.txt


The build.gradle file for the concerned module is below

apply plugin: 'com.android.library'

android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
compileOptions.encoding = 'ISO-8859-1'

defaultConfig {

minSdkVersion 14
targetSdkVersion 23
}

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

dependencies {
compile files('libs/IPlaySDK.jar')
compile files('libs/ToUProxy.jar')
}


even after adding the line
-keep class com.mm.android.dhproxy.client.DHProxyClient
I can see that the usage.txt file conatins the following entries

com.mm.android.dhproxy.client.DHProxyClient:
29:35:public boolean initWithName(java.lang.String,int,java.lang.String,java.lang.String)
64:69:public int delPort(int)
136:141:public int queryRate(int,com.mm.android.dhproxy.client.DHProxyRateParam)
158:163:public int p2pSetOption(int,int)
180:185:public int p2pGetOption(int)
192:197:public int exit()
private native int InitWithName(java.lang.String,int,java.lang.String,java.lang.String)
private native int DelPort(int,int)
private native int P2PSetOption(int,int,int)
private native int P2PGetOption(int,int)
private native int QueryRate(int,com.mm.android.dhproxy.client.DHProxyRateParam,int)
private native int Exit(int)
com.mm.android.dhproxy.client.DHProxyRateParam


Thanks in advance.

Answer

If you are using external/separate source libraries with your main project/application, you should not use a proguard on the library modules. Instead, you replace the following,

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
    }
    debug {
        minifyEnabled false
    }
}

with the following (in the build.gradle of the library/libraries):

buildTypes {
    release {
        consumerProguardFiles 'proguard-project.txt'
    }
}

where proguard-project.txt is the file that contains the proguard rules for your library project. When building the application (either in debug or release mode), the compiler will take care of all the rules (in the library and in the application).

Source: This stackoverflow answer

Comments