skip to content

Walk through the two-pass Gradle upgrade procedure and explain why each pass matters.

level: middleimportance: must knowfreq 55%

answer

  1. Pass 1 = bump distributionUrl (old Gradle)
  2. middle = build --warning-mode=all, fix deprecations
  3. Pass 2 = regenerate jar/scripts (new Gradle)
  4. task runs under the active version
  5. step minors, don't leap majors

basics

~10 s

Pass 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 s

The 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
bash
./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

for a junior

Know there are roughly two runs of the wrapper task and a build in between; details optional.

for a middle

Articulate all three steps and the reason the task runs under the active version, plus the deprecation middle step.

for a senior

Tie the procedure to safe incremental majors, CI parity, and when --distribution-type all / checksum verification belong in the flow.

for a principal

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.

context