# Gradle

## Summary


Gradle is an open-source build automation tool. A build process typically picks correct versions of project source code, resolves dependencies, assembles necessary assets, checks code against coding guidelines, executes unit tests, compiles code, and publishes the resulting software artifacts. Gradle can do all of these.

Gradle is performant, flexible and extensible. Via both convention and configuration, it balances ease of use and flexibility. Through plugins, the basic feature set of Gradle can be extended. It runs on the JVM and hence can be used on any platform. Gradle can be used for projects written in Java, C++, Swift, and more. Many IDEs and CI/CD tools support Gradle. 

Since it's release in 2008, adoption of Gradle has grown steadily. In 2020, Maven continued to be the more popular build tool for traditional Java applications. However, Gradle is more widely used by Android mobile app developers.

## Discussion

### What are the main features of Gradle?

Gradle has dozens of features. These relate to authoring of build scripts, Gradle execution, and integrations to IDEs, languages and repositories. 

Writing build scripts is made easy with Groovy or Kotlin Domain-Specific Language (DSL). Well-defined conventions make it easier for developers to write build scripts. However, Gradle is flexible enough to allow easy customization. 

Gradle downloads and manages transitive dependencies. Even files can be declared as dependencies. Remote dependencies can be cached locally. By locking dynamic dependencies to specific versions, builds become deterministic and reproducible. 

For performance, Gradle does incremental builds, skipping tasks and subtasks when their inputs haven't changed. It caches previous builds. It executes tasks in parallel. Build scans enable developers to analyse and compare past builds to find problems or optimize builds. Execution can be controlled via options. For example, some tasks can be excluded. Build can be configured to continue despite failures. 

Gradle has specific features and support for Java, Groovy, Scala, Android, C/C++, Assembler, GCC, Clang, CUnit, etc. The Gradle Tooling API allows Gradle SDK to be used within IDEs and CI/CD tools. 


### Which are the main building blocks of Gradle?

A **task** contains logic to execute something specific, such as compiling, testing or deploying software. Gradle comes with many in-built tasks and developers can create custom tasks. Tasks are composed of inputs, actions and outputs. 

A **build** is the execution of a set of tasks. A **project** is what a build achieves. For example, assembling a jar, war or zip file can be a project. Projects can have sub-projects. A build can contain more than one project. A project's build script is named `build.gradle` or `build.gradle.kts`. Build happens in three phases: initialization (set up the build environment for relevant projects), configuration (which tasks to run) and execution (run tasks). Execution can be started from command line or from an IDE. 

Gradle's design is minimalistic. It's extended by plugins. A **plugin** helps us reuse logic or configuration across projects. It helps us write more maintainable build scripts. 


### How does Gradle compare against Apache Maven?

It's claimed that Gradle is 2x faster than Maven for most cases and 100x faster for large builds. This is mainly due to incremental builds, better build caching and the Gradle daemon. Gradle daemon runs in the background, thus eliminating JVM startup time. It caches information across builds. It watches the file system to determine what needs to be built even before a build is started. Gradle's Build Scan helps developers visualize and optimize builds. 

Maven relies on XML for build configuration. Gradle scripts are in DSL. They're configuration but they're also code. They can be easier to maintain than XML. 

Gradle is more flexible. It's Tooling API allows us to embed it into IDEs and other tools. Customization with Maven can be hard. While Maven has better support with IDEs, Gradle is getting better here, particularly with Kotlin DSL. 

While Maven can override a dependency by version, Gradle has dependency selection and substitution rules. These can be declared once and used project-wide. Substitution enables composite builds across projects. In fact, it's been said that Maven is not suited for multi-project builds. 


### What's the right way to organize a Gradle project?

Start by running `gradle wrapper`. Then launch Gradle with `gradlew` (Linux) or `gradlew.bat` (Windows). The wrapper automatically installs Gradle and eases future upgrades.  

Follow common conventions in organizing files and folders. For example, keep Java and Kotlin files in separate folders. Keep unit tests separate from integration tests. 

Gradle always looks for the `settings.gradle` file. Create at least an empty file to speed up the search for this file. Properties can be specified in `gradle.properties`. Properties specified in build scripts can be hard to maintain. Properties passed via the command line are useful for ad hoc scenarios. 

Each task should write its output to a separate folder. This allows Gradle to apply incremental build for faster builds. Due to incremental build, there's no need to clean before a build. 

When the build script file `build.gradle` becomes large and unmaintainable, it's a good idea to modularize it into multiple files and organize them within a `buildSrc/` folder. Thus declarations are separated from implementations. Additional dependencies can be in `buildSrc/build.gradle`. 


### What are some best practices when using Gradle?

Write build scripts in a declarative manner. DSL enables this. Avoid writing imperative code in build scripts. Complex imperative code can be moved to a binary plugin.  

When a project has many dependencies, the ordering of repositories might matter. The more often used repositories should be listed first. 

Minimize logic during the configuration phase of a build. These would be executed every time even when the associated task is not executed. 

Use multi-project or composite builds rather than triggering another build using the `GradleBuild` task type. Avoid inter-project configuration, such as depending on a task from another project. 

On multicore systems, run tests in parallel with `test { maxParallelForks 3 }`. 

Don't include passwords in build scripts or `gradle.properties` file. 

Avoid using internal Gradle APIs. Their use can break build scripts if Gradle or plugins change. For example, don't use `org.gradle.internal.os.OperatingSystem`. Instead, call `System.getProperty("os.name")` from Apache Commons SystemUtils. 

Use the Gradle lint plugin to enforce a coding style to build scripts. Follow conventions when declaring tasks. An example is to always declare `group` and `description` so that tasks become discoverable. 

More best practices are shared by Liutikas and Zhuk.

## Milestones

2008

Dockter and Murdoch start working on Gradle. At this time, the project is open source and there's no commercial entity behind it. 

2010

**Gradle Inc.** is founded. Some major open source projects migrate to Gradle for their build processes. Gradle wins the Springy Award. 

Jun  
2012

**Gradle v1.0** is released. 

2013

Google's Android project adopts Gradle as the default build tool. Android Studio installation comes with the **Android Gradle plugin**. Over the years, a version compatibility matrix develops, mapping the versions of Android Studio, the plugin and Gradle. 

Jul  
2014

**Gradle v2.0** is released. This release removes many deprecated features and API. It simplifies the codebase. It improves performance, particularly for large builds. It uses Java 8 (Java 5 is no longer supported) and Groovy 2.3.2 (earlier this was Groovy 1.8). 

2015

Gradle achieves **one million downloads per month**. A 2016 study of 10,000 projects shows that Maven is the most popular build tool (53%) while Gradle is used by only 11% of the projects. However, Gradle adoption continues to grow, reaching 10M downloads per month (2019) and 30M downloads per month (2022). 

Aug  
2016

**Gradle v3.0** is released. This release enables Gradle Daemon by default. There's better IDE support for IDEA and Eclipse. While Groovy remains the primary build language, now there's support for Kotlin as well. Java 9 is supported. **Gradle Cloud Services** is part of the release and *Build Scans* is the first such service. A build scan provides insights into a build and identifies problems. **Gradle Enterprise** (first released in June 2016) is an on-premise version of Gradle Cloud Services. 

Jun  
2017

**Gradle v4.0** is released. This release makes *Build Cache* production-ready for Java and Groovy compilation. Logging and terminal display are improved. 

Nov  
2018

**Gradle v5.0** is released. Builds are now faster. Fine-grained dependency management is supported. Kotlin DSL is now production-ready. This enables code completion, error highlighting, quick documentation and refactoring. Task timeouts and Java 11 support are further additions. 

Nov  
2019

**Gradle v6.0** is released. This release improves dependency management and performance. It adds support for JDK13. 

Apr  
2021

**Gradle v7.0** is released. With file system watching enabled by default, incremental builds are faster. Builds are made more secure by running integrity checks on the dependencies. There's support for Java 16. In multi-project builds, dependency versions can be shared using an experimental feature called *version catalogs*.