skip to content

What is the difference between invoking ./gradlew and a system-installed gradle, and which should a team prefer?

level: middleimportance: should knowfreq 55%

answer

  1. gradlew = pinned/project Gradle
  2. gradle = machine Gradle
  3. prefer gradlew everywhere
  4. system gradle only to bootstrap wrapper
  5. IDE: use Gradle from wrapper

basics

~10 s

./gradlew runs the project's pinned Gradle via the committed wrapper; system gradle runs whatever version you installed globally. Teams should prefer ./gradlew for consistency and reproducibility.

solid answer

~40 s

`./gradlew` (or `gradlew.bat` on Windows) executes the **wrapper**: it reads the project's pinned distribution, downloads it if missing, and runs the build with that exact version. A bare `gradle` runs whatever Gradle is on the machine's `PATH`, which varies per developer and may not match the project. Teams should standardize on `./gradlew` everywhere — local development, scripts, CI, and documentation — because it guarantees everyone uses the same, project-defined Gradle without manual installation. The system `gradle` is mainly useful for the one-time `gradle wrapper` bootstrap on a brand-new project that has no wrapper yet, or for quick experiments. Mixing the two invites version-drift bugs, so the convention is: if the wrapper exists, always go through it.

code

bash · 6 lines
bash
# Always:
./gradlew test

# Compare reported versions:
./gradlew --version   # the pinned, project version
gradle --version      # whatever is installed system-wide

go deeper

for a junior

Know that ./gradlew is the project's Gradle and you should use it instead of a global gradle.

for a middle

Explain the project-vs-machine version distinction and the always-use-the-wrapper convention.

for a senior

Call out the few legitimate uses of system gradle and how to keep CI/IDE pinned to the wrapper.

for a principal

Standardize the convention across the org's repos and CI images so the wrapper is never bypassed accidentally.

## Two ways to launch Gradle - **`./gradlew <task>`** — the *wrapper* launcher. The script invokes the wrapper bootstrap, which resolves the project's pinned Gradle distribution (downloading and caching it on first use) and then runs your task with that version. - **`gradle <task>`** — a *system* Gradle binary on the user's `PATH`, installed via SDKMAN, Homebrew, a package manager, or a manual download. Its version is whatever that machine has. ## Why the distinction matters The wrapper makes the Gradle version a property of the **project**; the system binary makes it a property of the **machine**. Those two can disagree, and Gradle's behavior changes across versions (deprecations become errors, defaults shift). Building with the wrong version produces inconsistent or broken results. ## The team convention Use `./gradlew` **everywhere**: - Local builds and IDE run configurations. - CI pipeline steps. - Onboarding docs and helper scripts. This yields reproducible builds from a JDK-only clone and removes 'which Gradle?' from the troubleshooting checklist. ## When is system `gradle` legitimately useful? 1. **Bootstrapping a new project** that has no wrapper yet — you need *some* Gradle to generate the initial wrapper files. 2. **Throwaway experiments** outside any project. Once a wrapper exists, prefer it unconditionally. ```bash # Preferred everywhere: ./gradlew clean build # Only acceptable on a project with no wrapper yet: gradle wrapper # generates the wrapper files, then switch to ./gradlew ``` ## Practical guardrails - IDEs (IntelliJ) default to 'use Gradle from: gradle-wrapper' — keep that. - CI images may ship a system gradle; explicitly call `./gradlew` so it is never used by accident.

  • When is it acceptable to use a system-installed gradle?
    Mainly to bootstrap the wrapper on a brand-new project that has none yet (gradle wrapper), or for quick throwaway experiments. Once a wrapper exists, always use ./gradlew.
  • How should CI invoke the build to avoid the wrong Gradle?
    Explicitly call ./gradlew so it uses the project's pinned distribution, even if the CI image happens to ship a different system gradle.

saying these in an interview costs you the question

  • Recommending system gradle for day-to-day builds when a wrapper exists.
  • Assuming gradle and ./gradlew are interchangeable.
  • Letting CI fall back to a system gradle implicitly.

context