Renato Ivancic - Software Engineer

Background image

Gradle Dependencies

Gradle

Project Dependencies

Ever wonder why your gradle build is failing because unresolved or not compatible dependencies. Where to get started? To have a visual graph and information about all dependencies in front of your eyes is essential. Here dependencies command should be your answer.

Gradle provides sufficient tooling to navigate large dependency graphs and mitigate situations that can lead to dependency hell.

List all dependencies

By default, dependencies gets listed for all the configurations. This can output a lot of unnecessary information.

For this you can list all of the configurations first.

./gradlew --console plain dependencies | fgrep ' - '

Then you list all the dependencies for this particular configuration

./gradlew dependencies --configuration compileClasspath

In the following result we can clearly see the graph of dependencies that will be used for compiling java project

> Task :dependencies

------------------------------------------------------------
Root project
------------------------------------------------------------

compileClasspath - Compile classpath for source set 'main'.
+--- com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20191001.1
|    \--- com.google.guava:guava:27.1-jre
|         +--- com.google.guava:failureaccess:1.0.1
|         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|         +--- com.google.code.findbugs:jsr305:3.0.2
|         +--- org.checkerframework:checker-qual:2.5.2
|         +--- com.google.errorprone:error_prone_annotations:2.2.0
|         +--- com.google.j2objc:j2objc-annotations:1.1
|         \--- org.codehaus.mojo:animal-sniffer-annotations:1.17
+--- org.apache.commons:commons-lang3:3.10
+--- org.springframework.boot:spring-boot-starter-thymeleaf -> 2.2.6.RELEASE
|    +--- org.springframework.boot:spring-boot-starter:2.2.6.RELEASE
|    |    +--- org.springframework.boot:spring-boot:2.2.6.RELEASE
|    |    |    +--- org.springframework:spring-core:5.2.5.RELEASE
...

List specific dependency

You can also resolve a graph for one specific dependency.

./gradlew -q dependencyInsight --dependency aws-java-sdk-sqs --configuration compileClasspath

Force update dependencies

Once dependency in your Gradle build was fetched from a remote repository it will be cached. Now it can happen that:

  • this dependency was updated,
  • you changed some settings for the maven repository want to test if dependencies are still being resolved
  • dependencies were partially downloaded and you need to redoenload them

In above cases you can use flag for refreshing dependencies:

gradlew build --refresh-dependencies

Refreshing dependencies (Gradle Userguide)

CLI Execution options (Gradle Userguide)

How can I force Gradle to redownload dependencies? (Cloudhadoop)

How can I force gradle to redownload dependencies? (StackOverflow)

Transitive dependency exclusion

Exclude specific transitive dependency from a dependencies

org.springframework.boot:spring-boot-starter-web dependency includes a list of transitive dependencies. Note that Tomcat server is transitive dependency.

+--- org.springframework.boot:spring-boot-starter-web:2.6.2
|    ...
|    |         \--- com.fasterxml.jackson:jackson-bom:2.13.1 (*)
|    +--- org.springframework.boot:spring-boot-starter-tomcat:2.6.2
|    |    +--- jakarta.annotation:jakarta.annotation-api:1.3.5
|    |    +--- org.apache.tomcat.embed:tomcat-embed-core:9.0.56
|    |    +--- org.apache.tomcat.embed:tomcat-embed-el:9.0.56
|    |    \--- org.apache.tomcat.embed:tomcat-embed-websocket:9.0.56
|    |         \--- org.apache.tomcat.embed:tomcat-embed-core:9.0.56
|    +--- org.springframework:spring-web:5.3.14 (*)
...

If you want to replace Tomcat embedded server with Jetty, then you have to exclude Tomcat server first.

Exclude block has two properties group and module. For those of you coming from maven background, group is same as groupId and module is same as artifactId. You don’t need to specify version though.

implementation("org.springframework.boot:spring-boot-starter-web:2.6.2") {
  exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
}

Now spring-boot-starter-tomcat and all its transitive dependencies won’t be included through spring-boot-starter-web and won’t be a part of your application on classpath.

Example of exclusion in real life project on GitHub: https://github.com/FBI-Waring/test_mvparms/blob/03619cd595ade7ee1d301fbe37b7430d1b1e99aa/arms/build.gradle#L30

Question asked on StackOverflow https://stackoverflow.com/questions/21764128/how-do-i-exclude-all-instances-of-a-transitive-dependency-when-using-gradle

Buildscript Dependencies

Sometimes you even need to debug your buildscript configuration itself. Your build script can be broken before the project is even being evaluated. You want to see which plugins are included, what versions of those plugins are defined and which additional dependencies they will bring in.

There is buildEnvironment command that will output dependency tree of buildscript instead of your project.

Example output of buildEnvironment command for a simple SpringBoot project:

rivancic:app rivancic$ ./gradlew buildEnvironment

> Task :buildEnvironment

------------------------------------------------------------
Root project 'app'
------------------------------------------------------------

classpath
+--- org.springframework.boot:org.springframework.boot.gradle.plugin:2.6.7
|    \--- org.springframework.boot:spring-boot-gradle-plugin:2.6.7
|         +--- org.springframework.boot:spring-boot-buildpack-platform:2.6.7
|         |    +--- com.fasterxml.jackson.core:jackson-databind:2.13.2.1
|         |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.13.2
|         |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.2 -> 2.13.2.1
|         |    |    |         +--- com.fasterxml.jackson.core:jackson-annotations:2.13.2 (c)
|         |    |    |         +--- com.fasterxml.jackson.core:jackson-core:2.13.2 (c)
|         |    |    |         +--- com.fasterxml.jackson.core:jackson-databind:2.13.2.1 (c)
|         |    |    |         \--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.2 (c)
|         |    |    +--- com.fasterxml.jackson.core:jackson-core:2.13.2
|         |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.2 -> 2.13.2.1 (*)
|         |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.2.1 (*)
...
|         |    +--- org.apache.commons:commons-compress:1.21
|         |    \--- org.springframework:spring-core:5.3.19 (*)
|         +--- io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE
|         +--- org.apache.commons:commons-compress:1.21
|         \--- org.springframework:spring-core:5.3.19 (*)
+--- io.spring.dependency-management:io.spring.dependency-management.gradle.plugin:1.0.11.RELEASE
|    \--- io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE
\--- name.remal.sonarlint:name.remal.sonarlint.gradle.plugin:1.5.0
     \--- name.remal:gradle-plugins:1.5.0
          +--- name.remal:gradle-plugins-kotlin-dsl:1.5.0
          |    +--- name.remal:gradle-plugins-api:1.5.0
          |    +--- name.remal.tools:common:1.26.147
          |    +--- org.jdom:jdom2:2.0.6
...
          +--- org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:5.12.0.202106070339-r
          |    +--- org.eclipse.jgit:org.eclipse.jgit:5.12.0.202106070339-r
          |    |    \--- com.googlecode.javaewah:JavaEWAH:1.1.7
          |    +--- com.jcraft:jsch:0.1.55
          |    \--- com.jcraft:jzlib:1.1.1
          +--- org.eclipse.jgit:org.eclipse.jgit:5.12.0.202106070339-r (*)
          \--- name.remal.gradle-plugins.test-source-sets:test-source-sets:2.2.0

(c) - dependency constraint
(*) - dependencies omitted (listed previously)

Sources

Viewing and debugging dependencies - Gradle Userguide

Gradle Configurations - Stack Overflow

CLI Listing dependencies - Gradle Userguide

#Gradle #Build tool #Gradle Dependencies