skip to content

How do you control which Gradle distribution a GradleConnector uses, and when would you choose each option?

level: middleimportance: should knowfreq 35%

answer

  1. useBuildDistribution honors wrapper
  2. useGradleVersion pins a version
  3. useInstallation local dir, no download
  4. useDistribution from a URI mirror
  5. default rarely what you want

basics

~10 s

On 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 s

Before `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 lines
java
ProjectConnection 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

for a junior

Name at least useGradleVersion and that you can choose the distribution before connect().

for a middle

List the four options and when to use each, especially useBuildDistribution honoring the wrapper.

for a senior

Discuss reproducibility, offline/mirror constraints, and client-vs-target version compatibility.

for a principal

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

context