How do you control which Gradle distribution a GradleConnector uses, and when would you choose each option?
answer
- useBuildDistribution honors wrapper
- useGradleVersion pins a version
- useInstallation local dir, no download
- useDistribution from a URI mirror
- default rarely what you want
basics
~10 sOn the connector: useGradleVersion("8.7") downloads a version, useInstallation(dir) uses a local install, useDistribution(uri) uses a URL, and useBuildDistribution() honors the project's wrapper. Pick based on reproducibility needs.
solid answer
~50 sBefore `connect()`, the `GradleConnector` lets you pick the Gradle distribution that will run the build: - **useBuildDistribution()** — use whatever the project's Gradle **wrapper** declares (`gradle-wrapper.properties`). Best default for reproducibility: the build runs with the version the project was authored for. - **useGradleVersion("8.7")** — download and use an explicit version. Good when you must pin a version independent of the project. - **useInstallation(File gradleHome)** — use an already-installed Gradle. Avoids downloads; useful offline or in controlled CI images. - **useDistribution(URI)** — fetch a distribution from a specific URL (e.g. an internal mirror). If you set none, the connector picks a default, which is usually not what you want for a real tool. IDEs typically honor the wrapper (`useBuildDistribution()`) so the import matches the command-line build. For a tool that must guarantee a known engine version regardless of the project, pin with `useGradleVersion` or `useInstallation`.
code
java · 9 linesProjectConnection connection = GradleConnector.newConnector()
.forProjectDirectory(projectDir)
.useBuildDistribution() // run with the project's wrapper version
.connect();
// alternatives:
// .useGradleVersion("8.7")
// .useInstallation(new File("/opt/gradle-8.7"))
// .useDistribution(URI.create("https://mirror.example.com/gradle-8.7-bin.zip"))go deeper
Name at least useGradleVersion and that you can choose the distribution before connect().
List the four options and when to use each, especially useBuildDistribution honoring the wrapper.
Discuss reproducibility, offline/mirror constraints, and client-vs-target version compatibility.
Define an org policy: IDEs honor the wrapper; tooling pins versions via vetted local installs or a mirror.
## The problem The Tooling API runs a build, but **which Gradle** runs it? The connector exposes mutually-relevant configuration to choose the distribution. Getting this right matters because plugin compatibility, DSL features, and build behavior depend on the Gradle version. ## The options on GradleConnector ### useBuildDistribution() Honors the project's **wrapper**. Gradle reads `gradle/wrapper/gradle-wrapper.properties` to find the declared `distributionUrl` and uses exactly that version. This is the most reproducible choice: the embedded build matches `./gradlew` from the command line. IDEs generally default to this. ### useGradleVersion(String version) Downloads (and caches) the named version, e.g. `"8.7"`. Use when your tool must pin a Gradle version on its own terms, independent of whatever the project declares. ### useInstallation(File gradleHome) Points at an existing local installation directory. No download. Ideal offline, in air-gapped CI, or when the image already ships a vetted Gradle. ### useDistribution(URI location) Fetches the distribution zip from a URL — e.g. an internal artifact mirror so you do not hit services.gradle.org. ## Choosing | Goal | Choose | |------|--------| | Match the project's own build exactly | useBuildDistribution() | | Pin a known version regardless of project | useGradleVersion | | No network / use vetted local install | useInstallation | | Corporate mirror | useDistribution(URI) | ## Example ```java ProjectConnection connection = GradleConnector.newConnector() .forProjectDirectory(projectDir) .useBuildDistribution() // honor the wrapper .connect(); ``` ## Gotchas - These methods are mutually exclusive in intent; the last one you call wins. - `useBuildDistribution()` requires the project to actually have a wrapper configured; otherwise it falls back / errors depending on version. - Version skew between your Tooling API client and the target Gradle is constrained — very old clients cannot drive very new Gradle and vice-versa. Honoring the wrapper sidesteps surprises.
- Which option makes the embedded build match running ./gradlew on the command line?useBuildDistribution() — it honors the project's gradle-wrapper.properties, so the same version runs.
- How would you avoid any network download of Gradle?useInstallation(File) pointing at a Gradle already installed in the environment.
saying these in an interview costs you the question
- Assuming the Tooling API always uses the project's wrapper by default
- Thinking any Tooling API client can drive any Gradle version regardless of skew