Walk through the two-pass Gradle upgrade procedure and explain why each pass matters.
answer
- Pass 1 = bump distributionUrl (old Gradle)
- middle = build --warning-mode=all, fix deprecations
- Pass 2 = regenerate jar/scripts (new Gradle)
- task runs under the active version
- step minors, don't leap majors
basics
~10 sPass 1: ./gradlew wrapper --gradle-version X bumps distributionUrl. Then build with --warning-mode=all and fix deprecations. Pass 2: re-run ./gradlew wrapper so the new Gradle regenerates gradlew/jar to match itself.
solid answer
~40 sThe recommended upgrade is two passes. **Pass 1** — `./gradlew wrapper --gradle-version 8.7` runs under the *current* Gradle and only rewrites `distributionUrl` in `gradle-wrapper.properties`; the wrapper jar and `gradlew` scripts are still the old version's output. **Middle step** — run your build, ideally `./gradlew build --warning-mode=all`, so the new distribution downloads and surfaces every deprecation warning; fix those before the deprecated behavior is removed in a later major. **Pass 2** — run `./gradlew wrapper` (now executed by the new Gradle) so the new version regenerates `gradle-wrapper.jar`, `gradlew`, and `gradlew.bat` in its own format, making the wrapper self-hosting at X. Commit all wrapper files. The reason two passes matter: the task always runs under whatever Gradle launched it, so only after the new version is active can it emit matching bootstrap files.
code
bash · 4 lines./gradlew wrapper --gradle-version 8.7 # pass 1: bump URL
./gradlew build --warning-mode=all # surface + fix deprecations
./gradlew wrapper --gradle-version 8.7 # pass 2: self-host jar/scripts
git add gradle/wrapper gradlew gradlew.bat && git commit -m 'Upgrade Gradle to 8.7'go deeper
Know there are roughly two runs of the wrapper task and a build in between; details optional.
Articulate all three steps and the reason the task runs under the active version, plus the deprecation middle step.
Tie the procedure to safe incremental majors, CI parity, and when --distribution-type all / checksum verification belong in the flow.
Define the org playbook: cadence, automation, distribution checksum policy, and how teams roll majors without big-bang breakage.
## The core insight: the wrapper task runs under the *active* version Every Gradle task — including the built-in `wrapper` task — executes inside the Gradle runtime that was launched. So when you first run `./gradlew wrapper --gradle-version 8.7`, the **old** Gradle is doing the work. It can happily rewrite a text property (`distributionUrl`), but the `gradle-wrapper.jar` and launcher scripts it (re)generates are still the old version's artifacts. That's why a single invocation leaves you in a half-upgraded state. ## The canonical sequence ```bash # PASS 1 — under old Gradle: bump the distribution pointer ./gradlew wrapper --gradle-version 8.7 # MIDDLE — actually run the new version, surfacing deprecations ./gradlew build --warning-mode=all # PASS 2 — now under NEW Gradle: regenerate jar + scripts to match ./gradlew wrapper --gradle-version 8.7 ``` ### Pass 1 — bump `distributionUrl` Rewrites `gradle/wrapper/gradle-wrapper.properties`: ``` distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip ``` Nothing else is guaranteed to be at 8.7 yet. ### Middle — fix deprecations with `--warning-mode=all` The next build downloads 8.7 and runs your code on it. `--warning-mode=all` forces every deprecation (not just a summary) to print, so you can fix usages that a future major will *remove*. Doing this per-minor keeps each jump small. ### Pass 2 — self-host the wrapper Now `./gradlew` launches 8.7, so the `wrapper` task regenerates `gradle-wrapper.jar`, `gradlew`, and `gradlew.bat` in 8.7's exact format. The wrapper is now fully self-hosting. ## Why not skip to the latest in one leap? Jumping multiple majors at once dumps a wall of breaking changes. Stepping through minors and resolving deprecations as they appear (the `--warning-mode=all` middle step) is far safer. ## Commit everything Commit `gradle-wrapper.properties`, `gradle-wrapper.jar`, `gradlew`, and `gradlew.bat` in one commit so CI and every developer land on the identical version.
- Why can't the first pass produce a wrapper jar that matches the new version?Because the `wrapper` task runs under the currently active (old) Gradle; only after the new version is launched can it emit matching bootstrap files — hence the second pass.
- What does the `--warning-mode=all` middle step buy you?It prints every deprecation warning (not a summary) so you fix soon-to-be-removed behavior incrementally, before a future major removes it outright.
- What should be in the upgrade commit?All four wrapper files: `gradle-wrapper.properties`, `gradle-wrapper.jar`, `gradlew`, `gradlew.bat`, plus any code changes that resolved deprecations.
saying these in an interview costs you the question
- Claiming one run fully upgrades the wrapper jar and scripts.
- Skipping the deprecation-fixing middle step and jumping straight across majors.
- Forgetting to commit the regenerated jar/scripts.