How to prefer settings.gradle repositories over build.gradle

Starting with Gradle 7, Android suggests the use of centralized repository declarations in settings.gradle over project or module level build.gradle declarations. If you created a new Android project by following the project creation wizard in the latest Android Studio, you will encounter the following error when you try to add a new maven repository in one of your build.gradle scripts: "Build was configured to prefer settings repositories over project repositories but repository 'XXXX' was added by build file 'build.gradle'". Skip to the end of this post if you want to learn how to fix this error.

Declaring repositories in build.gradle

When gradle tries to resolve the host for one of your java dependencies, it walks through a list of repository urls and checks whether your dependency is hosted there. You can declare this list in your module’s (usually called app or library) build.gradle file the following way.

buildscript {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon

        maven { url 'https://maven.testfairy.com' }
        maven { url 'https://example.com/maven' }
    }
}

plugins {
  id 'com.android.application'
}

...

Alternatively, you can declare the list in your project level build.gradle to enable it for all modules.

allprojects {
    repositories {
        google()
        jcenter()

        maven { url 'https://maven.testfairy.com' }
        maven { url 'https://example.com/maven' }
    }
}

task clean(type: Delete) {
  delete rootProject.buildDir
}

Unless specified otherwise in settings.gradle, mixing both methods is allowed. However, in cases where the same dependency is hosted by multiple repos in the list, gradle may attempt to fetch the dependency from the wrong source.

Declaring repositories in settings.gradle

There is a way to enforce a policy for repository declarations. RepositoriesMode api provides the following modes:

FAIL_ON_PROJECT_REPOS : If this mode is set, any repository declared directly in a project, either directly or via a plugin, will trigger a build error.

PREFER_PROJECT : If this mode is set, any repository declared on a project will cause the project to use the repositories declared by the project, ignoring those declared in settings.

PREFER_SETTINGS : If this mode is set, any repository declared directly in a project, either directly or via a plugin, will be ignored.

When a new project is created with Android Studio project creation wizard, FAIL_ON_PROJECT_REPOS will be selected as the default mode. This means all repository declarations must go into settings.gradle file.

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
    google()
    mavenCentral()
    jcenter() // Warning: this repository is going to shut down soon

    maven { url 'https://maven.testfairy.com' }
    maven { url 'https://example.com/maven' }
  }
}
rootProject.name = "ExampleGradle7"
include ':app'

Fix “Build was configured to prefer settings repositories” error

Build your app and check if one of the errors below occurs.

Build was configured to prefer settings repositories over project repositories but repository 'XXXX' was added by build file 'build.gradle'
Could not find any matches for com.testfairy:testfairy-android-sdk:1.+ as no versions of com.testfairy:testfairy-android-sdk are available.

To fix, make sure you remove the repository declaration from all build.gradle files in the project, including the one in the root project.

Then declare your maven repository in settings.gradle.

Migrating existing projects

Add the following configuration to your settings.gradle or replace the current one if it already exists.

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) // or FAIL_ON_PROJECT_REPOS
  repositories {
    google()
    mavenCentral()
    jcenter() // Warning: this repository is going to shut down soon

    maven { url 'https://maven.testfairy.com' }
    maven { url 'https://example.com/maven' }
  }
}
rootProject.name = "ExampleGradle7"
include ':app'

Sync your project and rebuild.

Reference

To learn more about managing your dependencies, make sure to check out awesome gradle docs.

Until then, #staysafe