Reputation: 815
I have a library project(A) that reference another jar file(B.jar), but after generating aar file, jar file(B.jar) is not bundled in the output aar file, and when use this aar file, I got a NoClassDefFoundError
.
Is there a way to make gradle bundle all dependency classes in the output aar file? this is my build.gradle:
apply plugin: 'com.android.library'
repositories {
mavenCentral()
}
android {
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile project(':common')
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Upvotes: 6
Views: 4286
Reputation: 17991
Is there a way to make gradle bundle all dependency classes in the output aar file?
Yes, there is a way to do this, I have encountered this issue before. But this is going to be a long story, bear with me.
When you specify a dependency in build.gradle, you're telling Gradle to download an artifact (AAR / JAR) from Maven repository. So, Gradle need two things:
You specify Maven repository in top-level build.gradle
repositories {
jcenter()
google()
}
and you specify the dependency on project-level build.gradle
dependencies {
compile 'com.example:mylibrary:1.0.1'
}
How does Gradle / Maven know that mylibrary
requires other dependencies? From your Dependency POM file.
Let's use Square's OkHttp as an example, you can find this artifact in mvnrepository.com.
OkHttp has a POM file. You can click that link to show the complete XML, I'm only showing you the interesting part which is the dependencies block.
<project>
<modelVersion>4.0.0</modelVersion>
<parent>...</parent>
<artifactId>okhttp</artifactId>
<name>OkHttp</name>
<dependencies>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>...</build>
</project>
OkHttp requires dependencies from other artifacts. Okio, Android, and jsr305. But when you include OkHttp in your project you don't have to do include Okio, Android, and jsr305 on your project. Why is that?
Because Gradle / Maven will look into POM files and download the dependencies for you. No more NoClassDefFoundError
.
Back to your question, how to "combine" your library project into single .aar? Here are the steps:
There is a big chance that your dependencies is already exist on mvnrepository, if it didn't exist you can submit your dependencies on bintray, mvnrepository, or host your own Maven repository.
Just like in OkHttp dependencies block, you put your Library dependencies there.
You can use mvndeploy
to submit your library to Maven repository.
mvn deploy:deploy-file \
-DgroupId=com.example \
-DartifactId=your-library \
-Dversion=1.0.1 \
-Dpackaging=aar \
-Dfile=your-library.aar \
-DpomFile=path-to-your-pom.xml \
-DgeneratePom=true \
-DupdateReleaseInfo=true \
-Durl="https://mavenUserName:[email protected]/repository/maven-releases/"
If you don't want to do step 2 and 3 manually, as you can guess, "There is a gradle plugin for that!". The plugin is android-maven-publish, credit to: wupdigital to make these process easier.
Now you can use gradle command to publish your library:
gradle yourlibrary:assembleRelease yourlibrary:publishMavenReleaseAarPublicationToMavenRepository
Next time your teammate ask for your library, you can give them two things:
That's it! No need to give your dependency dependencies to your peers.
Cheers 🥂
Upvotes: 9
Reputation: 12823
What you're trying to do is not possible -- at least not possible in the way you have it described above.
Upvotes: 0