# Viewing Dependencies

version 9.7.0-rc-3

Gradle offers tools to navigate the results of dependency management, allowing you to more precisely understand how and why Gradle resolves dependencies. You can render a full dependency graph, identify the origin of a given dependency, and see why specific versions were selected. Dependencies can come from build script declarations or transitive relationships.

To visualize dependencies, you can use:

- The `dependencies` task

- The `dependencyInsight` task

- A Build Scan

## List project dependencies using the `dependencies` task

Gradle provides the built-in `dependencies` task to render a dependency tree from the command line. By default, the task shows dependencies for all configurations within a single project. The dependency tree shows the selected version of each dependency and provides information on conflict resolution.

The `dependencies` task is particularly useful for analyzing transitive dependencies. While your build file lists direct dependencies, the task helps you understand which transitive dependencies are resolved during the build.

    $ ./gradlew dependencies

| To render the graph of dependencies declared in the `buildscript` `classpath` configuration, use the `buildEnvironment` task.

### Understanding output annotations

    $ ./gradlew :app:dependencies

    > Task :app:dependencies

    ------------------------------------------------------------
    Project ':app'
    ------------------------------------------------------------

    annotationProcessor - Annotation processors and their dependencies for source set 'main'.
    No dependencies

    compileClasspath - Compile classpath for source set 'main'.
    \--- com.fasterxml.jackson.core:jackson-databind:2.17.2
         +--- com.fasterxml.jackson.core:jackson-annotations:2.17.2
         |    \--- com.fasterxml.jackson:jackson-bom:2.17.2
         |         +--- com.fasterxml.jackson.core:jackson-annotations:2.17.2 (c)
         |         +--- com.fasterxml.jackson.core:jackson-core:2.17.2 (c)
         |         \--- com.fasterxml.jackson.core:jackson-databind:2.17.2 (c)
         +--- com.fasterxml.jackson.core:jackson-core:2.17.2
         |    \--- com.fasterxml.jackson:jackson-bom:2.17.2 (*)
         \--- com.fasterxml.jackson:jackson-bom:2.17.2 (*)

    ...

The `dependencies` task marks dependency trees with the following annotations:

- `(*)`: Indicates repeated occurrences of a transitive dependency subtree. Gradle expands transitive dependency subtrees only once per project; repeat occurrences only display the root of the subtree, followed by this annotation.

- `(c)`: This element is a dependency constraint, not a dependency. Look for the matching dependency elsewhere in the tree.

- `(n)`: A dependency or dependency configuration that cannot be resolved.

### Specifying a dependency configuration

To focus on a specific dependency configuration, use the optional `--configuration` parameter.

Like project and task names, Gradle allows abbreviated names for dependency configurations. For example, you can use `tRC` instead of `testRuntimeClasspath`, as long as it matches a unique configuration.

The following examples display dependencies for the `testRuntimeClasspath` configuration in a Java project:

    $ ./gradlew -q dependencies --configuration testRuntimeClasspath

    $ ./gradlew -q dependencies --configuration tRC

To view a list of all configurations in a project, including those provided by plugins, run the `resolvableConfigurations` report. For more details, refer to the plugin’s documentation, such as the Java Plugin here.

### Looking at an example

Consider a project that uses the JGit library to execute Source Control Management (SCM) operations for a release process. You can declare dependencies for external tooling with the help of a custom dependency configuration. This avoids polluting other contexts, such as the compilation classpath for your production source code.

The following example declares a custom dependency configuration named `scm` that contains the JGit dependency:

build.gradle.kts

    configurations {
        create("scm")
    }

    dependencies {
        "scm"("org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r")
    }

build.gradle

    configurations {
        scm
    }

    dependencies {
        scm 'org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r'
    }

Use the following command to view a dependency tree for the `scm` dependency configuration:

    $ ./gradlew -q dependencies --configuration scm

    ------------------------------------------------------------
    Root project 'dependencies-report'
    ------------------------------------------------------------

    scm
    \--- org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r
         +--- com.jcraft:jsch:0.1.54
         +--- com.googlecode.javaewah:JavaEWAH:1.1.6
         +--- org.apache.httpcomponents:httpclient:4.3.6
         |    +--- org.apache.httpcomponents:httpcore:4.3.3
         |    +--- commons-logging:commons-logging:1.1.3
         |    \--- commons-codec:commons-codec:1.6
         \--- org.slf4j:slf4j-api:1.7.2

    A web-based, searchable dependency report is available by adding the --scan option.

## Identify the selected version using the `dependencyInsight` task

A project may request two different versions of the same dependency either directly or transitively that may result in a version conflict.

The following example introduces a conflict with `commons-codec:commons-codec`, added both as a direct dependency and a transitive dependency of JGit:

build.gradle.kts

    repositories {
        mavenCentral()
    }

    configurations {
        create("scm")
    }

    dependencies {
        "scm"("org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r")
        "scm"("commons-codec:commons-codec:1.7")
    }

build.gradle

    repositories {
        mavenCentral()
    }

    configurations {
        scm
    }

    dependencies {
        scm 'org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r'
        scm 'commons-codec:commons-codec:1.7'
    }

Gradle provides the built-in `dependencyInsight` task to render a dependency insight report from the command line.

Dependency insights provide information about a single dependency within a single configuration. Given a dependency, you can identify the reason and origin for its version selection.

`dependencyInsight` accepts the following parameters:

`--dependency <dependency>` (mandatory)

  The dependency to investigate. You can supply a complete `group:name`, or part of it. If multiple dependencies match, Gradle generates a report covering all matching dependencies.

`--configuration <name>` (mandatory)

  The dependency configuration which resolves the given dependency. This parameter is optional for projects that use the Java plugin, since the plugin provides a default value of `compileClasspath`.

`--single-path` (optional)

  Render only a single path to the dependency.

`--all-variants` (optional)

  Render information about all variants, not only the selected variant.

The following code snippet demonstrates how to run a dependency insight report for all paths to a dependency named `commons-codec` within the `scm` configuration:

    $ ./gradlew -q dependencyInsight --dependency commons-codec --configuration scm

    commons-codec:commons-codec:1.7
      Variant default:
        | Attribute Name    | Provided | Requested |
        |-------------------|----------|-----------|
        | org.gradle.status | release  |           |
       Selection reasons:
          - By conflict resolution: between versions 1.7 and 1.6

    commons-codec:commons-codec:1.7
    \--- scm

    commons-codec:commons-codec:1.6 -> 1.7
    \--- org.apache.httpcomponents:httpclient:4.3.6
         \--- org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r
              \--- scm

    A web-based, searchable dependency report is available by adding the --scan option.

### Understanding the selection reasons

The "Selection reasons" section of the dependency insight report lists the reasons why a dependency was selected.

Reason | Meaning
--- | ---
(Absent) | No reason other than a reference, direct or transitive, was present.
Was requested : <text> | The dependency appears in the graph, and the inclusion came with a `because` text.
Was requested : didn’t match versions <versions> | The dependency appears with a dynamic version which did not include the listed versions. May be followed by a `because` text.
Was requested : reject version <versions> | The dependency appears with a rich version containing one or more `reject`. May be followed by a `because` text.
By conflict resolution : between versions <version> | The dependency appeared multiple times, with different version requests. This resulted in conflict resolution to select the most appropriate version.
By constraint | A dependency constraint participated in the version selection. May be followed by a `because` text.
By ancestor | There is a rich version with a `strictly` which enforces the version of this dependency.
Selected by rule | A dependency resolution rule overruled the default selection process. May be followed by a `because` text.
Rejection : <version> by rule because <text> | A `ComponentSelection.reject` rejected the given version of the dependency.
Rejection: version <version>: <attributes information> | The dependency has a dynamic version and some versions did not match the requested attributes.
Forced | The build enforces the version of the dependency through an enforced platform or resolution strategy.

If multiple selection reasons exist, the insight report lists all of them.

## Get a holistic view using Build Scan

The dependency tree in a Build Scan shows information about conflicts.

A Build Scan was created for the `commons-codec` example above and a URL was provided with the results.

Head over to the `Dependencies` tab and navigate to your desired dependency. Select the `Required By` tab to see the selection reason and origin of the dependency:

## Resolving unsafe configuration resolution errors

Resolving a configuration can have side effects on Gradle’s project model, so Gradle needs manage access to each project’s configurations. There are a number of ways a configuration might be resolved unsafely. Gradle will produce a deprecation warning for each unsafe access. Each of these are bad practices and can cause strange and indeterminate errors.

If your build has an unsafe access deprecation warning, it needs to be fixed.

For example:

- A task from one project directly resolves a configuration in another project in the task’s action.

- A task specifies a configuration from another project as an input file collection.

- A build script for one project resolves a configuration in another project during evaluation.

- Project configurations are resolved in the settings file.

In most cases, this issue can be resolved by creating a cross-project dependency on the other project. See the how-to guide for sharing outputs between projects for more information.

If you find a use case that can’t be resolved using these techniques, please let us know by filing a GitHub Issue adhering to our issue guidelines.