skip to content

When would you use installDist for local verification, and how does it relate to the run task and the archive tasks?

level: seniorimportance: should knowfreq 30%

answer

  1. run = in-place, hides packaging bugs
  2. installDist = real artifact, unpacked
  3. distZip/distTar = ship it
  4. CI: launch bin/<name> as smoke test
  5. fidelity vs speed sweet spot

basics

~20 s

installDist materializes the exact unpacked distribution (bin/ + lib/) on disk so you can launch it via its real start script — closer to production than the run task, and faster to iterate than building and extracting distZip/distTar.

solid answer

~40 s

The Application plugin gives three ways to exercise your app. `run` executes the app **in-place** using Gradle's own classpath/JVM — convenient but it bypasses the generated launcher and packaged layout, so it can hide issues (missing resources, wrong mainClass in the script, classpath quirks). `installDist` produces the **real** unpacked image (`build/install/<name>/` with `bin/` + `lib/`) and you run it through the actual start script — this validates the exact artifact users get, without the cost of zipping/unzipping. `distZip`/`distTar` archive that same image for distribution. So the practical pipeline is: iterate with `run` for speed, **smoke-test with `installDist` to verify the packaged form** (scripts, classpath, JVM args, entry point), then produce `distZip`/`distTar` for release. In CI, running `./build/install/<name>/bin/<name>` is a strong end-to-end check that the distribution actually launches.

code

bash · 7 lines
bash
# dev loop
./gradlew run --args='--help'
# verify the real packaged form
./gradlew installDist
./build/install/myapp/bin/myapp --version
# ship
./gradlew distZip

go deeper

for a junior

Know installDist produces a runnable folder you can launch via its bin/ script.

for a middle

Contrast run (in-place) vs installDist (real packaged form) vs distZip/distTar (archives).

for a senior

Explain installDist as the fidelity-vs-speed sweet spot and why run can hide packaging bugs; use it as a CI smoke test.

for a principal

Bake an installDist launch smoke-test into the release gate across services so no archive ships without proving the distribution boots.

## Three execution/packaging paths The Application plugin provides: 1. **`run`** — launches the app immediately using Gradle's resolved classpath and toolchain JVM. Fast feedback loop, but it does **not** go through the generated start script and does not assemble `bin/`+`lib/`. It can therefore mask packaging problems. 2. **`installDist`** — builds the **actual unpacked distribution** at `build/install/<applicationName>/` (`bin/` launchers + `lib/` jars). You invoke the real launcher, exercising the same classpath assembly, JVM-options handling, and `mainClass` resolution that an end user gets. 3. **`distZip` / `distTar`** — package that install image into a `.zip` / `.tar` under `build/distributions/` for distribution (sibling topic). ## Why installDist for verification `installDist` sits at the sweet spot for *fidelity vs. speed*: - **Higher fidelity than `run`:** it tests the generated `bin/<name>` script — so it catches a wrong/missing `mainClass`, a resource not actually on the runtime classpath, encoding/JVM-arg issues, or a broken `executableDir` offset. - **Faster than building archives:** no compress/extract round-trip; the files are already on disk ready to launch. ```bash ./gradlew installDist ./build/install/myapp/bin/myapp --selfcheck # exercises the real launcher ``` ## In a CI/release pipeline A robust sequence: 1. Unit/integration tests. 2. `installDist` + run the launcher with a smoke command — proves the *packaged* app boots. 3. `distZip`/`distTar` to produce release archives (their contents are identical to the verified install image). This catches "works under `run` but the distribution won't start" failures **before** you ship an archive. ## Caching / up-to-date behavior All three are normal Gradle tasks with declared inputs/outputs, so they participate in incremental builds and the build cache; re-running `installDist` is cheap when nothing changed. ## Summary mental model - `run` = quick dev loop (not the real artifact). - `installDist` = run the real artifact, unpacked, locally/CI. - `distZip`/`distTar` = ship the real artifact.

  • Why can the run task pass while the distribution fails to launch?
    run uses Gradle's own classpath and skips the generated start script, so a wrong mainClass in the script, a missing runtime resource, or a classpath difference only surfaces when you launch the real installDist image.
  • What's the advantage of installDist over building distZip for a smoke test?
    It avoids the compress/extract round-trip — the runnable files are already on disk — while still exercising the exact bin/ + lib/ layout users receive.

saying these in an interview costs you the question

  • Treating run and installDist as equivalent verification — run bypasses the packaged launcher.
  • Assuming you must build and unzip distZip to test the distribution; installDist gives the same image unpacked.

context