# Declaring Dependencies between Subprojects

version 8.9

What if one subproject depends on another subproject? What if one project needs the artifact produced by another project?

This is a common use case for multi-project builds. Gradle offers project dependencies for this.

## Depending on another project

Let’s explore a theoretical multi-project build with the following layout:

    .
    ├── api
    │   ├── src
    │   │   └──...
    │   └── build.gradle.kts
    ├── services
    │   └── person-service
    │       ├── src
    │       │   └──...
    │       └── build.gradle.kts
    ├── shared
    │   ├── src
    │   │   └──...
    │   └── build.gradle.kts
    └── settings.gradle.kts

    .
    ├── api
    │   ├── src
    │   │   └──...
    │   └── build.gradle
    ├── services
    │   └── person-service
    │       ├── src
    │       │   └──...
    │       └── build.gradle
    ├── shared
    │   ├── src
    │   │   └──...
    │   └── build.gradle
    └── settings.gradle

In this example, there are three subprojects called `shared`, `api`, and `person-service`:

1. The `person-service` subproject depends on the other two subprojects, `shared` and `api`.

2. The `api` subproject depends on the `shared` subproject.

We use the `:` separator to define a project path such as `services:person-service` or `:shared`. Consult the DSL documentation of Settings.include(java.lang.String[]) for more information about defining project paths.

settings.gradle.kts

    rootProject.name = "dependencies-java"
    include("api", "shared", "services:person-service")

shared/build.gradle.kts

    plugins {
        id("java")
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation("junit:junit:4.13")
    }

api/build.gradle.kts

    plugins {
        id("java")
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation("junit:junit:4.13")
        implementation(project(":shared"))
    }

services/person-service/build.gradle.kts

    plugins {
        id("java")
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation("junit:junit:4.13")
        implementation(project(":shared"))
        implementation(project(":api"))
    }

settings.gradle

    rootProject.name = 'basic-dependencies'
    include 'api', 'shared', 'services:person-service'

shared/build.gradle

    plugins {
        id 'java'
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation "junit:junit:4.13"
    }

api/build.gradle

    plugins {
        id 'java'
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation "junit:junit:4.13"
        implementation project(':shared')
    }

services/person-service/build.gradle

    plugins {
        id 'java'
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation "junit:junit:4.13"
        implementation project(':shared')
        implementation project(':api')
    }

A project dependency affects execution order. It causes the other project to be built first and adds the output with the classes of the other project to the classpath. It also adds the dependencies of the other project to the classpath.

If you execute `./gradlew :api:compile`, first the `shared` project is built, and then the `api` project is built.

## Depending on artifacts produced by another project

Sometimes, you might want to depend on the output of a specific task within another project rather than the entire project. However, explicitly declaring a task dependency from one project to another is discouraged as it introduces unnecessary coupling between tasks.

The recommended way to model dependencies, where a task in one project depends on the output of another, is to produce the output and mark it as an "outgoing" artifact. Gradle’s dependency management engine allows you to share arbitrary artifacts between projects and build them on demand.