Hey
Apologies if this is a dumb question. I am new to both ProGuard and Gradle. I am also new to posting here, so I am hoping I got this right. I have a project that contains the following:
- core library
- N Plugins - each of which depend on the core library
- Sample Application - uses Core Library + Plugins
What we typically due is we obfuscate the core library and plugins (we formally used Maven/ZKM). When we obfuscated the core library, we would create a mapping file and apply it when we obfuscated the plugins. This allowed the plugins to use methods we had obfuscated.
We are doing (attempting to do) the same in Gradle with ProGuard. We have our core Library defined with:
// Called Core:
android {
publishNonDefault true
...
sourceSets {
...
}
buildTypes {
debug {
debuggable true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
}
}
}
configurations {
debugCompile
releaseCompile
configuration.exclude group: 'com.android.support', module: 'support-v4'
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile "com.android.support:support-v4:$supportLibraryVersion"
compile "com.google.code.gson:gson:$googleGsonVersion"
}
In the above, our release builds will be obfuscated, but are debug builds will not be.
Our plugins are then defined as follows:
android {
publishNonDefault true
...
sourceSets {
...
}
buildTypes {
debug {
debuggable true
minifyEnabled false
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
}
}
}
configurations {
debugCompile
releaseCompile
configuration.exclude group: 'com.android.support', module: 'support-v4'
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(path: ':core', configuration:'debug')
}
Of note - we force it to compile with the ‘debug’ (unobfuscated) version of the library. The obfuscation rules will then be applied to the result with the mapping file from the core (in theory allowing the obfuscated core and obfuscated plugins to work together.
We then have a sample app that references plugins + core as follows (for the sample app we don’t care if its obfuscated, we only care that it use the obfuscated library for demo/testing purposes).
android {
defaultConfig {
...
multiDexEnabled true
}
buildTypes {
debug {
debuggable true
minifyEnabled false
}
release {
minifyEnabled false
//proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
configurations {
debugCompile
releaseCompile
}
dependencies {
debugCompile project(path: ':core', configuration:'debug')
debugCompile project(path: ':plugins:plugin-eventlogger', configuration:'debug')
debugCompile project(path: ':plugins:plugin-openvidservice', configuration:'debug')
releaseCompile project(path: ':core', configuration:'release')
releaseCompile project(path: ':plugins:plugin-eventlogger', configuration:'release')
releaseCompile project(path: ':plugins:plugin-openvidservice', configuration:'release')
compile 'com.android.support:multidex:1.0.1'
compile "com.android.support:appcompat-v7:$supportLibraryVersion"
compile "com.android.support:support-v4:$supportLibraryVersion"
}
Note that for release we try to use the obfuscated release builds.
What were encountering is that our debug builds compile/build correctly. However, are release builds fail:
- What went wrong:
Execution failed for task ‘:sample-app:packageAllDebugClassesForMultiDex’.
java.util.zip.ZipException: duplicate entry: com/quickplay/vstb/exposed/BuildDefinitions$BuildType.class
We suspect that whats happening is when we ‘compile’ a release build - it uses the obfuscated project plugin-eventlogger, but also picks up the debug core that the plugin-eventlogger depends on.
I looked into disabling transitive dependencies, but I could not figure out how to do it for something that has ‘compile project(…)’ as one of the dependencies.
So I am at a bit of a loss. I can see us trying to exclude the dependencies, or somehow having are sample app release build depend on the outputted libs instead of compilation.
Does any one have any thoughts or suggestions as to if my hypothesis above is correct, and if so, how I can go about excluding a compile dependency?
Completly unrelated question: In ProGuard - does anyone know how to use ProGuard to access gradle properties (E.g. project.projectDir). We noticed the relative path when using gradle from the command line vs from within android studio is different. In our proguard we do:
-applymapping …/mapfiles/core-mapping.txt
-printmapping …/mapfiles/plugin-eventlogger-mapping.txt
The ‘relative’ path being different breaks this and I could not figure out how to make proguard aware of the gradle root path
Thanks for any guidance.