You have already learned how to set up the project in Gradle, run it, and build the application. Now, let's talk about the build.gradle(.kts) file, which is the primary configuration file for a project in Gradle. This knowledge can be applied to any programming language supported by Gradle, such as Java or Kotlin.
Please note that this article is based on Gradle 9.0.0, and there might be some variations in other Gradle versions.
Configuration file
Let's work with the project we set up earlier for creating an application.
.
├── app
│ ├── build.gradle.kts
│ └── src
│ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ └── example
│ │ │ └── App.java
│ │ └── resources
│ └── test
│ ├── java
│ │ └── org
│ │ └── example
│ │ └── AppTest.java
│ └── resources
├── gradle
│ ├── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ └── libs.version.toml
├── gradlew
├── gradlew.bat
├── gradle.properties
└── settings.gradle.ktsYou can find the build.gradle.kts file in the app directory since this is an application-type project. This file comes in two variations: build.gradle for Groovy DSL and build.gradle.kts for Kotlin DSL. It defines the project structure and includes various tasks and external libraries. Let's explore its main components.
Plugins
The plugins section adds plugins to extend the project's capabilities, such as adding new tasks or properties.
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
application
// Apply the plugin which adds support for Kotlin/JVM
kotlin("jvm") version "2.2.0"
// Apply code formatter plugin, using version catalog
alias(libs.plugins.spotless)
}Here alias is a reserved keyword that lets you load plugins defined in the version catalog file (gradle/libs.versions.toml). Here's an example of how to define a plugin in a version catalog.
[versions]
spotless = "7.2.1"
[plugins]
spotless = { id = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" }The plugins for Kotlin and Java understand how to build, package, and run tests on the project. The application plugin helps create an executable JVM application.
There is an alternative way to use plugins in the project. It's more of a legacy approach that isn't widely used now, but you might encounter it:
apply plugin: "application" // for Groovy DSL
apply(plugin = "application") // for Kotlin DSLMany other plugins are available on the official Gradle Plugins page. Large projects can use hundreds of plugins, as Gradle doesn't limit the maximum number of plugins you can use in a project.
Repositories and dependencies
Usually, you don't need to write your program from scratch – you can use existing code written by you or other developers. This is where the dependency system becomes useful.
The repositories section declares locations where Gradle will download and add dependencies to the project.
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}There are many public repositories: JCenter, Maven Central, Google, and others. Typically, a dependency's description specifies which repository contains it.
The dependencies section lets you add external libraries to the project. Gradle automatically downloads them from the repositories and includes them in the application archive. Your dependencies section should include at least one testing library like JUnit or another option, depending on what you chose when initializing the project. First, you need to define it in the version catalog, then use it in build.gradle.kts.
[versions]
guava = "33.4.6-jre"
junit-jupiter = "5.12.1"
[libraries]
guava = { module = "com.google.guava:guava", version.ref = "guava" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }dependencies {
// Use JUnit Jupiter for testing.
testImplementation(libs.junit.jupiter)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// This dependency is used by the application.
implementation(libs.guava)
}You will learn more about repositories and dependencies in the upcoming topics.
This represents a standard part of the Gradle build structure. You apply plugins and specify dependencies for your project. This structure remains consistent across all Gradle-managed projects.
Configurations for the application plugin
The auto-generated build.gradle.kts file contains a section that configures the application plugin, which enables you to run the application using the gradle run command.
application {
// Defines the main class for the application
mainClass = "org.example.App"
}The mainClass property specifies the class containing the entry point of the application. This configuration allows you to run the application by executing the gradle run command.
Generating and running Jar archive
Now, let's explore one more scenario where you can utilize the build.gradle.kts file.
The standard way to run a JVM-based application is to use the java -jar command. You can run this command without Gradle, but you need to have a JAR file first. Let's build the JAR file for our application:
gradle jar
BUILD SUCCESSFUL in 748ms
2 actionable tasks: 2 executedNow, the JAR file is in the app/build/libs directory. If you want to clean all generated artifacts from the project folder, simply run the gradle clean command.
However, if you try to run our generated application using the traditional approach, you'll encounter an issue:
java -jar app/build/libs/app.jar
no main manifest attribute, in app/build/libs/app.jarThe application doesn't contain the Main-Class attribute in the MANIFEST.MF file. As a result, the JVM cannot find the path to the application's entry point.
To resolve this, you need to add the required attribute when generating an archive for the application. Add the following declaration to the build.gradle.kts file:
// for Groovy DSL
jar {
manifest {
attributes("Main-Class": "org.hyperskill.gradleapp.App")
}
}
// for Kotlin DSL
tasks.jar {
manifest {
attributes("Main-Class" to "org.hyperskill.gradleapp.AppKt")
}
}This code adds the Main-Class attribute to the manifest property of the jar task. Think of the manifest as a map of properties where you add your pair Main-Class -> Main.
Now, when you run gradle jar followed by java -jar app/build/libs/app.jar, everything will work correctly, and you'll see the output line Hello world!.
Remember that you can run the java -jar command without Gradle. You just need to have a JAR file ready.
Conclusion
In this topic, you learned about the basic structure of the build.gradle(.kts) file and gained an introduction to plugins, repositories, dependencies, and version catalog. Now you know how to add plugins and repositories to the build.gradle(.kts) configuration file. You explored the application plugin configuration and learned how to troubleshoot JAR file creation issues. In the following topics, you will dive deeper into these concepts to expand your knowledge of Gradle.