The Comprehensive Guide to Gradle: Dive Deep with Examples

Hiten Pratap Singh
hprog99
Published in
4 min readAug 24, 2023

Gradle is a modern open-source build automation tool that has quickly grown in popularity, becoming the default build tool for Android applications. However, its applicability goes far beyond just Android. With its powerful scripting capabilities based on Groovy and Kotlin DSLs, Gradle can be used to automate the building, testing, publishing, and deploying of software packages or other types of projects.

Understanding Gradle and its Importance

In the realm of software development, building your code is an indispensable step. Gradle automates this process, ensuring that your software consistently compiles and packages correctly. It manages dependencies, runs tests, and does a lot more, allowing developers to focus on writing code.

Key Features of Gradle:

  • Flexibility: Gradle can be used for multiple languages and platforms.
  • Performance: Incremental builds save time by processing only changed files.
  • Extensibility: Write custom tasks and plugins tailored for your needs.

Installing and Setting Up Gradle

Installation:
You can download Gradle from its official website or use package managers like Homebrew (for macOS) or SDKMAN.

$ sdk install gradle 7.0

Setting Up:
After installation, verify its version:

$ gradle -v

Core Concepts

Project and Task:
In Gradle, everything is either a project or a task. A project represents a library, application, or even a set of shared tasks or configurations, while a task represents an atomic unit of work.

Build Script:
This is a file named build.gradle, which is where you configure how Gradle should behave. It can be written using Groovy or Kotlin DSL.

Gradle’s Task Management

Tasks are fundamental in Gradle. You can list all tasks of a project with:

$ gradle tasks

Defining a Task:
In your build.gradle:

task myTask {
doLast {
println 'This is my task.'
}
}

Run it:

$ gradle myTask

Dependency Management with Gradle

Gradle can automatically download and manage dependencies, libraries, and plugins your project needs.
To specify dependencies:

dependencies {
implementation 'com.some.library:library-name:1.0.0'
}

Writing Custom Gradle Plugins

Plugins extend Gradle’s functionality. While there are numerous available plugins, sometimes you may need custom behavior.

Example of Creating a Simple Plugin:
In buildSrc/src/main/groovy/MyPlugin.groovy:

class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('customTask') {
doLast {
println 'This is a custom task from MyPlugin.'
}
}
}
}

Gradle in Action: Practical Examples

Example 1: Java Application Build
Gradle can compile, test, and package Java applications. You just need to apply the Java plugin:

apply plugin: 'java'

Example 2: Android Application Build
For Android applications, you’d apply the Android plugin and specify the Android SDK versions:

apply plugin: 'com.android.application'

android {
compileSdkVersion 30
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 16
targetSdkVersion 30
}
}

Multi-Project Builds

Often, larger projects are divided into sub-projects, each handling a specific aspect of the application. Gradle excels in managing such multi-project builds.

Setting up a Multi-Project Build:
Imagine you have an application with a main app and a utilities library.
Your directory structure might look like:

/my-application
/app
/utilities

In the root project’s settings.gradle:

include 'app', 'utilities'

You can now define specific build scripts for each sub-project or share common configurations from the root project.

Gradle Wrapper

The Gradle Wrapper ensures that anyone building your project will use the same version of Gradle. This helps maintain consistency.
To set up the wrapper, run:

$ gradle wrapper --gradle-version 7.0

This creates a gradlew script and a gradlew.bat script for Windows.

Advanced Dependency Management

Gradle’s dependency resolution is powerful and offers features like conflict resolution and dependency insight.

Excluding a Transitive Dependency:

implementation('com.example:library:1.0.0') {
exclude group: 'com.unwanted.library'
}

Specifying Repositories:
By default, Gradle looks in Maven Central. However, you can specify other repositories:

repositories {
mavenCentral()
google()
jcenter()
}

Composite Builds

Imagine you're working on two Gradle projects, ProjectA and ProjectB, and ProjectA depends on ProjectB.
You can define this relationship in settings.gradle of ProjectA like so:

includeBuild '../ProjectB'

Now, when you build ProjectA, Gradle will also build ProjectB if necessary. This way, you don't have to publish ProjectB to test changes in ProjectA.

Gradle’s Build Cache

Here’s how to enable the local build cache in your settings.gradle:

buildCache {
local {
enabled = true
}
}

And for the remote cache:

buildCache {
remote(HttpBuildCache) {
url = 'http://build-cache.mycompany.com:8123/cache/'
}
}

Migrating from Maven to Gradle

Start by running

$ gradle init

This will attempt to convert your pom.xml to a build.gradle.

After that, verify dependencies and plugins. Here’s a basic mapping example:

Maven:

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>

Gradle:

dependencies {
testImplementation 'junit:junit:4.13.2'
}

With the depth and breadth of features offered by Gradle, it’s clear that it’s more than just a build tool. It’s an environment that can be molded and extended to fit almost any need. Its adaptability, performance-driven nature, and continuous evolution make it indispensable in modern software development. Whether you’re setting up a small Java project or managing a vast enterprise application, Gradle offers the tools, flexibility, and efficiency you need.

--

--