I have an android .aar
library built and I am trying to integrate it with one of the projects. When the app tries to open the initial screen of the .aar
library where I have API call using retrofit. I am getting the below exception
java.lang.NoClassDefFoundError: Failed resolution of:Lokhttp3/OkHttpClient$Builder;
I have not obfuscated or enabled pro-guard in my .aar
project.
Below are my .aar
Gradle dependencies
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:converter-gson:2.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
OK, this is a common issue. There are several ways to use an android library(aar) in other projects. For example:
implementation project(':mylibrary')
.Pay attention to this:
What do I recommend?
I recommend developers to use MavenLocal()
, it replicates a real scenario before publishing your aar to a public repository like Jitpack or whatever you want.
How can I do it?
apply plugin: 'maven-publish'
project.afterEvaluate {
publishing {
publications {
library(MavenPublication) {
setGroupId 'YOUR_GROUP_ID'
//You can either define these here or get them from project conf elsewhere
setArtifactId 'YOUR_ARTIFACT_ID'
version android.defaultConfig.versionName
artifact bundleReleaseAar //aar artifact you want to publish
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
Run assemble
and publishToMavenLocal
gradle tasks. And you'll see something like this:
allprojects {
repositories {
mavenLocal()
...
}
}
implementation '${YOUR_GROUP_ID}:${YOUR_ARTIFACT_ID}:${YOUR_VERSION}'
Let's assume you've built your .aar, and published it to a maven repository (artifactory, nexus, what have you) - e.g., "implementation 'com.mycompany:library:1.0@aar'". Any child dependencies need to be included in the pom.xml delivered by the server to have them available in your application.
Since you've used the "implementation" keyword, those dependencies are considered private to the .aar, and will not be listed in the pom.xml. So they will not be available in your aar, and not automatically imported into the project by gradle.
If you change to the api keyword to "api" instead of implementation, those dependencies become public, and should be listed in the generated pom.xml, and thus should be automatically imported into the project.
This is actually also true also with aar's inside modules, rather than referenced via external systems (e.g. implementation project(':mylibrary') ). If you need the dependencies of mylibrary to run the project, they need to be api.
For reference, you may want to take a look at the Android Studio Dependency Configurations Documentation.
If, however, you're manually including the arr via a files statement (e.g., implementation files('libs/my.aar')), then you don't get automatic dependency management, and you're going to have to add the libraries needed by your aar to the main project manually as well via copy and paste between the build.gradle files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With