Chapter 15Lesson 01~165 minutes

Gradle Installation, Wrapper, CLI, Settings, Build Scripts, and Project Bootstrap: Concepts, Architecture, and Mental Model

Build a precise Gradle bootstrap mental model before running build logic: which executable starts the build, which JVM runs Gradle, which files define the build, and which directories are disposable state rather than source.

Gradle 9.7.1WrapperSettingsBuild scriptsGradle User Home

Build a precise Gradle bootstrap mental model before running build logic: which executable starts the build, which JVM runs Gradle, which files define the build, and which directories are disposable state rather than source.

Learning objectives

  • Explain why a system Gradle installation is a bootstrap tool while a checked-in Wrapper is the normal project execution contract.
  • Distinguish settings.gradle(.kts) build structure from build.gradle(.kts) project build logic.
  • Separate Gradle User Home from project-local .gradle/ state and generated build/ outputs.
  • Describe how the Gradle client JVM, Daemon JVM, and Java toolchains can be related but are not the same configuration.
  • Read task/project information before running mutation-heavy tasks.
  • Identify the Wrapper scripts, Wrapper JAR, distribution URL, distribution SHA-256, and trust boundaries that must be reviewed before execution.

1. The practical problem: “Gradle works here” does not identify the build engine

A developer can type gradle build and a CI job can type ./gradlew build while both appear to run “Gradle.” They may actually use different Gradle releases, different runtime JVMs, different user-home configuration, and different cached distributions. Those are build inputs, not workstation trivia.

Chapter 14 ended with a Maven migration dossier. Chapter 15 starts the Gradle half of the course by establishing a similarly explicit baseline: which Gradle distribution executes this repository, which JVM hosts it, which source-controlled scripts define it, and which state may safely be discarded.

Production invariant: once a trusted Wrapper exists, developers and CI should invoke the project Wrapper rather than relying on whatever gradle happens to be on PATH.

2. Current baseline: Gradle 9.7.1, runtime JVM 17–26, project target Java 17

For this chapter the concrete, timestamped baseline is Gradle 9.7.1, released August 19, 2026. Gradle 9.7.1 requires a JVM from 17 through 26 to execute Gradle. The lab machine may run Gradle on JDK 21 while the Java project targets Java 17 through toolchain configuration.

Identity Chapter pin Why it matters
Gradle distribution 9.7.1 Defines build-engine behavior and built-in plugins.
Gradle runtime JVM JDK 21 in examples Hosts the client/daemon; must be supported by Gradle.
Project Java target 17 Compiler/test target is a separate decision from the runtime JVM.
Wrapper distribution SHA-256 acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a Authenticates the downloaded -bin ZIP against the reviewed expected digest.
Wrapper JAR SHA-256 7a9ce74cff467ca1bf60a4fcd9f05185acceda4d0f382434d393e17864262c5d Lets reviewers verify the executable Wrapper bootstrap JAR.

The phrase “Java version” is therefore ambiguous. Always ask whether it means the shell/client JVM, daemon JVM, compiler toolchain, or application runtime target.

3. Mental model: source-controlled build contract → executable graph → disposable state

Gradle bootstrap and execution flow
flowchart TD
  A["gradlew / gradlew.bat"] --> B["gradle-wrapper.jar"]
  C["gradle-wrapper.properties"] --> B
  B --> D["Verified Gradle 9.7.1 distribution"]

  E["JAVA_HOME / daemon criteria"] --> D

  F["settings.gradle.kts"] --> G["Build structure"]
  H["build.gradle.kts"] --> I["Project model and tasks"]

  D --> G
  D --> I

  G --> J["Selected task graph"]
  I --> J
  J --> K["build/ outputs"]

  D --> L["GRADLE_USER_HOME caches / daemon / wrapper dists"]
  D --> M["project .gradle state"]
  

The Wrapper scripts start the bootstrap JAR. The properties file tells that bootstrapper which distribution to provision and, when configured, which SHA-256 it must match. Gradle then evaluates settings to establish build structure and build scripts to configure projects/tasks. Execution writes generated outputs under build/ and performance state under project/user-home caches. No arrow says “the cache is the build definition”: caches are accelerators, not authority.

4. Four state stores beginners must not collapse into one “Gradle folder”

State store Examples Authority / lifecycle
Repository build definition settings.gradle.kts, build.gradle.kts, gradle.properties, Wrapper files Reviewed source-controlled inputs.
Gradle User Home caches/, daemon/, wrapper/dists/, init.d/ User/agent state; may inject global behavior and is a trust boundary.
Project-local Gradle state .gradle/ Transient project state for incremental/configuration features; not source truth.
Build outputs build/classes, build/libs, build/test-results Generated evidence/artifacts; reproduce from controlled inputs.

5. Settings script and build script answer different questions

The settings script is evaluated during initialization and describes the build: root name, included projects, plugin-management/repository-management boundaries, and other build-wide setup. The build script configures a Project: plugins, dependencies, tasks, Java toolchains, testing, packaging, and related behavior.

// settings.gradle.kts
rootProject.name = "wrapper-lab"

// build.gradle.kts
plugins {
    application
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

application {
    mainClass = "dev.academy.bootstrap.App"
}

Single-project builds can operate without an explicit settings file, but keeping one makes the build identity deliberate. Multi-project builds require settings to declare the project structure; deeper project modeling arrives later in the Gradle chapters.

6. Wrapper files are executable supply-chain inputs

The Wrapper consists of gradlew, gradlew.bat, gradle/wrapper/gradle-wrapper.jar, and gradle/wrapper/gradle-wrapper.properties. The JAR executes before your normal build logic and may download a Gradle distribution, so a Wrapper change deserves the same review discipline as other executable build dependencies.

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
distributionSha256Sum=acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

The distribution checksum verifies the downloaded ZIP. It does not verify that a malicious reviewer-replaced gradle-wrapper.jar is genuine; verify the Wrapper JAR separately against Gradle’s published Wrapper-JAR checksum.

7. CLI mental model: global options + task paths + task options

Gradle commands select tasks from a task graph. ./gradlew tasks is a read-oriented discovery command; ./gradlew build executes the lifecycle tasks contributed by the applied plugins. Options such as --version, --status, --no-daemon, and --console=plain change invocation behavior or output rather than becoming tasks.

# POSIX — read identity and model before mutation
./gradlew --version
./gradlew -q projects
./gradlew tasks --all
./gradlew help --task build

Task paths become important in multi-project builds: :app:test names a task in project :app, while plain test may match tasks relative to the current build context. This chapter stays with one project so the bootstrap model remains small.

8. The client JVM, Daemon JVM, and toolchain can intentionally differ

Gradle starts a client JVM when the Wrapper script launches. Normally it connects to or starts a compatible Gradle Daemon, which hosts the build engine. Daemon selection considers Gradle version, Java home/version, and JVM arguments. A Java toolchain configured in the build can then select another JDK for compilation or testing.

Diagnostic consequence: seeing java -version is not enough. Capture ./gradlew --version and, when daemon behavior matters, inspect daemon status/logs or daemon JVM criteria as well.

9. Read-only inspection before bootstrap changes

# POSIX
java -version
gradle --version 2>/dev/null || echo "No system Gradle on PATH"

# Only after Wrapper files have been reviewed/verified:
./gradlew --version
./gradlew -q projects
./gradlew tasks --all
./gradlew --status

The first two commands describe the workstation. The Wrapper command describes the repository contract. projects proves the settings-derived structure, tasks proves available task names, and --status observes compatible daemons. None of them proves that a build is trustworthy; they establish evidence before changes.

10. DevOps connection: bootstrap identity is part of CI provenance

A CI job that runs a globally installed Gradle can silently change behavior when the runner image changes. A verified Wrapper moves the Gradle version into reviewable repository state. Pair it with an explicit runtime JDK and controlled Gradle User Home/cache policy, and CI can explain which engine produced an artifact.

This does not mean “commit every Gradle-generated file.” Commit the Wrapper and build definitions; treat .gradle/ and build/ as generated state. Cache restore may improve speed, but a cache hit is never proof of artifact provenance by itself.

Knowledge check

Why is gradle build a weaker reproducibility contract than ./gradlew build?

Does distributionSha256Sum authenticate gradle-wrapper.jar?

A build runs Gradle on JDK 21 and compiles with Java 17. Is that contradictory?

Where would a global init script normally live?

Should build/ or project .gradle/ be treated as source-controlled build definitions?

11. Bridge to the guided workflow

You now have the map. Lesson 2 will create a disposable Java project, use a trusted system Gradle only for initial bootstrap, immediately pin and verify the Wrapper, then switch every normal operation to ./gradlew/gradlew.bat.

Official references and version notes

Version snapshot: These lessons were generated for August 24, 2026 with Gradle 9.7.1 as the pinned lab release. Re-check the official release and compatibility pages before copying version-specific pins into a future production repository.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.