10

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'
8
  • do you enabled instant-run? and running your app in below android M? Commented Jul 11, 2019 at 13:40
  • How are you referencing the aar in the project that's using it? Commented Jul 11, 2019 at 15:58
  • @Mark implementation project(path: ':LibraryName') this how i am referencing the aar Commented Jul 12, 2019 at 4:54
  • @RajasekaranM I have disabled instant-run and running the app in android M Commented Jul 12, 2019 at 5:25
  • still issue exists? Commented Jul 12, 2019 at 6:17

4 Answers 4

18

OK, this is a common issue. There are several ways to use an android library(aar) in other projects. For example:

  1. By importing this aar as a module into your sample project by using implementation project(':mylibrary').
  2. By uploading your aar to a maven repository(artifactory, maven local, Jitpack, etc)

Pay attention to this:

  1. If you are using number 1 above, so you will also have to add(retrofit, okhttp3, etc) to your sample project with the same version, because the aar by default doesn't include child dependencies. That's why you are getting that exception "java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/OkHttpClient$Builder'".
  2. If you are using number 2 above, so you will have to make sure that your pom.xml file includes your child dependencies, because the server needs to download and have them available in your sample project.

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?

  1. Inside build.gradle of your library module:

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: enter image description here

  1. In your Sample Project
allprojects {
    repositories {
        mavenLocal()
        ...
    }
}

implementation '${YOUR_GROUP_ID}:${YOUR_ARTIFACT_ID}:${YOUR_VERSION}'

Sign up to request clarification or add additional context in comments.

1 Comment

If you haven't specified signing info, you'll get a no configured signatory error. Follow here to add signatory credentials: docs.gradle.org/current/userguide/signing_plugin.html
1

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.

5 Comments

Thanks for your suggestion and help @Mark. I have not published my .aar to the maven repository. It's a local module which I tried to import the library using api like this 'api project(':MyLibrary')' but didn't work.
No, within the MyLibrary module, you need to change your dependencies from implementation to API, eg, for okhttp, retrofit, etc. Then they will be "public", and available to your parent project.
Thanks, Mark I have changed my library module dependencies from module to api and re-imported the library in the project, but I have the same issue java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/OkHttpClient$Builder'
If you've got "api 'com.squareup.okhttp3:okhttp:3.12.0'" and you're still getting this message... have you tried turning off proguard (could be you're missing proguard rules and the class is getting stripped).
Ya, I have tried turning off the proguard and even tried adding proguard rules, but still, I have the same error message.
0

You can try using fat-aar to solve this https://github.com/kezong/fat-aar-android

Comments

0

For me, the fix was to change

compileOnly files('libs/mylibrary.aar') 

in gradle to

implementation files('libs/mylibrary.aar')

and the error was gone.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.