Introduction
If there are Duplicate classes found in a jetified version of android build and it fails when using aar, one of the reason could be duplicate sub packages from two or more dependencies
One way to solve this problem is to rename the package name in one of the aar, to avoid naming collision. This process is called shadowing the package
Installation
- Create a Java project with Gradle as the build system and Groovy as the Gradle DSL
- Add a
shadowplugin to thebuild.gradle
plugins {
id 'com.gradleup.shadow' version '8.3.5'
id 'java'
}Create Tasks
Extract aar
Create a task called extractAar which takes the sourceAar and extract it’s contents and puts under extractedAar folder under the build directory
task extractAar(type: Copy) {
def sourceAAR = project.hasProperty('sourceAar') ? project.sourceAar : null
from {
zipTree(sourceAAR)
}
into "$buildDir/extractedAar"
}Relocate Package names
Use shadowJar to relocate packages under the aar.
shadowJar {
dependsOn extractAARs
from("$buildDir/extractedAar") {
include 'classes.jar'
// Relocate dependencies
relocate 'org.apache.commons.codec', 'shadow.org.apache.commons.codec'
archiveFileName = "merged-classes.jar"
}
}This Task should run only after extracting aar. The from("$buildDir/extractedAar") block needs the Source Directory. Let’s pass the extractedAar Directory.
The aar file will have the classes.jar file where the package need to be relocated. So include it in the task.
Pass the package name for which the Duplicate Classes error occurred. In my scenario apache commons package. This will change the package name of org.apache.commons.codec package to shadow.org.apache.commons.codec
Finally mention the archive file name. Here it’s called as merged-classes.jar
Prepare aar
task prepareAar(type: Jar) {
dependsOn shadowJar
from("$buildDir/libs") {
include "merged-classes.jar"
rename "merged-classes.jar", "classes.jar"
into ''
}
from("$buildDir/extractedAar") {
exclude 'classes.jar'
into ''
}
}Finally, create the main task prepareAar, which is dependent on shadowJar task.
Here we take the merged-classes/jar which is built in shadowJar step and rename it back to classes.jar and put in the root build directory.
Next take all the files in the extractedAar folder except classes.jar as we need repackaged classes.jar from shadowJar and put it in the root buid directory
After running this, you will find a jar file with the project name. If my preject name is rename-aar-package it will be rename-aar-package.jar
Rename this rename-aar-package.jar to rename-aar-package.aar and use it
The flow is
- Run the prepareAar task
- This will trigger shadowJar task
- shadowJar will trigger extractAar task and extracts the aar
- Use the extracted aar folder and relocate packaged in shadowJar task
- Finally Repackage the jar
The Command Would be
./gradlew clean prepareAAR -PsourceAAR=libs/protean-esign-v-3.8_UAT.aar