skip to content

gradle.properties Precedence

Which gradle.properties wins among the project root, GRADLE_USER_HOME, and the command line, and where secrets belong. Asked because putting a token in the project file is a classic leak.

on this pageshow

questions

5

Where can a gradle.properties file live, and what is each location used for?

level: juniorimportance: must knowfreq 60%

answer

  1. project root = committed/shared
  2. GRADLE_USER_HOME (~/.gradle) = per-machine/secret
  3. subproject + install dir rarely used
  4. all feed one property namespace
  5. next to settings.gradle

basics

~10 s

Two main spots: the project root (<project>/gradle.properties), checked into the repo for shared settings, and GRADLE_USER_HOME (~/.gradle/gradle.properties), a per-developer/machine file for local or secret values.

solid answer

~40 s

Gradle reads `gradle.properties` from a few locations. The **project-root** file (next to `settings.gradle`) is committed to version control and holds settings everyone on the team should share — build flags, dependency versions, feature toggles. The **`GRADLE_USER_HOME`** file (defaults to `~/.gradle/gradle.properties`) is per-machine and *not* in the repo, so it's the right place for credentials and developer-specific overrides. There is also a subproject-level `gradle.properties` in a child module's directory, but its values apply only to the root project's properties view in older docs — in practice the root and user-home files are the ones that matter. Each location feeds the same project-property namespace; differences appear only when the same key is defined in more than one place, which is where precedence rules come in.

code

properties · 7 lines
properties
# <project-root>/gradle.properties (in Git, shared)
org.gradle.caching=true
springBootVersion=3.3.0

# ~/.gradle/gradle.properties (per developer, not in Git)
myRepoUsername=alice
myRepoPassword=s3cr3t

go deeper

for a junior

Name the two key files: committed project-root file vs per-machine ~/.gradle file, and what each is for.

for a middle

Add that GRADLE_USER_HOME defaults to ~/.gradle, that subproject/install files exist but are rarely used, and that all feed one property namespace.

for a senior

Frame the split as a security/reproducibility boundary: shared deterministic config in Git vs secret/local config in user home.

for a principal

Discuss org policy: standardizing GRADLE_USER_HOME on CI, secret injection patterns, and preventing credential sprawl across many repos.

## What `gradle.properties` is `gradle.properties` is a plain Java-properties file (`key=value` lines) that seeds **Gradle project properties** and Gradle's own `org.gradle.*` build flags *before* any build script runs. It is the static, file-based way to configure a build, as opposed to passing values on the command line. ## The locations Gradle reads Gradle looks for `gradle.properties` in several places: 1. **`GRADLE_USER_HOME/gradle.properties`** — `GRADLE_USER_HOME` defaults to `~/.gradle`. This file is **per machine / per developer** and is *never* committed (it lives outside the repo). It is the correct home for secrets (signing keys, repository credentials) and personal overrides (e.g. bumping `org.gradle.jvmargs` on a big workstation). 2. **Project-root `gradle.properties`** — the file next to `settings.gradle(.kts)` at the top of the build. This **is committed** and carries settings the whole team should share: pinned versions, `org.gradle.caching=true`, `org.gradle.parallel=true`, custom flags consumed via `providers.gradleProperty(...)`. 3. **Subproject directory `gradle.properties`** — historically present, but in a modern multi-project build the root file is the canonical place; subproject files are rarely used and easy to misread. 4. **Installation directory** — `gradle.properties` in the Gradle distribution's own folder; almost never used and not portable, so avoid relying on it. ## Why the split matters The two files map cleanly onto two audiences: - *Shared, reproducible, safe-to-publish* → **project root** (in Git). - *Local, secret, machine-specific* → **`GRADLE_USER_HOME`** (out of Git). Keeping that separation is what prevents credentials from leaking into version control while still letting the build read them by the same property name. ```properties # <project>/gradle.properties (committed) org.gradle.caching=true org.gradle.parallel=true springBootVersion=3.3.0 # ~/.gradle/gradle.properties (per-developer, NOT committed) myRepoUsername=alice myRepoPassword=s3cr3t ``` Both files populate the same property namespace; a build script reading `springBootVersion` or `myRepoPassword` doesn't know or care which file it came from.

  • Where would you put a CI-only credential so it never lands in the repo?
    In `GRADLE_USER_HOME/gradle.properties` on the CI agent (or inject it as an `ORG_GRADLE_PROJECT_*` env var), not the committed root file.
  • Does GRADLE_USER_HOME have to be ~/.gradle?
    No — it's the default, but you can point `GRADLE_USER_HOME` at any directory via the env var, which CI often does to control caching and isolation.

saying these in an interview costs you the question

  • Claiming credentials belong in the project-root file that's committed to Git.
  • Thinking there is only one possible location for gradle.properties.

context

open as a page

If the same property is defined in the project-root gradle.properties, in GRADLE_USER_HOME, and on the command line, which value wins?

level: middleimportance: must knowfreq 65%

basics

~10 s

Highest to lowest: command line / system-property / env-var overrides beat GRADLE_USER_HOME/gradle.properties, which beats the project-root gradle.properties. So the command line wins, and user-home beats the committed project file.

open as a page

Where should build secrets (like repository or signing credentials) live in the gradle.properties hierarchy, and why?

level: middleimportance: must knowfreq 55%

basics

~10 s

Put secrets in GRADLE_USER_HOME/gradle.properties (~/.gradle), which is outside the repo and per-machine. Never put them in the committed project-root gradle.properties. On CI, inject them as env vars instead.

open as a page

A property has an unexpected value at build time and you suspect a gradle.properties conflict. How do you reason about and confirm which source supplied it?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Walk the precedence ladder top-down: check command-line/env overrides, then ~/.gradle/gradle.properties, then the project-root file — the highest source that defines the key wins. Print the resolved value in a task to confirm.

open as a page

Across many repositories, how would you let developers override shared defaults locally while keeping team-wide settings authoritative, given gradle.properties precedence?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

Keep shared defaults in each committed project-root file, let ~/.gradle provide per-developer overrides (it outranks the repo file by design), and enforce truly non-negotiable settings at invocation time in CI so no local file can change them.

open as a page