Contents

Gradle Cheatsheet

Gradle automates building, testing, and deployment of software from information in build scripts.

https://prod-files-secure.s3.us-west-2.amazonaws.com/f30e4495-2e1e-4eb6-b870-d053c4447a5c/47beb876-6ebe-43fe-87e0-478b6f7575a4/Untitled.png

  • Projects: A Gradle project is a piece of software that can be built, such as an application or a library. Single project builds include a single project called the root project. Multi-project builds include one root project and any number of subprojects.
  • Build Scripts: Build scripts detail to Gradle what steps to take to build the project. Each project can include one or more build scripts.
  • Dependency Management: Dependency management is an automated technique for declaring and resolving external resources required by a project.
  • Tasks: Tasks are a basic unit of work such as compiling code or running your test. Each project contains one or more tasks defined inside a build script or a plugin.
  • Plugins: Plugins are used to extend Gradle’s capability and optionally contribute tasks to a project.

Project Structure

project
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle(.kts)
├── subproject-a
│   ├── build.gradle(.kts)
│   └── src
└── subproject-b
    ├── build.gradle(.kts)
    └── src
  • gradle: Gradle directory to store wrapper files and more
  • libs.versions.toml: Gradle version catalog for dependency management
  • gradlew: Gradle wrapper scripts
  • settings.gradle: Gradle settings file to define a root project name and subprojects
  • build.gradle: Gradle build scripts of the two subprojects - subproject-a and subproject-b
  • src: Source code and/or additional files for the projects

Invoking gradle

Gradle is usually invoked by the IDEs.

For command line, use: gradle build

Most projects do not use the installed version of Gradle. The Wrapper is a script that invokes a declared version of Gradle and is the recommended way to execute a Gradle build. It is found in the project root directory as a gradlew or gradlew.bat file.

The Wrapper provides the following benefits:

  • Standardizes a project on a given Gradle version.
  • Provisions the same Gradle version for different users.
  • Provisions the Gradle version for different execution environments (IDEs, CI servers…).

Understanding the Wrapper files

The following files are part of the Gradle Wrapper:

.
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
  • gradle-wrapper.jar: This is a small JAR file that contains the Gradle Wrapper code. It is responsible for downloading and installing the correct version of Gradle for a project if it’s not already installed.
  • gradle-wrapper.properties: This file contains configuration properties for the Gradle Wrapper, such as the distribution URL (where to download Gradle from) and the distribution type (ZIP or TARBALL).
  • gradlew and gradlew.bat: This is a shell script (Unix-based systems) that acts as a wrapper around gradle-wrapper.jar. It is used to execute Gradle tasks on Unix-based systems without needing to manually install Gradle.
  • gradlew.bat: This is a batch script (Windows) that serves the same purpose as gradlew but is used on Windows systems.

CLI

Executing Gradle on the command line conforms to the following structure:

./gradle [taskName1 taskName2...] [--option-name...]

Options that accept values can be specified with or without = between the option and argument. The use of = is recommended.

./gradle [...] --console=plain

Options that enable behavior have long-form options with inverses specified with --no-. The following are opposites.

./gradle [...] --build-cache and ./gradle [...] --no-build-cache

Many long-form options have short-option equivalents. The following are equivalent:

./gradle --help and ./gradle -h

Executing a task: ./gradle taskName --exampleOption=exampleValue

Name abbreviation: When you specify tasks on the command-line, you don’t have to provide the full name of the task. You can provide enough of the task name to identify the task uniquely. For example, it is likely gradle che is enough for Gradle to identify the check task.

Debugging options

  • ?, h, -help Shows a help message with the built-in CLI options.
  • v, -version Prints Gradle, Groovy, Ant, Launcher & Daemon JVM, and operating system version information and exit without executing any tasks.
  • V, -show-version Prints Gradle, Groovy, Ant, Launcher & Daemon JVM, and operating system version information and continue execution of specified tasks.
  • S, -full-stacktrace Print out the full (very verbose) stacktrace for any exceptions.
  • s, -stacktrace Print out the stacktrace also for user exceptions (e.g. compile error).
  • -scan Create a Build Scan with fine-grained information about all aspects of your Gradle build.
  • Dorg.gradle.debug=true A Gradle property that debugs the Gradle Daemon process. Gradle will wait for you to attach a debugger at localhost:5005 by default.
  • Dorg.gradle.debug.host=(host address) A Gradle property that specifies the host address to listen on or connect to when debug is enabled.
  • Dorg.gradle.debug.port=(port number) A Gradle property that specifies the port number to listen on when debug is enabled. Default is 5005.
  • Dorg.gradle.debug.server=(true,false) A Gradle property that if set to true and debugging is enabled, will cause Gradle to run the build with the socket-attach mode of the debugger. Otherwise, the socket-listen mode is used. Default is true.
  • Dorg.gradle.debug.suspend=(true,false) A Gradle property that if set to true and debugging is enabled, the JVM running Gradle will suspend until a debugger is attached. Default is true.

Performance options

Try these options when optimizing and improving build performance. Many of these options can be specified in the gradle.properties file, so command-line flags are unnecessary.

  • -build-cache, -no-build-cache Toggles the Gradle Build Cache. Gradle will try to reuse outputs from previous builds. Default is off.
  • -configuration-cache, -no-configuration-cache Toggles the Configuration Cache. Gradle will try to reuse the build configuration from previous builds. Default is off.
  • -configuration-cache-problems=(fail,warn) Configures how the configuration cache handles problems. Default is fail.
  • -configure-on-demand, -no-configure-on-demand Toggles configure-on-demand. Only relevant projects are configured in this build run. Default is off.
  • -max-workers Sets the maximum number of workers that Gradle may use. Default is number of processors.
  • -parallel, -no-parallel Build projects in parallel. Default is off.
  • -priority Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are normal or low. Default is normal.
  • -profile Generates a high-level performance report in the layout.buildDirectory.dir("reports/profile") directory. --scan is preferred.
  • -watch-fs, -no-watch-fsToggles watching the file system. When enabled, Gradle reuses information it collects about the file system between builds. Enabled by default on operating systems where Gradle supports this feature*.*

Gradle daemon options

You can manage the Gradle Daemon through the following command line options.

  • -daemon, -no-daemon Use the Gradle Daemon to run the build. Starts the daemon if not running or the existing daemon is busy. Default is on.
  • -foreground Starts the Gradle Daemon in a foreground process.
  • -status (Standalone command) Run gradle --status to list running and recently stopped Gradle daemons. It only displays daemons of the same Gradle version.
  • -stop (Standalone command) Run gradle --stop to stop all Gradle Daemons of the same version.
  • Dorg.gradle.daemon.idletimeout=(number of milliseconds) A Gradle property wherein the Gradle Daemon will stop itself after this number of milliseconds of idle time. Default is 10800000 (3 hours).

Logging options

  • Setting log level
    • -Dorg.gradle.logging.level=(quiet,warn,lifecycle,info,debug)
    • -q, --quiet Log errors only.
    • -w, --warn
    • -i, --info
    • -d, --debug
  • Customizing log format
    • -Dorg.gradle.console=(auto,plain,rich,verbose)
    • --console=(auto,plain,rich,verbose)
  • Showing or hiding warnings
    • -Dorg.gradle.warning.mode=(all,fail,none,summary)
    • --warning-mode=(all,fail,none,summary)

Execution options

The following options affect how builds are executed by changing what is built or how dependencies are resolved.

  • -include-build Run the build as a composite, including the specified build.
  • -offline Specifies that the build should operate without accessing network resources.
  • U, -refresh-dependencies Refresh the state of dependencies.
  • -continue Continue task execution after a task failure.
  • m, -dry-run Run Gradle with all task actions disabled. Use this to show which task would have executed.
  • t, -continuous Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.
  • -write-locks Indicates that all resolved configurations that are lockable should have their lock state persisted.
  • -update-locks <group:name>[,<group:name>]* Indicates that versions for the specified modules have to be updated in the lock file. This flag also implies --write-locks.
  • a, -no-rebuild Do not rebuild project dependencies. Useful for debugging and fine-tuning buildSrc, but can lead to wrong results. Use with caution!

Dependency verification options

  • F=(strict,lenient,off), -dependency-verification=(strict,lenient,off) Configures the dependency verification mode. The default mode is strict.
  • M, -write-verification-metadata Generates checksums for dependencies used in the project (comma-separated list) for dependency verification.
  • --refresh-keys Refresh the public keys used for dependency verification.
  • --export-keys Exports the public keys used for dependency verification.

Environment options

  • b, -build-file (deprecated) Specifies the build file. For example: gradle --build-file=foo.gradle. The default is build.gradle, then build.gradle.kts.
  • c, -settings-file (deprecated) Specifies the settings file. For example: gradle --settings-file=somewhere/else/settings.gradle
  • g, -gradle-user-home Specifies the Gradle User Home directory. The default is the .gradle directory in the user’s home directory.
  • p, -project-dir Specifies the start directory for Gradle. Defaults to current directory.
  • -project-cache-dir Specifies the project-specific cache directory. Default value is .gradle in the root project directory.
  • D, -system-prop Sets a system property of the JVM, for example -Dmyprop=myvalue.
  • I, -init-script Specifies an initialization script.
  • P, -project-prop Sets a project property of the root project, for example -Pmyprop=myvalue.
  • Dorg.gradle.jvmargs A Gradle property that sets JVM arguments.
  • Dorg.gradle.java.home A Gradle property that sets the JDK home dir.

Task options

Tasks may define task-specific options which are different from most of the global options described in the sections above (which are interpreted by Gradle itself, can appear anywhere in the command line, and can be listed using the –help option).

Built-in task options are options available as task options for all tasks. At this time, the following built-in task options exist:

  • -rerun Causes the task to be rerun even if up-to-date. Similar to --rerun-tasks, but for a specific task.

Settings file

The primary purpose of the settings file is to add subprojects to your build. Gradle supports single and multi-project builds.

  • For single-project builds, the settings file is optional.
  • For multi-project builds, the settings file is mandatory and declares all subprojects.

The settings file is a script. It is either a settings.gradle file written in Groovy or a settings.gradle.kts file in Kotlin.

The settings file is typically found in the root directory of the project. An example is:

rootProject.name = 'root-project'   

include('sub-project-a')            
include('sub-project-b')
include('sub-project-c')

Build file

Every Gradle build comprises at least one build script. In the build file, two types of dependencies can be added:

  • The libraries and/or plugins on which Gradle and the build script depend.
  • The libraries on which the project sources (i.e., source code) depend.

The build script is either a build.gradle file written in Groovy or a build.gradle.kts file in Kotlin. An example

plugins {                                                               
    id 'org.jetbrains.kotlin.jvm' version '1.9.0'
    id 'application'
}

repositories {                                                          
    mavenCentral()
}

dependencies {                                                          
    testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    implementation 'com.google.guava:guava:32.1.1-jre'
}

application {                                                           
    mainClass = 'com.example.Main'
}

tasks.named('test') {                                                   
    useJUnitPlatform()
}

Dependency Management

Version Catalog

Version catalogs provide a way to centralize your dependency declarations in a libs.versions.toml file. The catalog makes sharing dependencies and version configurations between subprojects simple. It also allows teams to enforce versions of libraries and plugins in large projects. The version catalog typically contains four sections:

  1. [versions] to declare the version numbers that plugins and libraries will reference.
  2. [libraries] to define the libraries used in the build files.
  3. [bundles] to define a set of dependencies.
  4. [plugins] to define plugins.
[versions]
androidGradlePlugin = "7.4.1"
mockito = "2.16.0"

[libraries]
googleMaterial = { group = "com.google.android.material", name = "material", version = "1.1.0-alpha05" }
mockitoCore = { module = "org.mockito:mockito-core", version.ref = "mockito" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "androidGradlePlugin" }

Declaring Your Dependencies

To add a dependency to your project, specify a dependency in the dependencies block of your build.gradle(.kts) file. The following build.gradle.kts file adds a plugin and two dependencies to the project using the version catalog above:

plugins {
   alias(libs.plugins.androidApplication)  
}

dependencies {
    // Dependency on a remote binary to compile and run the code
    implementation(libs.googleMaterial)    

    // Dependency on a remote binary to compile and run the test code
    testImplementation(libs.mockitoCore)   
}

Dependencies in Gradle are grouped by configurations.

  • The material library is added to the implementation configuration, which is used for compiling and running production code.
  • The mockito-core library is added to the testImplementation configuration, which is used for compiling and running test code.

Tasks

A task represents some independent unit of work that a build performs, such as compiling classes, creating a JAR, generating Javadoc, or publishing archives to a repository.

The build task can be run by: ./gradlew build

Lists available tasks using: ./gradlew tasks

The run task is executed with ./gradlew run

Build scripts can optionally define task dependencies. Gradle then automatically determines the task execution order.

Plugins

Gradle is built on a plugin system. Gradle itself is primarily composed of infrastructure, such as a sophisticated dependency resolution engine. The rest of its functionality comes from plugins.

A plugin is a piece of software that provides additional functionality to the Gradle build system.

Plugins can be applied to a Gradle build script to add new tasks, configurations, or other build-related capabilities:

  • The Java Library Plugin - java-library Used to define and build Java libraries. It compiles Java source code with the compileJava task, generates Javadoc with the javadoc task, and packages the compiled classes into a JAR file with the jar task.
  • The Google Services Gradle Plugin - com.google.gms:google-services Enables Google APIs and Firebase services in your Android application with a configuration block called googleServices{} and a task called generateReleaseAssets.
  • The Gradle Bintray Plugin - com.jfrog.bintray Allows you to publish artifacts to Bintray by configuring the plugin using the bintray{} block.

Plugins are distributed in three ways:

  • Core plugins - Gradle develops and maintains a set of Core Plugins.
  • Community plugins - Gradle’s community shares plugins via the Gradle Plugin Portal.
  • Local plugins - Gradle enables users to create custom plugins using APIs.

Applying a plugin to a project allows the plugin to extend the project’s capabilities. You apply plugins in the build script using a plugin id (a globally unique identifier / name) and a version:

plugins {
    id «plugin id» version «plugin version»
}

Core plugins

Gradle Core plugins are a set of plugins that are included in the Gradle distribution itself. These plugins provide essential functionality for building and managing projects.

Some examples of core plugins include:

  • java: Provides support for building Java projects.
  • groovy: Adds support for compiling and testing Groovy source files.
  • ear: Adds support for building EAR files for enterprise applications.

Core plugins are unique in that they provide short names, such as java for the core JavaPlugin, when applied in build scripts. They also do not require versions.

plugins {
    id("java")
}

Community plugins

Community plugins are plugins developed by the Gradle community, rather than being part of the core Gradle distribution. These plugins provide additional functionality that may be specific to certain use cases or technologies. The Spring Boot Gradle plugin packages executable JAR or WAR archives, and runs Spring Boot Java applications.

To apply the org.springframework.boot plugin to a project:

plugins {
    id("org.springframework.boot") version "3.1.5"
}

Community plugins can be published at the Gradle Plugin Portal, where other Gradle users can easily discover and use them.

Local plugins

Custom or local plugins are developed and used within a specific project or organization. These plugins are not shared publicly and are tailored to the specific needs of the project or organization.

Local plugins can encapsulate common build logic, provide integrations with internal systems or tools, or abstract complex functionality into reusable components.

Gradle provides users with the ability to develop custom plugins using APIs.

To create your own plugin, you’ll typically follow these steps:

  1. Define the plugin class: create a new class that implements the Plugin<Project> interface.
// Define a 'HelloPlugin' plugin
class HelloPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // Define the 'hello' task
        val helloTask = project.tasks.register("hello") {
            doLast {
                println("Hello, Gradle!")
            }
        }
    }
}
  1. Build and optionally publish your plugin: generate a JAR file containing your plugin code and optionally publish this JAR to a repository (local or remote) to be used in other projects.
// Publish the plugin
plugins {
    `maven-publish`
}

publishing {
    publications {
        create<MavenPublication>("mavenJava") {
            from(components["java"])
        }
    }
    repositories {
        mavenLocal()
    }
}
  1. Apply your plugin: when you want to use the plugin, include the plugin ID and version in the plugins{} block of the build file.
// Apply the plugin
plugins {
    id("com.example.hello") version "1.0"
}

Gradle Incremental Builds and Build Caching

Gradle uses two main features to reduce build time: incremental builds and build caching.

An incremental build is a build that avoids running tasks whose inputs have not changed since the previous build. Re-executing such tasks is unnecessary if they would only re-produce the same output.

For incremental builds to work, tasks must define their inputs and outputs. Gradle will determine whether the input or outputs have changed at build time. If they have changed, Gradle will execute the task. Otherwise, it will skip execution.

Incremental builds are always enabled, and the best way to see them in action is to turn on verbose mode. With verbose mode, each task state is labeled during a build.

Info
When you run a task that has been previously executed and hasn’t changed, then UP-TO-DATE is printed next to the task.

Incremental Builds are a great optimization that helps avoid work already done. If a developer continuously changes a single file, there is likely no need to rebuild all the other files in the project.

However, what happens when the same developer switches to a new branch created last week? The files are rebuilt, even though the developer is building something that has been built before.

This is where a build cache is helpful.

The build cache stores previous build results and restores them when needed. It prevents the redundant work and cost of executing time-consuming and expensive processes.

Info
When the build cache has been used to repopulate the local directory, the tasks are marked as FROM-CACHE.

Performance Tips

Gradle is designed for speed. Ensure you are using these features:

  1. Gradle Daemon: A background process that keeps Gradle “warmed up.” It is enabled by default in recent versions.
  2. Parallel Execution: In your gradle.properties, add: org.gradle.parallel=true
  3. Build Cache: Reuses outputs from previous builds (even from other developers!). org.gradle.caching=true
Info
If your build feels slow, run ./gradlew build --scan. It will generate a URL with a comprehensive performance report telling you exactly which task took the longest.

Cheatsheet

  • Build the project: ./gradle build
  • View gradle version: ./gradlew --version
  • Change gradle version: ./gradlew wrapper --gradle-version 7.2
  • Executing a task: ./gradle taskName --exampleOption=exampleValue
  • Executing tasks in multi-project builds: gradle subproject:taskName
  • Run test task: gradle test
  • Executing multiple tasks: gradle test deploy
  • Forcing tasks to execute: gradle test –rerun-tasks
  • Continue the build after a task failure: gradle test –continue
  • Running an application: gradle run
  • Running all checks: gradle check
  • Cleaning outputs: gradle clean
  • List subprojects: gradle projects
  • List tasks: gradle tasks –all
  • Sho task information: gradle -q help –task libs
  • Get dependency report / build scan: gradle build –scan
  • List dependencies: gradle dependencies
  • List project properties: gradle -q api:properties
  • Create new Gradle builds: gradle init –type java-library

References