As an Android developer, I've always been deep into coding and app design, but kind of skimmed over the whole Gradle thing—even though it's such a key part of our workflow. Recently, I decided to really get to know Gradle, and I want to share what I've learned.
Let's break down some of its complexities and actually understand Gradle.
Understanding Settings file
Let's get started by creating an empty project in Jetbrain's IntelliJ IDEA (Community Edition)
The settings file, either settings.gradle
or settings.gradle.kts
, is the entry point of any Gradle project. Create a new file setting.gradle.kts. Your project structure should appear as follows
Key Components of the Settings File
The settings file serves several purposes, but here are the three primary aspects to keep in mind:
-
Naming Your Project:
Give your project a stable identifier using the
rootProject.name
property.
rootProject.name = "demo-project"
-
Dependency and Plugins:
Specify where Gradle should look for other components your build may depend upon. There are two fundamentally different things:
- The first thing are libraries your production code might need. e.g., an Apache Commons library.
- The second thing are plugins that extend Gradle itself.
These are usually located in the Gradle plugin portal, google and mavenCentral but may also be provided through other binary repositories. Or, you may also define plugins locally in other builds.
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}
pluginManagement{
repositories {
gradlePluginPortal()
google()
}
}
-
Structuring Your Project:
Organize your project into subprojects using the
include()
function. This helps in managing separate components of your application. e.g., we are defining 3 sub-projects "business-logic", "data-model", and "app".
include(":business-logic")
include(":data-model")
include(":app")
Based on the three points discussed, your settings.gradle.kts
file should be structured like this
rootProject.name = "demo-project"
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}
pluginManagement{
repositories {
gradlePluginPortal()
google()
}
}
include(":business-logic")
include(":data-model")
include(":app")
The project structure, once the components are configured in the settings file, should appear as follows
Understanding Build Files
We have created a project with three subprojects namely
- business-login
- data-model
- app
So far, these subprojects are empty and thus have no real meaning to Gradle. We can add a build file to each of them to change this.
The build file, either build.gradle
or build.gradle.kts
, is the heart of Gradle projects.
These files are crucial as they dictate how your project is built, what plugins and dependencies are included, and how your source code is organized.
Key Components of the Build File
Let's take a closer look at the build file for our business-logic project. There are three things to configure in your build files.
- Configuring Plugins: This is the first component in any build file. The plugins section provides structure by specifying the type of project you are building, enabling Gradle and your IDE to understand your project’s layout, compile options, and packaging details. Let’s clarify with an example. In this example, we’ll apply the Java Library Plugin.
plugins {
id("java-library")
}
Applying this plugin turns the subproject into a Java Library project, so Gradle and the IDE know where the source code is located, how the code is compiled, and how it’s packaged into a JAR file.
- Setting Extension: Plugins often come with extensions that enable further customization. For the Java Library plugin, you can access the Java extension to configure compilation specifics, such as targeting a certain Java version.
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
- Defining Dependencies: Dependencies are what your subproject relies on for building and running. They can include other subprojects or external components housed in repositories. Here’s how you can define them:
dependencies {
// Dependency on internal subproject
implementation(project(":data-model"))
// External library dependency
implementation("org.apache.commons:commons-lang3:3.12.0")
}
Here, implementation is used to denote compile-time dependencies. The project keyword assists in referring to subprojects, while the external component is specified through its group, name, and version.
Based on the three points discussed, your business-logic/build.gradle.kts
file should be structured like this
plugins {
id("java-library")
}
java {
sourceCompatibility = org.gradle.api.JavaVersion.VERSION_11
targetCompatibility = org.gradle.api.JavaVersion.VERSION_11
}
dependencies {
implementation(project(":data-model"))
implementation("org.apache.commons:commons-lang3:3.12.0")
}
And Project structure should appear as follows
Sharing my notes/project(which form the base of this and upcoming article/s) as github project .
In our future discussions, we'll delve deeper into advanced Gradle features and plugins, further expanding development toolkit. Till then Keep exploring and building :🚀🚀!