Build Automation in Java and Gradle: The Odyssey

Ernesto Gonzalez
Strategio
Published in
6 min readFeb 21, 2023

Oh boy! If there is anything that I am scared of, it would be build automation and setting up anything that has to do with it. Nevertheless, just because something is scary to look at doesn't mean it is bad. Washing the dishes, cleaning the floor, driving, cooking, and food delivery are all repetitive, "mundane" tasks that have either been fully or partially automated over time. Automation brings efficiency, and software development is not exempt from this. Over the years, multiple tools have been created to make the life of a software developer more pleasant. Today we will discuss build automation and one of the dozens of tools used for it.

Defining Build Automation

Build automation automates the tasks required to build, test, and deploy a software application. The process of building an application involves many tasks, such as compiling source code, running unit tests, creating executable files (artifacts), and deploying the application to various environments (ex., Render, AWS EC2, Heroku). Build automation helps save time and reduces the potential for errors by automating repetitive tasks and ensuring that the entire process is standardized.

What Are Build Automation Tools Available Out There?

Here are some of the build automation tools available out there:

  • Apache Maven — A widely used build automation tool primarily used for Java projects.
  • Gradle — A flexible and extensible build automation tool that supports multiple languages and platforms.
  • Ant — Another popular build automation tool primarily used for Java projects.
  • Make — A classic build automation tool that has been around for decades and is commonly used for C and C++ projects. My bread and butter for the last five months 😆.
  • Bazel — A build automation tool primarily used for large-scale projects and supports multiple languages.
  • Jenkins — A popular open-source continuous integration and continuous delivery (CI/CD) automation tool.
  • NPM — A package manager for JavaScript projects that can also be used for build automation and task running.
  • Yarn — Another package manager for JavaScript projects that is faster and more reliable than NPM and includes support for build automation and task running.

Today, I want to focus on Gradle, a tool I have been using quite often to build Java projects for the last two weeks. Honestly, I still quite not fully understand it, but I've had a couple of "Aha!" moments that I want to discuss here.

Gradle

A project that uses Gradle as the build automation tool probably has these three main components: build.gradle, gradlew and gradlew.bat , and a settings.gradle file.

settings.gradle is the file where you define the structure of your Gradle project. This file is responsible for including or excluding subprojects, which are individual parts of a larger project that can be built independently. In this file, you can also define the name and version of your project and any other settings specific to your project's structure.

  • On the settings.gradle we could specify the location of our back CORSend and front end, which can be standalone parts of the same project. Just… watch out for CORS errors if you are deploying both the backend and front end to the same instance of a server.

On the other hand, build.gradle is the file where you define the build process for your project. This file is responsible for specifying the dependencies, plugins, tasks, and configurations that are required to build your project. It contains the actual Gradle script that defines the build process, including tasks such as compiling source code, running tests, and packaging the application.

  • At first, this file looked like gibberish to me. I couldn’t comprehend most of it until I started researching.
  • It turns out Gradle files are written in either Groovy or Kotlin. These are two programming languages that, like Java, run on the Java Virtual Machine (JVM). Groovy is the dominant option when it comes to writing Gradle files.

Recently, I worked on a Spring Boot project as part of my training @Strategio. I used a boilerplate generator to create my Spring Boot project, which came with Gradle set up as its automated build tool. Let’s take a look at the build.gradle file:

plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}

group = 'tech.strategio'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

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

The code above is Groovy code. As mentioned, I didn’t quite understand it initially, but now I have a slightly better grasp.

In Groovy, function calls do not require parenthesis as long as there is one parameter. Immediate method calls do not require parenthesis but curly braces. plugins, group, version, sourceCompatibility, dependencies, and tasks are all methods of the class project. In other words, they all are functions provided by a class called project which operates in the build.gradle file. These outer methods are also called closures because they essentially call other functions within themselves and get the returned values of such. In the case of the plugin method, we call the function id three times because we will be using and applying three plugins in our Spring Boot project.

Note we have a repositories method. This method allows us to specify where we will get the dependencies from. In our case, we will access the mavenCentral repository and download all the dependencies listed under the dependencies method. On the dependency method, we are calling four functions. Notice we don’t have a parenthesis? That is because we are using Groovy, and all we need is the method name and its parameters next to it.

In Gradle, a project is constructed through the execution of tasks defined within a task method and invoked as required. It is within this task method that you can establish the tasks that need to be performed. As you can see in the last part, we can also use external tasks by invoking the tasks method, naming new task, and operating the task itself inside the enclosure. In other words, when we execute the task named test, we will run the JUnit test cases, if any.

What do others think?

Again, as mentioned, for me, Gradle was and still is a nightmare to a certain extent. I decided to look for someone else’s experience and found a review from Mohit Goenka, a Senior Engineering Manager. According to him, in recent times, Gradle has become the standard for developing Android applications. Gradle allowed their team to release multiple versions of the same application for different environments. He listed integration and delivery as his pros, technical expertise required, and no easy integration as his cons. He does seem to emphasize how helpful Gradle is in versioning.

In conclusion, build automation is an essential aspect of modern software development, and Gradle is a powerful and flexible build automation tool that can be used to automate the build process of Java applications, Android applications, and web applications. It is a tool that has become the modern build standard for Android development. It might be tedious at first, but in the end, it is all code with some meaning behind it.

As an old wise man once said…

Clap and comment if you like. Suggestions and corrections are always welcomed!

--

--