A teammate committed org.gradle.configuration-cache=true, but your local build behaves differently from CI. How do the command-line flag, project property, and user property interact, and how would you control activation per environment?
answer
- flag > -D system property > project gradle.properties > ~/.gradle
- user gradle.properties overrides project file
- CI may pass --no-configuration-cache
- be explicit in CI scripts
- --info reveals whether it's on
basics
~10 sCommand-line flags override gradle.properties for that run. Properties resolve from project gradle.properties, then ~/.gradle/gradle.properties, then -D/-P overrides. Control per-environment by setting the flag in CI scripts and the property (or its override) locally.
solid answer
~40 sActivation is resolved from several layers with a clear precedence. The **command-line flag** (`--configuration-cache` / `--no-configuration-cache`) always wins for that invocation. Absent a flag, the **property** `org.gradle.configuration-cache` is read; it can come from the **project** `gradle.properties` (committed, team-wide), the **user** `~/.gradle/gradle.properties` (per-developer), an environment variable `ORG_GRADLE_PROJECT_...`, or a `-Dorg.gradle.configuration-cache=...` system property override. Divergence between local and CI usually means one layer differs — e.g. CI passes `--no-configuration-cache` in its invocation, or your `~/.gradle/gradle.properties` overrides the committed value. To control activation per environment, prefer being explicit: enable via the property in the committed `gradle.properties` for everyone, and pass the flag explicitly in CI scripts so the behavior is visible in the pipeline rather than implicit.
code
bash · 9 lines# explicit per-environment control
# CI job that wants it on:
./gradlew build --configuration-cache
# a job that must disable it (incompatible plugin):
./gradlew specialTask --no-configuration-cache
# diagnose which layer won:
./gradlew help --info | grep -i 'configuration cache'go deeper
Know the flag overrides the property; deeper precedence is beyond junior scope.
Lay out the layers (flag, project file, user file) and that the user file overrides the project file.
Diagnose local-vs-CI divergence by inspecting each layer and recommend explicit flags in CI for auditability.
Define an org policy: committed default plus explicit per-pipeline flags, and guard against per-developer overrides silently changing build semantics across the fleet.
## The resolution layers Gradle determines whether the configuration cache is on by consulting, in order of precedence: 1. **Command-line flag** for the invocation: `--configuration-cache` forces on, `--no-configuration-cache` forces off. Highest priority. 2. **System-property override** on the command line: `-Dorg.gradle.configuration-cache=true`. 3. **Project `gradle.properties`** (checked into the repo root) — the team-wide default. 4. **User `~/.gradle/gradle.properties`** — per-developer, overrides the project file for that user. Because the user file overrides the project file, a developer who set `org.gradle.configuration-cache=false` in `~/.gradle/gradle.properties` will *not* get the cache even though the repo committed `true` — a classic source of 'works on CI, not on my machine' confusion (or the reverse). ## Diagnosing local-vs-CI divergence - Check the **CI invocation**: does the pipeline pass `--no-configuration-cache` or a different `-D` override? - Check **`~/.gradle/gradle.properties`** for a conflicting value. - Add `--info` and look for whether Gradle prints the store/reuse messages at all; if it never mentions the configuration cache, it is off in that environment. ## Making activation explicit and portable ```bash # CI: be explicit so the pipeline log shows intent ./gradlew build --configuration-cache ``` ``` # committed gradle.properties: team default org.gradle.configuration-cache=true ``` For environments where you must disable it (e.g. a job using an incompatible plugin), pass `--no-configuration-cache` in *that* job's invocation rather than mutating shared properties. ## Why explicitness matters Implicit property layering is convenient but invisible in logs. Passing the flag in CI scripts makes the setting auditable and removes ambiguity about which layer won — important when a build's behavior (skipping configuration) materially affects correctness and timing.
- Project gradle.properties says true, but your ~/.gradle/gradle.properties says false, and you pass no flag. Is the cache on?No — the user-level ~/.gradle/gradle.properties overrides the committed project value, so the cache is off for you until you remove that line or pass --configuration-cache.
- How would you make the activation visible and auditable in CI?Pass the flag explicitly in the pipeline invocation (e.g. --configuration-cache) so the build log records the intent, rather than relying on an implicit property layer that is invisible in the log.
saying these in an interview costs you the question
- Claiming the project gradle.properties always wins over the user file — it's the opposite.
- Saying the property overrides the command-line flag — the flag has higher precedence.
- Treating local-vs-CI divergence as a Gradle bug rather than a layered-config difference.