# View and Debug Dependencies

version 8.4

Gradle provides tooling to navigate dependency graphs and mitigate dependency hell. Users can render the full graph of dependencies as well as identify the selection reason and origin for a dependency. Dependencies can originate through build script declared dependencies or transitive dependencies. You can visualize dependencies with:

- the built-in Gradle CLI `dependencies` task

- the built-in Gradle CLI `dependencyInsight` task

- build scans

## List Project Dependencies

Gradle provides the built-in `dependencies` task to render a dependency tree from the command line. By default, the dependency tree renders dependencies for all configurations within a single project. The dependency tree indicates the selected version of each dependency. It also displays information about dependency conflict resolution.

The `dependencies` task can be especially helpful for issues related to transitive dependencies. Your build file lists direct dependencies, but the `dependencies` task can help you understand which transitive dependencies resolve during your build.

| Graph of dependencies declared in the `buildscript` `classpath` configuration can be rendered using task `buildEnvironment`.

### Output Annotations

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.

### Specify a Dependency Configuration

To focus on the information about one dependency configuration, provide the optional parameter `--configuration`. Just like project and task names, Gradle accepts abbreviated names to select a dependency configuration. For example, you can specify `tRC` instead of `testRuntimeClasspath` if the pattern matches to a single dependency configuration. Both of the following examples show dependencies in the `testRuntimeClasspath` dependency configuration of a Java project:

    > gradle -q dependencies --configuration testRuntimeClasspath

    > gradle -q dependencies --configuration tRC

To see a list of all the configurations available in a project, including those added by any plugins, you can run a `resolvableConfigurations` report.

For more info, see that plugin’s documentation (for instance, the Java Plugin is documented here).

### 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

    repositories {
        mavenCentral()
    }

    configurations {
        create("scm")
    }

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

build.gradle

    repositories {
        mavenCentral()
    }

    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:

    > gradle -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 Dependency Version Selected

A project may request two different versions of the same dependency either directly or transitively. Gradle applies version conflict resolution to ensure that only one version of the dependency exists in the dependency graph. 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'
    }

The dependency tree in a build scan shows information about conflicts. Click on a dependency and select the "Required By" tab to see the selection reason and origin of the dependency.

### Dependency Insights

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 selection reason and origin.

`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.

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:

    > gradle -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.

For more information about configurations, see the dependency configuration documentation.

#### Selection Reasons

The "Selection reasons" section of the dependency insight report lists the reasons why a dependency was selected. Have a look at the table below to understand the meaning of the different terms used:

Table 1. Terminology
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.

## Troubleshooting

### Version Conflicts

If the selected version does not match your expectation, Gradle offers a series of tools to help you control transitive dependencies.

### Variant Selection Errors

Sometimes a selection error happens at the variant selection level. Have a look at the dedicated section to understand these errors and how to resolve them.

### Unsafe Configuration Resolution Errors

Resolving a configuration can have side effects on Gradle’s project model. As a result, Gradle must manage access to each project’s configurations. There are a number of ways a configuration might be resolved unsafely. 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.

Gradle produces a deprecation warning for each unsafe access. Unsafe access can cause indeterminate errors. You should fix unsafe access warnings in your build.

In most cases, you can resolve unsafe accesses by creating a cross-project dependency on the other project. See the documentation 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.