Lazy resolution of dependencies in Android

Hi guys,
I’ve this project schema:

:app
  -> references library1, library2
:library1
:library2

What i want to achieve is the ability to build library1 and 2 into aar format and add them as dependencies of “releaseImplementation” of app “assembleRelease” task.

Currently I’ve tried this:

//adding a dependsOn before my app is compiled in release mode
afterEvaluate {
    tasks.getByPath(':app:compileReleaseKotlin').dependsOn(buildObfuscatedAar)
}

task buildObfuscatedAar(type: Exec) {
    commandLine "sh", "$projectDir/scripts/build-release-aar.sh"
    doLast {
        configurations.releaseImplementation.withDependencies { deps ->
            println "Resolving dependencies release"
            dependencies {
                releaseImplementation(name: 'library1-release', ext: 'aar')
                releaseImplementation(name: 'library2-release', ext: 'aar')
            }
        }
    }
}

If I try to run this with ./gradlew :app:assembleRelease --stacktrace, I get this error:

Cannot change dependencies of configuration ‘:app:releaseImplementation’ after it has been included in dependency resolution.

So then I tried to change buildObfuscatedAar in this way below without results, I can’t even complete the normal project sync without errors saying that I don’t have the aars in my library.

task buildObfuscatedAar(type: Exec) {
    //launch a script which build library1 and library2 in release mode and copy the aar in
    //app/libs folder
    commandLine "sh", "$projectDir/scripts/build-release-aar.sh"
    //reference all the aars in the folder
    def aarsFolder = fileTree(dir: 'libs', include: ['*.aar'])
    aarsFolder.each { File aarFile ->
        //remove the extension of the file (.aar)
        def length = aarFile.name.length() - 4
        def fileName = aarFile.name[0..<length]
        //add each aar to the "releaseImplementation" configuration, which is provided
        //by the Android plugin
        project.dependencies.add("releaseImplementation", [name: fileName])
    }
}

How can i solve that?

Thank you.
Mat

I am aware my answer comes a bit late.

I faced a similar issue and I solved it by relying on the local maven repository, being the default one located in ~/.m2 .

My approach at the beginning was basically making my :app:assemble${variant.name} task depend on :my-library:publishToMavenLocal .

This approach kind of works, but the dependencies {...} block is still evaluated before the library puts its aar under the local maven repository. Also, the assemble tasks are not run if you just sync the project in Android Studio/IntelliJ.

Therefore this is what I did in the end:

tasks.getByPath(":prepareKotlinBuildScriptModel").dependsOn(":library:publishToMavenLocal")

which makes the local maven repo be populated with your aar when syncing the project, so the dependency on those aar s is satisfied in a later step.

Don’t forget to add mavenLocal() in your repositories {...} closure, if you want to give it a try.

Of course, this solution comes with a cost, which is the local maven deploy on every sync. In my case, it’s relatively fast (due to the gradle cache), but just saying :slight_smile: