Gradle Introduction and build.gradle
Gradle is a modern build tool that uses Groovy or Kotlin instead of XML. It’s faster than Maven (incremental builds, build cache) and more flexible, though with a steeper learning curve.
Gradle Wrapper
Every Gradle project should include the wrapper — a script that downloads and uses the correct Gradle version:
my-project/
├── gradlew ← Unix wrapper script
├── gradlew.bat ← Windows wrapper script
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── build.gradle ← Build configuration
└── settings.gradle ← Project settings
# Always use the wrapper — NOT system Gradle
./gradlew build # ✅
gradle build # ❌ uses system version — might be different
Generate a wrapper:
gradle wrapper --gradle-version 8.8
Project Structure
Gradle uses the same directory layout as Maven:
src/
├── main/
│ ├── java/
│ └── resources/
└── test/
├── java/
└── resources/
settings.gradle
rootProject.name = 'my-project'
// Multi-module:
// include 'api', 'service', 'common'
build.gradle (Groovy DSL)
plugins {
id 'java'
id 'application'
}
group = 'com.myapp'
version = '1.0.0'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.google.guava:guava:33.2.1-jre'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.3'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
application {
mainClass = 'com.myapp.App'
}
tasks.named('test') {
useJUnitPlatform()
}
build.gradle.kts (Kotlin DSL)
plugins {
java
application
}
group = "com.myapp"
version = "1.0.0"
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.guava:guava:33.2.1-jre")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
application {
mainClass.set("com.myapp.App")
}
tasks.test {
useJUnitPlatform()
}
Groovy vs Kotlin DSL
| Feature | Groovy (.gradle) |
Kotlin (.gradle.kts) |
|---|---|---|
| IDE autocomplete | Limited | ✅ Full |
| Type safety | ❌ Dynamic | ✅ Static |
| Syntax | Shorter | Slightly verbose |
| Adoption | Legacy projects | New projects |
Recommendation: Use Kotlin DSL for new projects — better IDE support and type safety.
Running Builds
# Build (compile + test + jar)
./gradlew build
# Just compile
./gradlew compileJava
# Run tests
./gradlew test
# Run application
./gradlew run
# Clean build output
./gradlew clean
# Clean + build
./gradlew clean build
# List all available tasks
./gradlew tasks
Terminal Output
$ ./gradlew build
> Task :compileJava
> Task :processResources
> Task :classes
> Task :jar
> Task :compileTestJava
> Task :processTestResources
> Task :testClasses
> Task :test
> Task :check
> Task :build
BUILD SUCCESSFUL in 4s
7 actionable tasks: 7 executed
Repositories
repositories {
mavenCentral() // Default — most libraries
mavenLocal() // ~/.m2/repository
google() // Android libraries
maven { // Private repo
url 'https://nexus.mycompany.com/repository/maven-releases/'
credentials {
username = project.findProperty("nexusUser") ?: ""
password = project.findProperty("nexusPass") ?: ""
}
}
}
Gradle Daemon
Gradle runs a background daemon process to speed up builds:
# Check daemon status
./gradlew --status
# Stop daemon
./gradlew --stop
# Run without daemon (CI/CD)
./gradlew build --no-daemon
| Feature | With Daemon | Without Daemon |
|---|---|---|
| First build | ~10s | ~10s |
| Subsequent builds | ~2s | ~10s |
Build Output
build/
├── classes/java/main/ ← Compiled classes
├── classes/java/test/ ← Compiled test classes
├── libs/ ← JAR files
│ └── my-project-1.0.0.jar
├── reports/tests/test/ ← HTML test report
├── test-results/ ← XML test results
└── tmp/ ← Temporary files
Gradle uses
build/(nottarget/like Maven).
Gradle Init — Create New Project
gradle init --type java-application --dsl kotlin
Interactive prompts:
Project name: my-project
Source package: com.myapp
Java version: 21
Build script DSL: Kotlin
Test framework: JUnit Jupiter
Common Mistakes
| Mistake | Fix |
|---|---|
Using gradle instead of ./gradlew |
Always use the wrapper |
Missing useJUnitPlatform() |
JUnit 5 tests won’t run without it |
Committing .gradle/ directory |
Add .gradle/ to .gitignore |
Confusing build/ with target/ |
Gradle uses build/, Maven uses target/ |
Key Takeaways
- Always use
./gradlew(wrapper) — ensures consistent Gradle version. build.gradle(Groovy) orbuild.gradle.kts(Kotlin) — prefer Kotlin for new projects.- Gradle uses the same directory layout as Maven.
- The daemon makes subsequent builds fast.
- Output goes to
build/(nottarget/).
What’s Next?
Next: Gradle Tasks, Dependencies, and Plugins — custom tasks, dependency configurations, version catalogs, and the Spring Boot plugin.