Stop fighting
flatDir { … }
and let your AAR behave like a first-class Maven artifact.
Android Gradle Plugin 8 throws this build-time error whenever a library module tries to embed a raw .aar inside another AAR:
Execution failed for task ':master:bundleDebugLocalLintAar'. > Direct local .aar file dependencies are not supported when building an AAR …
Below is a step-by-step guide—with copy-paste code—to convert that raw file into a miniature, in-project Maven repository and wire every module to it via Gradle 8’s dependencyResolutionManagement
.
The example uses an imaginary Connector 1.0.0 AAR; substitute your own library name or version as needed.
Project baseline
AarTestApp/ ├── master/ # → Android library you package as an AAR │ └── build.gradle.kts ├── app/ # → Demo app that depends on :master ├── libs/ │ └── Connector-1.0.0.aar # ← raw AAR causing the build to fail └── settings.gradle.kts
1 Create a “publisher” module
- Move the AAR into its own folder and make that folder a Gradle project:
mkdir -p libs/connector_publisher mv libs/Connector-1.0.0.aar libs/connector_publisher/
- Register the module in
settings.gradle.kts
:
include(":connector_publisher") project(":connector_publisher").projectDir = file("libs/connector_publisher")
- Add a
build.gradle.kts
insidelibs/connector_publisher
:
plugins { id("maven-publish") } val connectorAar = file("Connector-1.0.0.aar") publishing { publications { create<MavenPublication>("connector") { groupId = "com.example.connector" artifactId = "connector" version = "1.0.0" artifact(connectorAar) } } repositories { maven { name = "localAkamaiRepo" url = uri("${rootProject.rootDir}/local-maven-repo") } // mavenLocal() } }
This module doesn’t compile code; it simply tells Gradle “publish that file as a Maven artifact.”
2 Publish once
./gradlew :connector_publisher:publishConnectorPublicationToLocalMavenRepoRepository
You should now see:
local-maven-repo/ └─ com/example/connector/connector/1.0.0/ ├─ connector-1.0.0.aar └─ connector-1.0.0.pom
3 Tell all modules where that repo lives
(Gradle 8 syntax)
Open settings.gradle.kts
and wire the repo once at the top:
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() // ⭐ local repository for the published AAR maven { url = uri(rootDir.resolve("local-maven-repo")) } // mavenLocal() // uncomment if you also published to ~/.m2 } }
4 Consume the library like any other Maven artifact
master/build.gradle.kts
dependencies { // expose to consumers? use api(); otherwise implementation() api("com.example.connector:connector:1.0.0") }
Important: remove any old
files("…/Connector-1.0.0.aar")
orflatDir { … }
lines—they’re no longer needed.
5 Build & profit!
./gradlew clean :app:assembleDebug
AGP now:
- Finds
com.example.connector:connector:1.0.0
in your local repo. - Merges its classes/resources into the
master
AAR. - Packages the
master
AAR into yourapp
APK/AAB.
No more “direct local .aar dependencies” errors. 🎉
Wrap-up
By turning your standalone .aar into a proper Maven artifact and pointing Gradle 8 at a local repository, you:
- Eliminate AGP’s AAR-within-AAR restriction.
- Keep a clear audit trail of library versions.
- Remove brittle
flatDir
hacks from your builds.
Happy (error-free) coding!
Written By

I’m an Enterprise Architect at Akamai Technologies with over 14 years of experience in mobile app development across iOS, Android, Flutter, and cross-platform frameworks. I’ve built and launched 45+ apps on the App Store and Play Store, working with technologies like AR/VR, OTT, and IoT.
My core strengths include solution architecture, backend integration, cloud computing, CDN, CI/CD, and mobile security, including Frida-based pentesting and vulnerability analysis.
In the AI/ML space, I’ve worked on recommendation systems, NLP, LLM fine-tuning, and RAG-based applications. I’m currently focused on Agentic AI frameworks like LangGraph, LangChain, MCP and multi-agent LLMs to automate tasks