Structuring Projects with Gradle
Declaring Dependencies between Subprojects
Sharing Build Logic between Subprojects
Composite Builds
Developing Tasks
Authoring Tasks
Writing Gradle Task Types
Configuring Tasks Lazily
Avoiding Unnecessary Task Configuration
Developing Parallel Tasks
Developing Plugins
Starting Plugin Development
Designing Plugins
Implementing Plugins
Testing Plugins
Publishing Plugins
Best Practices
Organizing Build Logic
Following Best Practices
Other Topics
Gradle managed Directories
Working with Files
Working with Logging
Avoiding Traps
Configuring the Build Environment
Initialization Scripts
Writing Custom Gradle Types and Service Injection
Shared Build Services
Dataflow Actions
Testing a Build with TestKit
Using Ant from Gradle
Authoring JVM Builds
Building Java & JVM projects
Testing Java & JVM projects
Java Toolchains
Toolchains for JVM projects
Toolchain Resolver Plugins
Managing Dependencies
JVM Plugins
Java Library Plugin
Java Application Plugin
Java Platform Plugin
Groovy Plugin
Scala Plugin
Working with Dependencies
Terminology
Learning the Basics
What is Dependency Management?
Declaring Repositories
Declaring Dependencies
Understanding Library and Application Differences
Viewing and Debugging Dependencies
Understanding Resolution
Verifying dependencies
Declaring Versions
Declaring Versions and Ranges
Declaring Rich Versions
Handling Changing Versions
Locking Versions
Controlling Transitives
Upgrading Versions
Downgrading and Excluding
Sharing Versions
Aligning Dependencies
Handling Mutually Exclusive Dependencies
Fixing Metadata
Customizing Resolution
Preventing accidental upgrades
Producing and Consuming Variants of Libraries
Declaring Capabilities of a Library
Modeling Feature Variants and Optional Dependencies
Understanding Variant Selection
Declaring Variant Attributes
Sharing Outputs of Projects
Transforming Artifacts
Publishing Libraries
Setting up Publishing
Understanding Gradle Module Metadata
Signing Artifacts
Customizing Publishing
Maven Publish Plugin
Ivy Publish Plugin
Improving Performance of Gradle Builds
Gradle Daemon
File System Watching
Incremental Build
Using the Build Cache
Enabling and Configuring
Why use the Build Cache?
Understanding the Impact
Learning Basic Concepts
Caching Java Project
Caching Android Project
Debugging Caching Issues
Troubleshooting
Using the Configuration Cache
Inspecting Gradle Builds
Configuring Gradle
Project Properties
Gradle Networking
Authoring C++/Swift Builds
Building C++ projects
Testing C++ projects
Building Swift projects
Testing Swift projects
Gradle on CI
Jenkins
TeamCity
GitHub Actions
Travis CI
Reference
Gradle DSLs and API
Javadoc
Groovy DSL Primer
Groovy DSL Reference
Kotlin DSL Primer
Kotlin DSL API
Groovy to Kotlin DSL Migration
Samples
Command-Line Interface
Gradle Wrapper
Core Plugins
Gradle & Third-party Tools
User Manual PDF
The
recommended way to execute any Gradle build
is with the help of the Gradle Wrapper (referred to as "Wrapper").
The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary.
As a result, developers can get up and running with a Gradle project quickly.
Provisioning the Gradle version for different users is done with a simple Wrapper definition change.
Provisioning the Gradle version for different execution environments (e.g., IDEs or Continuous Integration servers) is done with a simple Wrapper definition change.
Generating the Wrapper files requires an installed version of the Gradle runtime on your machine as described in
Installation
.
Thankfully, generating the initial Wrapper files is a one-time process.
Every vanilla Gradle build comes with a built-in task called
wrapper
.
The task is listed under the group "Build Setup tasks" when
listing the tasks
.
Executing the
wrapper
task generates the necessary Wrapper files in the project directory:
$ gradle wrapper
To make the Wrapper files available to other developers and execution environments, you need to check them into version control.
Wrapper files, including the JAR file, are small.
Adding the JAR file to version control is expected.
Some organizations do not allow projects to submit binary files to version control, and there is no workaround available.
The
type of Gradle distribution
. By default, the
-bin
distribution contains only the runtime but no sample code and documentation.
The
Gradle version
used for executing the build. By default, the
wrapper
task picks the same Gradle version used to generate the Wrapper files.
Optionally, a
timeout
in ms used when downloading the Gradle distribution.
Optionally, a
boolean
to set the
validation of the distribution
URL.
The Gradle version used for downloading and executing the Wrapper.
The resulting distribution URL is validated before it is written to the properties file.
The following labels are allowed:
The Gradle distribution type used for the Wrapper.
Available options are
bin
and
all
.
The default value is
bin
.
--gradle-distribution-url
The full URL pointing to the Gradle distribution ZIP file.
This option makes
--gradle-version
and
--distribution-type
obsolete, as the URL already contains this information.
This option is valuable if you want to host the Gradle distribution inside your company’s network.
The URL is validated before it is written to the properties file.
--gradle-distribution-sha256-sum
The SHA256 hash sum used for
verifying the downloaded Gradle distribution
.
--network-timeout
The network timeout to use when downloading the Gradle distribution, in ms. The default value is
10000
.
--no-validate-url
Disables the validation of the configured distribution URL.
--validate-url
Enables the validation of the configured distribution URL. Enabled by default.
If the distribution URL is configured with
--gradle-version
or
--gradle-distribution-url
, the URL is validated by sending a HEAD request in the case of the
https
scheme or by checking the existence of the file in the case of the
file
scheme.
Let’s assume the following use-case to illustrate the use of the command line options.
You would like to generate the Wrapper with version 8.6 and use the
-all
distribution to enable your IDE to enable code-completion and being able to navigate to the Gradle source code.
The following command-line execution captures those requirements:
$ gradle wrapper --gradle-version 8.6 --distribution-type all
> Task :wrapper
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
As a result, you can find the desired information (the generated distribution URL) in the Wrapper properties file:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
Let’s have a look at the following project layout to illustrate the expected Wrapper files:
A Gradle project typically provides a
settings.gradle(.kts)
file and one
build.gradle(.kts)
file for each subproject.
The Wrapper files live alongside in the
gradle
directory and the root directory of the project.
The following list explains their purpose:
gradle-wrapper.jar
The Wrapper JAR file containing code for downloading the Gradle distribution.
gradle-wrapper.properties
A properties file responsible for configuring the Wrapper runtime behavior e.g. the Gradle version compatible with this version. Note that more generic settings, like
configuring the Wrapper to use a proxy
, need to go into a
different file
.
gradlew
,
gradlew.bat
A shell script and a Windows batch script for executing the build with the Wrapper.
You can go ahead and
execute the build with the Wrapper
without installing the Gradle runtime.
If the project you are working on does not contain those Wrapper files, you will need to
generate them
.
It is always recommended to execute a build with the Wrapper to ensure a reliable, controlled, and standardized execution of the build.
Using the Wrapper looks like running the build with a Gradle installation.
Depending on the operating system you either run
gradlew
or
gradlew.bat
instead of the
gradle
command.
The following console output demonstrates the use of the Wrapper on a Windows machine for a Java-based project:
$ gradlew.bat build
Downloading https://services.gradle.org/distributions/gradle-5.0-all.zip
.....................................................................................
Unzipping C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0-all.zip to C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-al\ac27o8rbd0ic8ih41or9l32mv
Set executable permissions for: C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0\bin\gradle
BUILD SUCCESSFUL in 12s
1 actionable task: 1 executed
If the Gradle distribution is unavailable on the machine, the Wrapper will download it and store it in the local file system.
Any subsequent build invocation will reuse the existing local distribution as long as the distribution URL in the Gradle properties doesn’t change.
Projects typically want to keep up with the times and upgrade their Gradle version to benefit from new features and improvements.
One way to upgrade the Gradle version is by manually changing the
distributionUrl
property in the Wrapper’s
gradle-wrapper.properties
file.
The better and recommended option is to run the
wrapper
task and provide the target Gradle version as described in
Adding the Gradle Wrapper
.
Using the
wrapper
task ensures that any optimizations made to the Wrapper shell script or batch file with that specific Gradle version are applied to the project.
As usual, you should commit the changes to the Wrapper files to version control.
Note that running the wrapper task once will update
gradle-wrapper.properties
only, but leave the wrapper itself in
gradle-wrapper.jar
untouched.
This is usually fine as new versions of Gradle can be run even with older wrapper files.
Once you have upgraded the wrapper, you can check that it’s the version you expected by executing
./gradlew --version
.
Don’t forget to run the
wrapper
task again to download the Gradle distribution binaries (if needed) and update the
gradlew
and
gradle.bat
files.
Most users of Gradle are happy with the default runtime behavior of the Wrapper.
However, organizational policies, security constraints or personal preferences might require you to dive deeper into customizing the Wrapper.
Thankfully, the built-in
wrapper
task exposes numerous options to bend the runtime behavior to your needs.
Most configuration options are exposed by the underlying task type
Wrapper
.
Let’s assume you grew tired of defining the
-all
distribution type on the command line every time you upgrade the Wrapper.
You can save yourself some keyboard strokes by re-configuring the
wrapper
task.
Check out the
API documentation
for a more detailed description of the available configuration options. You can also find
various samples for configuring the Wrapper
in the Gradle distribution.
The Gradle
Wrapper
can download Gradle distributions from servers using HTTP Basic Authentication.
This enables you to host the Gradle distribution on a private protected server.
You can specify a username and password in two different ways depending on your use case: as system properties or directly embedded in the
distributionUrl
.
Credentials in system properties take precedence over the ones embedded in
distributionUrl
.
System properties can be specified in the
.gradle/gradle.properties
file in the user’s home directory or by other
means
.
To specify the HTTP Basic Authentication credentials, add the following lines to the system properties file:
systemProp.gradle.wrapperUser=username
systemProp.gradle.wrapperPassword=password
Embedding credentials in the
distributionUrl
in the
gradle/wrapper/gradle-wrapper.properties
file also works.
Please note that this file is to be committed into your source control system.
The Gradle Wrapper allows for verification of the downloaded Gradle distribution via SHA-256 hash sum comparison.
This increases security against targeted attacks by preventing a man-in-the-middle attacker from tampering with the downloaded Gradle distribution.
To enable this feature, download the
.sha256
file associated with the Gradle distribution you want to verify.
You can download the
.sha256
file from the
stable releases
or
release candidate and nightly releases
.
The format of the file is a single line of text that is the SHA-256 hash of the corresponding zip file.
You can also reference the
list of Gradle distribution checksums
.
Add the downloaded (SHA-256 checksum) hash sum to
gradle-wrapper.properties
using the
distributionSha256Sum
property or use
--gradle-distribution-sha256-sum
on the command-line:
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10
Gradle will report a build failure if the configured checksum does not match the checksum found on the server hosting the distribution.
Checksum verification is only performed if the configured Wrapper distribution hasn’t been downloaded yet.
The
Wrapper
task fails if
gradle-wrapper.properties
contains
distributionSha256Sum
, but the task configuration does not define a sum.
Executing the
Wrapper
task preserves the
distributionSha256Sum
configuration when the Gradle version does not change.
The Wrapper JAR is a binary file that will be executed on the computers of developers and build servers.
As with all such files, you should ensure it’s trustworthy before executing it.
Since the Wrapper JAR is usually checked into a project’s version control system, there is the potential for a malicious actor to replace the original JAR with a modified one by submitting a pull request that only upgrades the Gradle version.
To verify the integrity of the Wrapper JAR, Gradle has created a
GitHub Action
that automatically checks Wrapper JARs in pull requests against a list of known good checksums.
Gradle also publishes the
checksums of all releases
(except for version 3.3 to 4.0.2, which did not generate reproducible JARs), so you can manually verify the integrity of the Wrapper JAR.
The
GitHub Action
is released separately from Gradle, so please check its documentation for how to apply it to your project.
You can manually verify the checksum of the Wrapper JAR to ensure that it has not been tampered with by running the following commands on one of the major operating systems.
Manually verifying the checksum of the Wrapper JAR on Linux:
$ cd gradle/wrapper
If the checksum does not match the one you expected, chances are the
wrapper
task wasn’t executed with the upgraded Gradle distribution.
You should first check whether the actual checksum matches a different Gradle version.
Here are the commands you can run on the major operating systems to generate the actual checksum of the Wrapper JAR.
Generating the checksum of the Wrapper JAR on Linux:
$ sha256sum gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95 gradle/wrapper/gradle-wrapper.jar
Generating the actual checksum of the Wrapper JAR on macOS:
$ shasum --algorithm=256 gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95 gradle/wrapper/gradle-wrapper.jar
Generating the actual checksum of the Wrapper JAR on Windows (using PowerShell):
> (Get-FileHash gradle\wrapper\gradle-wrapper.jar -Algorithm SHA256).Hash.ToLower()
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95
Once you know the actual checksum, check whether it’s listed on
https://gradle.org/release-checksums/
.
If it is listed, you have verified the integrity of the Wrapper JAR.
If the version of Gradle that generated the Wrapper JAR doesn’t match the version in
gradle/wrapper/gradle-wrapper.properties
, it’s safe to run the
wrapper
task again to update the Wrapper JAR.
If the checksum is not listed on the page, the Wrapper JAR might be from a milestone, release candidate, or nightly build or may have been generated by Gradle 3.3 to 4.0.2.
Try to find out how it was generated but treat it as untrustworthy until proven otherwise.
If you think the Wrapper JAR was compromised, please let the Gradle team know by sending an email to
[email protected]
.