# Dependency Management

version 8.10.2

Software projects typically depend on other libraries to function. These libraries can either be sourced from other projects in the same build or from external repositories.

Gradle’s dependency management infrastructure provides APIs to declare, resolve, and expose binaries required by and provided by a project.

Understanding dependency management in Gradle is important for structuring projects into components. It is also important when you want to reuse existing libraries, or you need to upgrade those libraries while managing their versions.

Let’s look at a Java project where the code relies on Guava which is a suite of Google Core libraries for Java. The build file of the project includes the following:

build.gradle.kts

    dependencies {
        implementation("com.google.guava:guava:32.1.2-jre")
        api("org.apache.juneau:juneau-marshall:8.2.0")
    }

build.gradle

    dependencies {
        implementation("com.google.guava:guava:32.1.2-jre")
        api("org.apache.juneau:juneau-marshall:8.2.0")
    }

Within the `dependencies` block, there are three things to notice when a dependency is declared:

1. The configuration: `implementation` also known as the scope the dependency is applied to

2. The module ID: `com.google.guava:guava` is made up of a `group` and an artifact `name` which are uniquely identifiable

3. The version: `32.1.2-jre` which is not always required

Dependencies can be local or external. To let Gradle know where to find external dependencies, use the `repositories{}` block in the Build File.

Let’s expand our example:

build.gradle.kts

    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        implementation("com.google.guava:guava:32.1.2-jre")
        api("org.apache.juneau:juneau-marshall:8.2.0")
    }

build.gradle

    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        implementation("com.google.guava:guava:32.1.2-jre")
        api("org.apache.juneau:juneau-marshall:8.2.0")
    }

In this example, Gradle fetches the `guava` and `juneau-marshall` dependencies from the Maven Central and Google repositories.

## 1. Declaring Dependencies

You can add external libraries to your Java project, such as Guava. These libraries are dependencies of your project. They are added using the `dependencies{}` block in your build file.

## 2. Dependency Configurations

You can declare dependencies for different scopes. For example, you can declare dependencies that are only used at compile time. Gradle calls the scope of a dependency a configuration.

## 3. Declaring Repositories

You can declare repositories to tell Gradle where to fetch external dependencies.

During a build, Gradle locates and downloads the dependencies, a process called dependency resolution.

## 4. Centralizing Dependencies

Centralizing dependencies in Gradle involves managing dependencies in a single location to ensure consistency and simplify dependency management across multiple projects.

This is typically done using platforms and version catalogs. A platform is a set of modules intended to be used together. A version catalog is a centralized list of dependency coordinates that can be referenced in multiple projects.

## 5. Dependency Constraints and Conflict Resolution

Conflicts can arise when the same library is declared multiple times or when different libraries provide the same functionality. This usually leads to failing builds.

Gradle manages two types of conflicts: version conflicts, and capability conflicts.

You can customize Gradle’s handling of dependencies and conflict resolution with a number of available APIs.