13

My project is including some library project. Library is using some aar files and its dependecny is already defined in the module: gradle file. I am facing problem in including this library in my project.

If I keep duplicate aar files in app->lib and define their dependency in app->gradle file then there is no problem. But it shouldn't be the right approach.

Please find below the error:

A problem occurred configuring project ':app'.

Could not resolve all dependencies for configuration ':app:_qaDebugCompile'. Could not find :api-release:. Searched in the following locations:
         https://jcenter.bintray.com//api-release//api-release-.pom
         https://jcenter.bintray.com//api-release//api-release-.aar
         file:/D:/sample/sample-android-app/app/libs/api-release-.aar
         file:/D:/sample/sample-android-app/app/libs/api-release.aar
     Required by:
         sample-android-app:app:unspecified > sample-android-app:misnapworkflow:unspecified

please find below the project structure:

sample
|-- app
|-- misnapworkflow
    |
    |-- lib
        |-- api-release.aar

In app gradle file following has been mentioned to include the project

dependencies { compile project(':misnapworkflow') }

Please find below the misnapworkflow gradle file:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 23
        consumerProguardFiles 'proguard-rules.pro'
    }

    lintOptions {
        abortOnError false
    }

    // Publish both debug and release libraries
    publishNonDefault true

    buildTypes {
        debug {
            debuggable true
            jniDebuggable true
            minifyEnabled false
            shrinkResources false
            testCoverageEnabled true
        }

        release {
            signingConfig signingConfigs.debug
            debuggable false
            jniDebuggable false
            minifyEnabled true
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

task grantPermissions(type: Exec, dependsOn: 'installDebugTest') {
    logger.warn('Granting permissions...')
    commandLine "adb shell pm grant com.miteksystems.misnap.misnapworkflow.test android.permission.WRITE_EXTERNAL_STORAGE".split(' ')
    commandLine "adb shell pm grant com.miteksystems.misnap.misnapworkflow.test android.permission.CAMERA".split(' ')
    logger.warn('Permissions granted.')
}

tasks.whenTaskAdded { task ->
    if (task.name.startsWith('connected')
            || task.name.startsWith('create')) {
        task.dependsOn grantPermissions
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.0.1'

    // Add dependency for MiSnap external API
    compile(name: 'api-release', ext: 'aar')

    // Add dependency for MiSnap
    compile(name: 'misnap-release', ext: 'aar') {
        exclude module: 'appcompat-v7'
    }

    // Eventbus dependency
    compile 'de.greenrobot:eventbus:2.4.0'

    // Add OPTIONAL dependency for Manatee
    compile(name: 'manatee-release', ext: 'aar')

    compile(name: 'cardio-release', ext: 'aar')
}

repositories {
    flatDir {
        dirs 'libs'
    }
}
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Manish
  • 983
  • 1
  • 9
  • 27
  • Did you manage to solve this problem? I'm facing the exact same issue. If I don't copy the aar file into the app module it doesn't work. I do have the jcenter and the flatDir instruction int he app gradle but makes no difference. – Roberto May 26 '17 at 10:22
  • @Lancelot I have solved this issue in my project, please check the answer below – aldok Jan 28 '18 at 08:14
  • 1
    @aldok thank you!!! It's been a while so not really needed it any more. Thanks anyway :) – Roberto Feb 02 '18 at 10:08

5 Answers5

25

The aar file doesn't contain the transitive dependencies and doesn't have a pom file which describes the dependencies used by the library.

It means that, if you are importing a aar file using a flatDir repo you have to specify the dependencies also in your project.

You should use a maven repository (you have to publish the library in a private or public maven repo), you will not have the same issue.
In this case, gradle downloads the dependencies using the pom file which will contains the dependencies list.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • if there are some aar file used by the library module but not in the app module then do I still have to keep two copies of same aar file? Please note that in my case, library module is a third party library. so I don't want to modify lib module's gradle file – Manish Jun 21 '16 at 08:35
  • Can it achieve using provided tag – Manish Jun 21 '16 at 08:44
  • You can use the same aar file without copying it. In any case you haven't to modify the gradle file of the library, but you have to have the dependencies in your app build.gradle file. – Gabriele Mariotti Jun 21 '16 at 08:55
  • I have done same but getting error. All aar files are copied in the module's lib folder and also mentioned in the lib's gradle file. Now in my app module, in gradle file I have written included lib project in dependency and also all aar files. Gradle is searching them in the app:libs folder – Manish Jun 21 '16 at 09:06
  • @Manish You have to specify the folder of the aar in your flatDir, and also you have to add the jcenter repo in your build.gradle file. – Gabriele Mariotti Jun 21 '16 at 10:11
  • You can specify an aar in a module by using - flatDir { dirs "${rootProject.projectDir}/path/to/aar" } – enyciaa Oct 25 '17 at 13:32
  • @GabrieleMariotti, This time i am facing issue with the Maven. I have published one of lib module (say lib1) to jfrog. Now another library module (lib2) was dependent on lib1 module. Other lib modules(lib3, lib4) and app module are dependent on lib2 and were able to use lib1 without adding lib1 in dependency. but from the time lib2 is referring to lib1 via jfrog repo, all other modules (lib3, lib4, app) also have to add lib1 in dependency otherwise getting error, unable to resolve lib1:1.0.0 – Manish Dec 11 '17 at 12:56
7

For Android studio

Follow this steps:

Step 1:

Import .aar

File ---> New ---> New Module ---> (select) import .JAR/.AAR package ---> Next --->(select .aar file then)Finish

Now your existing project is imported.

Step 2:

Add dependencies

File ---> Project Structure ---> (Now you will get module list in left side at bottom.) ---> (Select app module) ---> select dependencies tab ---> click on (+) button ---> select module dependencies ---> (select module which you added) ---> ok ---> ok

To add dependencies(1)  add dependencies(2)

Note: To check dependency is added

your build.gradle looks like

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
    compile 'com.squareup.picasso:picasso:2.5.0'
    compile project(':ScreenSharingSDK')
}
Pramod Waghmare
  • 1,273
  • 13
  • 21
  • Hi Pramod, all of project dependency are already defined but there are some aar files which are getting used by the library project itself. these aar files are there in the module folder's lib folder but gradle is searching them in the app's lib folder – Manish Jun 21 '16 at 07:41
2

If I keep duplicate aar files in app->lib and define their dependency in app->gradle file then there is no problem. But it shouldn't be the right approach.

You're right, your app shouldn't define your AAR library dependencies in build.gradle. That's a common practice for 3rd party libraries like OkHttp, Picasso or RxJava. Those libraries are, in fact, has their own dependencies, just like your AAR library.

So, how come OkHttp, Picasso or RxJava doesn't ask your App to include their dependencies? Because they have included their dependencies on a POM file. A POM file contains configuration file for your AAR, including your artifact, group name, version, and its dependencies.

Let's take OkHttp as an example. OkHttp and its dependencies are stored in other people computer. Go to mvnrepository.com and search for OkHttp.

Ok Http Maven

You will find OkHttp and its POM file.

<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>

When you include a library in your build.gradle(), Gradle will search that library on repositories define in top-level build.gradle. For OkHttp it was stored in mavenCentral().

repositories {
    google()
    mavenCentral()
    jcenter()
}

Gradle will download the dependencies automatically, you don't need to specify library dependency on your App project.

But it shouldn't be the right approach.

The right approach is:

  1. Store your library and its dependencies in a Maven repository.

You can use local Maven repository, host your own Maven repo, or publish your library on Maven Central or Bintray. inthecheesefactory has a good tutorial for that.

  1. Create a POM file for your library.

When you deploy your AAR you have to include POM file. It can be done manually.

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:mavenPassword@nexus.example.com/repository/maven-releases/"

Or using android-maven-publish Gradle plugin.

gradle yourlibrary:assembleRelease yourlibrary:publishMavenReleaseAarPublicationToMavenRepository
  1. Share your library to your peers:

In app-level build.gradle add the GAV of your library.

dependencies{
    implementation "com.example:yourlibrary:1.0.1"
}

You and your peers should be able to use yourlibrary now.

aldok
  • 17,295
  • 5
  • 53
  • 64
1

In my case, following thing worked:

Put your .aar file in the libs directory(create, if needed), then, add the following code in your build.gradle(app level):

    repositories { 
        flatDir { 
            dirs 'libs' 
        } 
    } 

    dependencies { 
        compile fileTree(dir: 'libs', include: ['*.jar']) 
        compile(name:'your_arr_filename', ext:'aar') 
    } 
Monika Moon
  • 188
  • 3
  • 9
1

Monika Moon put me on the correct path but I don't have enough rep points to comment inline above. sigh

So a default Android app built in 2020 with Android Studio 3.5.3 will have the following project structure via the Project View:

--[yourAppName]
  --[app]
  --[gradle]
  build.gradle <this is the TOP LEVEL one and NOT the one you normally mess with>

In the top level build.gradle files add the 'flatDir' item :

allprojects {
        repositories {
            google()
            jcenter()

            // needed so it picks up my aar files
            flatDir {
                dirs 'libs'
            }
        }
}

Then in your 'app' folder shown above. You will have these two key resources:

 -- [libs] folder where you should drop your aar files
 build.gradle file that is the one you add your aar dependencies to.

The default project build will already contain a 'libs' include for you but just in case your version doesn't have it this is what you need to add:

dependencies {
    implementation fileTree(dir: './libs', include: ['*.jar'])
    implementation(name: 'fileNameBeforeExtension', ext:'aar')

This is clean and works as expected.

The AAR file I'm using is an in-house custom built for internal hardware and will never be on a public repot.

Waxhaw
  • 599
  • 5
  • 9