What is the difference between providers.gradleProperty(name) and project.findProperty(name) / project.property(name)?
answer
- gradleProperty: lazy String Provider, tracked
- sources: gradle.properties, -P, ORG_GRADLE_PROJECT_
- findProperty/property: eager, includes ext
- findProperty null vs property throws
- map to type, orElse for default
basics
~10 sgradleProperty returns a lazy, config-cache-tracked Provider<String> from gradle.properties and -P flags. findProperty/property read eagerly and also see project ext/extra properties, not just Gradle properties.
solid answer
~30 s`providers.gradleProperty("x")` returns a lazy `Provider<String>` resolved from **Gradle properties** — `gradle.properties` files, `-Px=...`, and `ORG_GRADLE_PROJECT_x` env vars — and is tracked as a configuration-cache input. It does **not** see `ext`/extra project properties. `project.findProperty("x")` and `project.property("x")` read **eagerly** and resolve from a broader namespace including project extra properties; `findProperty` returns `null` if absent while `property` throws `MissingPropertyException`. For modern, config-cache-safe authoring you prefer `gradleProperty`, chaining `.orElse(...)` for defaults and `.map { it.toBoolean() }` for typing, rather than the eager `findProperty`. A common pattern is `providers.gradleProperty("release").map { it.toBoolean() }.orElse(false)`.
code
kotlin · 6 linesval isRelease = providers.gradleProperty("release")
.map { it.toBoolean() }
.orElse(false)
// Eager, broader namespace, returns Any?/null
val legacy = project.findProperty("release")go deeper
Know gradleProperty reads gradle.properties/-P and returns a Provider; findProperty reads eagerly.
Contrast namespaces (ext inclusion), null-vs-throw, and the map/orElse pattern.
Justify gradleProperty for config-cache correctness and explain ORG_GRADLE_PROJECT_ mapping.
Set conventions: gradleProperty + typed providers for all build configuration toggles to keep inputs tracked.
## Two different lookups Though they sound similar, these read from overlapping-but-different namespaces with different evaluation semantics. ### providers.gradleProperty(name) - Source: **Gradle properties** only — `gradle.properties` (project and home), `-Pname=value` CLI, and `ORG_GRADLE_PROJECT_name` environment variables. - Returns `Provider<String>` — **lazy**, resolved on query. - **Tracked** as a configuration-cache input. - Does *not* include `ext`/extra properties set programmatically in a script. ### project.findProperty / project.property - Source: a **broader** resolution that also includes project **extra (ext) properties** and other dynamic project properties. - **Eager** — returns `Any?` (or throws) at the moment you call it. - `findProperty` → `null` if missing; `property` → throws `MissingPropertyException` if missing. - Not inherently config-cache friendly when used to branch configuration on external input. ## Why prefer gradleProperty Laziness + input tracking, exactly as with `environmentVariable`. It composes cleanly: ```kotlin val isRelease: Provider<Boolean> = providers.gradleProperty("release") .map { it.toBoolean() } .orElse(false) val repoUrl: Provider<String> = providers.gradleProperty("repoUrl") .orElse("https://repo.internal/maven") ``` No value is forced until queried, and changing the property invalidates the configuration cache correctly. ## When findProperty still appears Reading a programmatically-set `ext` value, or quick eager script logic where the configuration cache is not a concern. But for plugin authoring and anything feeding task inputs, reach for `gradleProperty`. ## Gotcha `gradleProperty` always yields a `String` provider — you must convert types yourself (`.map { it.toInt() }`). `findProperty` returns `Any?` and may already be a non-String for `ext` values.
- Which environment variable form feeds a Gradle property named buildNumber?ORG_GRADLE_PROJECT_buildNumber=... — Gradle maps that env var onto the gradleProperty lookup.
- Why doesn't providers.gradleProperty see an ext property you set in build.gradle?gradleProperty only resolves true Gradle properties (files/-P/env). ext/extra properties live in the project's extra-properties extension, which findProperty reads.
saying these in an interview costs you the question
- Saying gradleProperty reads ext/extra properties
- Claiming findProperty is lazy/config-cache tracked
- Forgetting gradleProperty always returns a String (needs map for typing)