What does the foojay-resolver-convention Settings plugin do, and why is it commonly applied?
answer
- Java toolchain auto-provisioning
- no download repo by default
- foojay Disco API resolver
- toolchainManagement on Settings
- JavaToolchainResolver API
basics
~10 sIt registers a Java toolchain resolver (the foojay Disco API) so Gradle can auto-download a matching JDK when a build requests a toolchain version that isn't installed locally.
solid answer
~40 s`org.gradle.toolchains.foojay-resolver-convention` is a Settings plugin applied in `settings.gradle.kts`. Java toolchain *auto-provisioning* lets a build declare `languageVersion = JavaLanguageVersion.of(21)` and have Gradle download a matching JDK if none is installed — but Gradle ships with **no** download source by default. This plugin registers the **foojay Disco API** as a toolchain repository via the toolchain-resolver API, so the convention version wires it up automatically. It must be a Settings plugin because toolchain resolvers are configured on `settings.toolchainManagement`, which only exists in the settings phase. Without it (or another resolver), requesting an uninstalled toolchain fails with an error telling you no toolchain repositories are configured.
code
kotlin · 11 lines// settings.gradle.kts
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
// build.gradle.kts (now an uninstalled JDK 21 can be auto-downloaded)
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}go deeper
Know it lets Gradle auto-download a JDK matching the requested toolchain version.
Explain that Gradle has no default download source, and this plugin registers the foojay Disco API as a resolver via toolchainManagement.
Discuss the JavaToolchainResolver API, the -convention auto-registration, and when auto-provisioning is bypassed (already-installed JDKs).
Weigh foojay vs an internal mirror/resolver for reproducibility and supply-chain control, and policy for disabling auto-download in CI.
## The problem it solves: Java toolchains Gradle's **Java toolchain** feature lets you decouple the JDK that *runs* Gradle from the JDK used to *compile and test* your code. You declare: ```kotlin java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } ``` Gradle then locates a JDK 21 on the machine. If one isn't found, **auto-provisioning** can download it — but Gradle needs to know *where* to download JDKs from. Out of the box, Gradle defines **no** download repositories, so auto-provisioning fails. ## What foojay-resolver-convention does The foojay plugin plugs into Gradle's **Java Toolchain Resolver API**. A resolver implements `JavaToolchainResolver` and answers "given this version/vendor request, what's a download URL?" The foojay plugin's resolver queries the **foojay Disco API** (a community service that indexes many JDK distributions — Temurin, Zulu, Corretto, etc.) and returns a download link. The `-convention` variant additionally registers itself into `toolchainManagement.jvm.javaRepositories` automatically, so you only need to apply the plugin — no manual repository wiring. ## Why it must be a Settings plugin Toolchain download repositories are configured on the **`Settings`** object, under `toolchainManagement {}`. That block exists only during initialization. A manual setup looks like: ```kotlin // settings.gradle.kts plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } ``` Under the hood the convention plugin does the equivalent of: ```kotlin toolchainManagement { jvm { javaRepositories { repository("foojay") { resolverClass = FoojayToolchainResolver::class.java } } } } ``` Because `toolchainManagement` lives on `Settings`, this can only happen in the settings phase — hence a Settings plugin. ## Practical notes - It does not *force* downloads: Gradle first checks installed JDKs and `org.gradle.java.installations.*` properties; only on a miss does it call a resolver. - Auto-provisioning can be disabled with `-Dorg.gradle.java.installations.auto-download=false`. - Newer Gradle starters scaffold this plugin by default, which is why you see it in nearly every modern multi-project build.
- What happens if you request an uninstalled toolchain and no resolver plugin is applied?The build fails with an error saying no toolchain download repositories are defined and the requested JDK couldn't be located or provisioned.
- Why can't this be done from a Project plugin in build.gradle.kts?Toolchain repositories are configured on `settings.toolchainManagement`, which only exists during initialization, so the resolver must be registered from the settings phase.
saying these in an interview costs you the question
- Saying Gradle downloads JDKs out of the box without any resolver — it doesn't.
- Confusing toolchain resolution (downloading JDKs) with dependency resolution.