Skip to main content

How to use gradle to find dependency tree

A quick guide to creating an easy to read report of your dependency tree using Gradle. 

Inspecting Dependencies 

Gradle provides enough tools to navigate large dependency graphs and solve situations that can lead to dependency hell. You can choose to render the full graph of dependencies as well as identify the selection reason and origin for a dependency.

Listing dependencies in your project

Rendering the dependency tree is particularly useful if you'd like to identify which dependencies have been resolved at runtime and get valuable information in case any dependency conflict resolution occurred. The dependency report will contain declared and transitive dependencies.

Every Gradle project provides the task dependencies for rendering the so-called dependency report from the command line. By default, the dependency report presents dependencies for all configurations. To print information for a specific configuration, you need to provide the optional parameter        
--configuration

Available configuration in Android projects

  • debug
  • debugCompileClasspath - Dependencies for compilation
  • debugRuntimeClasspath - Dependencies for runtime/packaging
  • debugAndroidTest
  • debugAndroidTestCompileClasspath - Dependencies for compilation
  • debugAndroidTestRuntimeClasspath - Dependencies for runtime/packaging
  • debugUnitTest
  • debugUnitTestCompileClasspath - Dependencies for compilation
  • debugUnitTestRuntimeClasspath - Dependencies for runtime/packaging
  • release
  • releaseCompileClasspath - Dependencies for compilation
  • releaseRuntimeClasspath - Dependencies for runtime/packaging
  • releaseUnitTest
  • releaseUnitTestCompileClasspath - Dependencies for compilation
  • releaseUnitTestRuntimeClasspath - Dependencies for runtime/packaging

Example: Using Android Studio to render the dependency graph

Additionally, the Android Gradle plugin also provides a task to print the dependency tree for all configurations directly from Android Studio.




When working on large projects, is inevitably deal with an increased number of dependencies whether through direct or transitive dependencies. The dependency report provides us with the raw list of dependencies. Let's see how can we get more dependency insights.

Example: Rendering the dependency report for the dependencies for runtime/packaging using the console.

>gradlew app:dependencies --configuration debugRuntimeClasspath

> Task :app:dependencies 

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

debugRuntimeClasspath - Resolved configuration for runtime for variant: debug
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.61
|    \--- org.jetbrains.kotlin:kotlin-stdlib:1.2.61
|         +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.2.61
|         \--- org.jetbrains:annotations:13.0
+--- com.android.support:appcompat-v7:28.0.0-rc02
|    +--- com.android.support:support-annotations:28.0.0-rc02
|    +--- com.android.support:support-compat:28.0.0-rc02
|    |    +--- com.android.support:support-annotations:28.0.0-rc02
...

- some dependencies have been omitted 

Now we can see identify dependency conflicts and the selection reason and track down the origin of the dependency. When resolving dependencies issues, we usually want to look for a particular dependency and to do that; we can use the Gradle task dependencyInsight to render the so-called dependency insight report from the command line. 

Example: Rendering the dependency insight report from the command line


>gradlew -q app:dependencyInsight --dependency runtime --configuration debugRuntimeClasspath


android.arch.core:runtime:1.1.1 (conflict resolution)
+--- android.arch.lifecycle:extensions:1.1.1
|    +--- debugRuntimeClasspath
|    \--- org.koin:koin-android-architecture:0.9.3
|         \--- debugRuntimeClasspath
+--- android.arch.lifecycle:livedata:1.1.1
|    \--- android.arch.lifecycle:extensions:1.1.1 (*)
+--- android.arch.lifecycle:livedata-core:1.1.1
|    +--- com.android.support:loader:28.0.0-rc02
|    |    +--- com.android.support:support-fragment:28.0.0-rc02
|    |    |    +--- com.android.support:design:28.0.0-rc02
|    |    |    |    \--- debugRuntimeClasspath
|    |    |    +--- com.android.support:appcompat-v7:28.0.0-rc02
|    |    |    |    +--- debugRuntimeClasspath
|    |    |    |    \--- com.android.support:design:28.0.0-rc02 (*)
|    |    |    +--- android.arch.lifecycle:extensions:1.1.1 (*)
....

android.arch.lifecycle:runtime:1.1.1 (conflict resolution)
+--- android.arch.lifecycle:extensions:1.1.1
|    +--- debugRuntimeClasspath
|    \--- org.koin:koin-android-architecture:0.9.3
|         \--- debugRuntimeClasspath
\--- com.android.support:support-compat:28.0.0-rc02
     +--- com.android.support:design:28.0.0-rc02
     |    \--- debugRuntimeClasspath
     +--- com.android.support:appcompat-v7:28.0.0-rc02
     |    +--- debugRuntimeClasspath
     |    \--- com.android.support:design:28.0.0-rc02 (*)
     +--- com.android.support:support-vector-drawable:28.0.0-rc02
     |    +--- com.android.support:appcompat-v7:28.0.0-rc02 (*)
     |    \--- com.android.support:animated-vector-drawable:28.0.0-rc02
     |         \--- com.android.support:appcompat-v7:28.0.0-rc02 (*)
     +--- com.android.support:transition:28.0.0-rc02
     |    \--- com.android.support:design:28.0.0-rc02 (*)
     +--- com.android.support:recyclerview-v7:28.0.0-rc02
     |    \--- com.android.support:design:28.0.0-rc02 (*)
     +--- com.android.support:support-v4:26.1.0
     |    \--- com.google.android.gms:play-services-basement:15.0.1
  ....

android.arch.persistence.room:runtime:1.1.1
+--- debugRuntimeClasspath
\--- android.arch.persistence.room:rxjava2:1.1.1
     \--- debugRuntimeClasspath
...

In the example, we can see that the origin fort he runtime dependency and identify conflicts and track down the dependency selection to resolve issues.

You can think of the dependency insight report as the inverse representation of the dependency report for a given dependency. 

Using the project report plugin

The project report plugin adds some tasks to generate dependency reports. These tasks create the same results than running the commands from the terminal. In contrast to the command line, the report plugin creates a file.

To use the project report plugin. Add the plugin to the app build.gradle

apply plugin: 'project-report' 

And generate the dependency and dependency insight report in HTML using the command line. 

>gradlew htmlDependencyReport

Conclusion

We've reviewed different ways to visualize and analyze the dependency tree and get insights about how Gradle resolves dependencies in your project for different configurations which can be very handy when resolving dependency issues.

What problems have you faced in your projects with conflicting dependencies? Leave your answer in a comment down below and remember to hit the subscribe button!


Comments

Popular posts from this blog

Hello World!

Hi, welcome to my blog. I'm going to use this space to write about how to build Android apps and share my background and some lessons learned for the past 4 years working as an Android developer. Software development is growing very fast, with tons of new languages, frameworks, components released so, we the developers have to be up to date and take advantage of the latest technologies and tools if we want to succeed. That is my goal with this project to help people out there trying to come into this space. If you are new to Android development you come to the right place. Stay tuned, in my first blog series I'll be writing about Kotlin for Android Development and I'll teach you how to build your first app. I am very excited to start this journey and be able to connect with you. I want to know what your next app idea is. Leave a comment down below and don't forget to hit the subscribe button. I'll leave here a picture of me back in 2016 at the G...

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun

Today I updated my Mac to OS Sierra, and when I opened Android Studio, I was getting an error about Git configuration So I went to Preferences/Git, and I make sure the path to git executable was working by clicking on the Test button, and that's when I got this error :  xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun I figure I'd post this in case someone else runs into the same situation. The solution:  xcode-select --install Happy coding!