38

Summary:

I have an AAR file that depends on a JAR file, when I build the AAR project, it doesn't contain the JAR code.

Details:

I have a Java SDK library project that contains code that we use for Java web projects and such, this library is created using Gradle and resides in an internal nexus server (as a JAR).

The goal is to provide an "Android configured" version of this JAR library through an AAR library that multiple Android Applications can use and minimize the effort (and boilerplate code) to implement it. This AAR file is also uploaded to the nexus server to be used by the Android Application projects.

My AAR project includes a gradle dependency for my Java SDK library (the JAR) but when built, the AAR doesn't include any classes from it.

Code:

This is the Java SDK project's gradle file:

apply plugin: 'java'

//noinspection GroovyUnusedAssignment
sourceCompatibility = 1.7
version = '1.1.1'

repositories {
    mavenCentral()
}

jar {
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    testCompile 'org.apache.directory.studio:org.apache.commons.io:2.4'
    compile 'org.springframework:spring-web:3.1.1.RELEASE'
    compile 'com.google.code.gson:gson:2.3'
}

This is the gradle file for my AAR Project, note that I removed the Maven repository declarations to my nexus server from it. I guess it shouldn't matter for the sake of this question.

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "2.2.2"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lintOptions {
        abortOnError false
    }
}

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

    compile ('com.mycompany:javasdk:1.1.1')
}

This is the gradle file for my Android Project, again I removed the nexus server references:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "com.mycompany.application1"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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

    compile ('com.mycompany:androidsdk:2.2.2@aar')
}

NOTE: I initially solved the issue by adding the JAR in the lib directory of the AAR project, but this is undesired. It makes having a nexus server useless. It would be good that we can just bump the JAR's version number in the AAR project's gradle file and the update happens automatically at compile time.

NOTE2: I tried adding transitive=true to my AAR dependency in the Android Project but it didn't solved anything, the real issue is that when building the AAR project, the JAR project code doesn't get bundled.

Zoe
  • 27,060
  • 21
  • 118
  • 148
rastadrian
  • 1,025
  • 1
  • 10
  • 17

4 Answers4

53

You can add this task:

task copyLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

Dependencies will be downloaded from your Nexus, but when you need package the library, execute this task first and jar files will be copied and included inside final aar.

Héctor
  • 24,444
  • 35
  • 132
  • 243
  • man, I think this is what Ive been looking for, Ill try it out and come back. Thank you! – rastadrian Nov 06 '15 at 15:26
  • yes, this solved the issue. I just added a `clean task` first to clear the libs directory, based from [this post](https://discuss.gradle.org/t/how-do-i-delete-a-subset-of-files/6855/2). After this I had to add some exclusions in the `packagingOptions` for some generated files in the `META-INF`, but in overall, this worked! – rastadrian Nov 08 '15 at 06:21
  • @bigdestroyer: Any idea of I can do the same thing with an aar dependency? Here is my question: http://stackoverflow.com/questions/41847266/how-to-package-multiple-aars-in-my-release-aar – Sid Jan 25 '17 at 09:23
  • 1
    HI @rastadrian, i have same issues, can you share your code ? about creat clean task ? – Nguyễn Hoàng Jun 11 '17 at 14:54
  • can u explain complete solution? where did you add this task? – faraz khonsari Oct 09 '17 at 07:25
  • 1
    where should I add this task in my project? I am also having the same scenerio – Shailesh Nov 25 '17 at 11:32
  • With this task I'm getting the error `Error:(29, 0) Could not get unknown property 'compile' for configuration container of type org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.` I'm using Android Studio 3.0.1 and Gradle 4.1 – ocramot Feb 07 '18 at 22:40
  • PS: ok, I was adding in the Project Gradle and I had to add it in the Module Gradle instead. – ocramot Feb 07 '18 at 22:47
  • Doesn't seem to work with gradle 3.0.1. The task executes but doesn't do nothing. It says: `:copyDeps NO-SOURCE BUILD SUCCESSFUL in 0s 16:03:18: Task execution finished 'copyDeps'.` – Lucas Montenegro Carvalhaes May 17 '18 at 19:03
  • Does this work with the `assemble` task when building only the .aar files? – rraallvv Jun 18 '19 at 12:52
12

By default, AAR does not include any dependencies. Solution mentioned by @Hector should work for gradle plugin < 3.0. For Gradle plugin 3.0+, try custom config as mentioned here.

android { ... }

// Add a new configuration to hold your dependencies
configurations {
    myConfig
}

dependencies {
    ....
    myConfig 'com.android.support:appcompat-v7:26.1.0'
    myConfig 'com.android.support:support-v4:26.1.0'
    ...
}

task copyLibs(type: Copy) {
    from configurations.myConfig 
    into "libs"
}
nayan
  • 181
  • 2
  • 8
  • 2
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](//stackoverflow.com/help/deleted-answers) – Papershine May 22 '18 at 04:11
  • I copy jar lib from another module and by adding `preBuild.dependsOn copyLibs` the jar will be copied every build ( just in case the module was modiefied ) – Davide May 29 '19 at 10:34
  • 1
    Add `afterEvaluate {assembleDebug.finalizedBy(copyLibs)}` inside `android{...}`. this will work – Alireza Saremi Apr 28 '20 at 11:14
6

None of the suggestions helped me for Gradle 4.6, so I wasted the whole day inventing my own.

Eventually I found a good Gist and modified it for my version of Gradle: https://gist.github.com/stepio/824ef073447eb8d8d654f22d73f9f30b

stepio
  • 865
  • 2
  • 9
  • 22
4

The upper ones didn't work for me in android tools 3.6.2 with Gradle. 5.6.1 . For anyone having the same issue, using https://github.com/kezong/fat-aar-android in the end worked fine for me.

Dirk Bolte
  • 572
  • 4
  • 12