Gradle tricks – display dependencies for all subprojects in multi-project build

Posted: 2014-11-13 in Tricks & Tips
Tags: , ,

gradle dependencies allows to display dependencies in your project printed as pretty ascii tree. Unfortunately it does not work well for submodules in multi-project build. I was not able to find satisfactory solution on the web, so after worked out my own that blog post arose.

Multiple subprojects

For multi-project builds gradle dependencies called in the root directory unexpectedly displays no dependencies:

No dependencies displayed for the root project

No dependencies displayed for the root project

In fact Gradle is right. Root project usually has no code and no compile or runtime dependencies. Only in case of using plugins there could be some additional configurations created by them.

You could think about --recursive or --with-submodules flags, but they do not exist. It is possible to display dependencies for subprojects with “gradle sub1:dependencies” and “gradle sub2:dependencies“, but this is very manual and unpractical for more than a few modules. We could write a shell script, but having regard to (potential) recursive folders traversal there are some catches. Gradle claims to be very extensible with its Groovy based DSL, so why not take advantage of that. Iteration over subprojects can give some effects, but after testing a few conception I ended with pure and simple:

subprojects {
    task allDeps(type: DependencyReportTask) {}

When called gradle allDeps it executes dependencies task on all subprojects.

Dependencies for all subprojects

Dependencies for all subprojects

Remove duplication

All dependencies belong to us, but some parts of the tree looks similar (and duplication is a bad thing). Especially configurations default, compile and runtime and the second group testCompile and testRuntime in most cases contain (almost) the same set of dependencies. To make the output shorter we could limit it to runtime (or in case of test dependencies testRuntime). dependencies task provides convenient parameter --configuration and to focus on test dependencies “gradle allDeps --configuration testRuntime” can be used.

Dependencies in one configuration for all subprojects

Dependencies in one configuration for all subprojects


Where it could be useful? Recently I was pair programming with my old-new colleague in a new project (with dozens submodules) where SLF4J in addition to expected slf4j-logback provider discovered on a classpath also slf4j-simple. We wanted to figure out which library depends on it. Logging dependencies tree to file with a help of grep gave us the answer.

As a bonus during my fights with DependencyReportTask I found an easier way how get know who requires given library. I will write about it in my next post.

Tested with Gradle 2.2.

Gradle logo

  1. Very nice (big) gradle banner, do you work for gradle?

  2. […] Gradle tricks – display dependencies for all subprojects in multi-project build […]

  3. sepadev says:

    For a multiproject setup, i had to use following script:

    subprojects {
    	task allRuntimeDeps(type: DependencyReportTask) {
    			try {
    				configurations = [project.configurations.runtime] as Set
    			} catch(UnknownConfigurationException) {
    				// ignore for projects without desired config
  4. […] Gradle tricks – display dependencies for all subprojects in multi-project build […]

  5. If you would like to analyze result ascii tree dependencies, you can try to use this tool:

  6. Wonderful, what a web site it is! This weblog provides valuable facts to us, keep it up.

  7. Stephen Friedrich says:

    Thanks for sharing!
    If gradle is configured to run tasks in parallel, this wil make the output useless, because it interweaves output from the different subprojects.
    I added this to solve it:
    // Create a chain of dependencies between all sub project’s “allDeps” tasks, so that the output is linear
    // even when we run gradle in default “–parallel” mode.
    def allSubProjects = subprojects as List
    for (def index = 1; index < allSubProjects.size; ++index) {
    allSubProjects[index].tasks.allDeps.dependsOn allSubProjects[index – 1].tasks.allDeps

    • Thanks for sharing. That in fact could be some problem, but for most of the projects I worked with it was doable to just wait a little bit longer executing just that one task. However then, you need to remember to disable the parallel mode :).

      Btw, what Gradle version do you use? I believe in one of the Gradle versions released this year I have seen an improvement which was sorting out the console output in the parallel mode. Therefore, maybe it is already fixed out-of-box in 4.10?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s