Your team wants to upgrade Gradle and guarantee everyone (devs and CI) uses the new version. Walk through how gradle-wrapper.properties makes that reproducible and the right way to perform the bump.
answer
- distributionUrl = committed version fact
- wrapper ignores PATH Gradle
- run wrapper task twice
- commit properties + jar + gradlew(.bat)
- verify with --version
basics
~20 sBecause distributionUrl in gradle-wrapper.properties pins the exact Gradle version and the wrapper ignores any local Gradle, committing the bumped properties file makes everyone use the same version. Bump it with ./gradlew wrapper --gradle-version X, run it twice, then commit.
solid answer
~40 sThe reproducibility guarantee comes from `distributionUrl` in `gradle-wrapper.properties`: it encodes the exact Gradle version, and `./gradlew` downloads and runs **only** that version, ignoring any system-installed Gradle. So whoever checks out the repo gets the pinned version — devs and CI alike. The correct upgrade is the **two-pass wrapper task**, not hand-editing: run `./gradlew wrapper --gradle-version 8.7 --distribution-type bin` once to rewrite `distributionUrl` (and the wrapper jar/scripts), then run `./gradlew wrapper` **again** so the wrapper that performs the second run is itself the new version, ensuring the jar matches. Commit the updated `gradle-wrapper.properties`, `gradle-wrapper.jar`, `gradlew`, and `gradlew.bat` together. After that, every clone is reproducible because the version lives in a committed file, not on anyone's machine. Verify with `./gradlew --version`.
code
bash · 4 lines./gradlew wrapper --gradle-version 8.7 --distribution-type bin
./gradlew wrapper # second pass with the new wrapper
./gradlew --version # confirm 8.7
git add gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.jar gradlew gradlew.batgo deeper
Know that distributionUrl pins the version and committing it makes the team consistent.
Use the wrapper task to bump and remember to commit the properties plus wrapper files; verify with --version.
Explain the two-pass upgrade, why the wrapper jar must be regenerated by the new version, and that the committed file is the single source of truth.
Govern version pins across many repos: internal distribution mirrors, automated bump bots, CI gates asserting --version, and rollout/upgrade strategy.
## Why the wrapper gives reproducibility The contract is simple: the version is a **committed fact**, not an environment fact. `gradle/wrapper/gradle-wrapper.properties` holds: ```properties distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip ``` The version is parsed from that filename. `./gradlew` resolves it, downloads (or reuses the cached) distribution under `~/.gradle/wrapper/dists/`, and executes **that** Gradle — it never falls back to a `gradle` on the PATH. Therefore, once the properties file is committed, a fresh clone on a laptop, a colleague's machine, and the CI runner all run byte-for-byte the same Gradle. This is the foundation of reproducible builds at the build-tool layer. ## The right way to upgrade — two passes Hand-editing only `distributionUrl` is risky: it leaves the wrapper **jar/scripts** at the old version, and they can drift. The supported path is the built-in `wrapper` task: ```bash # Pass 1: rewrite distributionUrl + wrapper files using the CURRENT Gradle ./gradlew wrapper --gradle-version 8.7 --distribution-type bin # Pass 2: run again so the NEW wrapper regenerates itself consistently ./gradlew wrapper ``` Why twice? Pass 1 executes under the *old* Gradle and updates the properties; pass 2 executes under the *new* Gradle so the generated wrapper jar and scripts are produced by the version you're standardizing on. After that: 1. `./gradlew --version` to confirm. 2. Commit **all four** changed files together: `gradle-wrapper.properties`, `gradle-wrapper.jar`, `gradlew`, `gradlew.bat`. ## Useful flags - `--distribution-type bin|all` — pick the variant (lean vs IDE docs). - `--gradle-version 8.7` or `--gradle-version latest`. - `--network-timeout <ms>` — for slow mirrors during the download. ## Org-level considerations Across many repos, the pin becomes a governance concern: you may mirror distributions internally (rewriting the host in `distributionUrl`), automate bumps with a bot, and gate on CI running `./gradlew --version`. The key insight to articulate in an interview: **the wrapper properties file is the single source of truth for the version, so the upgrade is just a committed change to that file plus regenerated wrapper artifacts.**
- Why run the wrapper task twice instead of once?The first pass runs under the old Gradle and rewrites the properties; the second pass runs under the new Gradle so the regenerated wrapper jar/scripts match the version you're standardizing on.
- Why is committing the wrapper files (not just installing Gradle on CI) the reproducible approach?Because the version is encoded in the committed distributionUrl and the wrapper ignores system Gradle, every checkout runs the identical version with no per-machine setup.
- What single command verifies the active wrapper version?./gradlew --version, which prints the Gradle version the wrapper resolved from distributionUrl.
saying these in an interview costs you the question
- Recommending team members install matching Gradle manually instead of relying on the committed wrapper.
- Editing only distributionUrl and leaving the wrapper jar/scripts stale.
- Forgetting to commit the regenerated wrapper jar and gradlew scripts alongside the properties file.