skip to content

What does the `application` plugin add, and how do you configure it to run a Java program?

level: juniorimportance: should knowfreq 70%

answer

  1. applies java + distribution
  2. run task launches mainClass
  3. application { mainClass.set(...) }
  4. installDist / distZip / distTar
  5. generates bin start scripts

basics

~10 s

The application plugin applies java, adds a run task that launches your main class, an application {} extension where you set mainClass, and distZip/distTar/installDist tasks that package the app with start scripts.

solid answer

~40 s

The `application` plugin builds on `java` to turn a module into a runnable, distributable program. It adds the **`application {}` extension** where you set `mainClass` (the fully-qualified class with `main`), optional `applicationDefaultJvmArgs`, and `applicationName`. It registers a **`run`** task that executes that main class against the project's runtime classpath, so `./gradlew run` launches the app. It also adds packaging tasks — `installDist` (an unpacked runnable layout under `build/install`), `distZip`/`distTar` (archives), and generates cross-platform **start scripts** (`bin/<name>` and `bin/<name>.bat`). It applies the `distribution` plugin to do the bundling. Use it for CLIs and services where you want `gradle run` during development and a self-contained distribution for deployment.

code

kotlin · 10 lines
kotlin
plugins {
    application
}

application {
    mainClass.set("com.example.Main")
    applicationDefaultJvmArgs = listOf("-Xmx256m")
}

// ./gradlew run --args="--verbose input.txt"

go deeper

for a junior

Know the run task, the mainClass setting, and that it produces a runnable distribution.

for a middle

Explain the installDist/distZip outputs, start scripts, and how --args and default JVM args flow through.

for a senior

Contrast plain application distributions with fat-jar plugins (Shadow) or bootJar, and when each fits deployment needs.

for a principal

Discuss standardizing run/packaging conventions across services and how distribution layout interacts with containerization.

## Purpose The `application` plugin makes a JVM module **executable and distributable**. It applies the `java` plugin (so you get source sets, `compileJava`, `jar`, etc.) and layers on running + packaging. ## The `application {}` extension ```kotlin plugins { application } application { mainClass.set("com.example.Main") // required: FQN with main() applicationName = "myapp" // start-script base name applicationDefaultJvmArgs = listOf("-Xmx256m") } ``` `mainClass` is a `Property<String>` (lazy), so you set it with `.set(...)`. It's the entry point the `run` task and the start scripts invoke. ## Tasks it adds | Task | What it does | |------|--------------| | `run` | runs `mainClass` against the `main` runtime classpath | | `startScripts` | generates `bin/<name>` and `bin/<name>.bat` | | `installDist` | assembles a runnable image under `build/install/<name>` | | `distZip` / `distTar` | package that image as an archive | ## How a distribution is shaped The plugin applies the `distribution` plugin. The generated layout is: ``` <name>/ bin/<name> # *nix launcher bin/<name>.bat # Windows launcher lib/*.jar # your jar + runtime deps ``` The launcher sets the classpath from `lib/` and invokes `mainClass`. This is a portable bundle you can ship without Gradle. ## Passing arguments `./gradlew run --args="--verbose input.txt"` forwards arguments to your `main(String[] args)`. ## When to use it Reach for `application` for command-line tools, batch jobs, or services you launch with a `main`. For Spring Boot apps you'd typically use the Spring Boot plugin's `bootRun`/`bootJar` instead, though Boot still relies on a main class concept.

  • How do you pass command-line arguments to the `run` task?
    Use `./gradlew run --args="arg1 arg2"`; Gradle forwards them to your `main(String[])`.
  • What's the difference between `installDist` and `distZip`?
    `installDist` creates an unpacked runnable directory under `build/install`; `distZip` (and `distTar`) package that same layout into a distributable archive.

saying these in an interview costs you the question

  • Setting `mainClass` with `=` on the property instead of `.set(...)` in Kotlin DSL.
  • Claiming the `application` plugin alone produces a fat/uber jar — it bundles deps as separate jars under `lib/`, not a single executable jar.
  • Forgetting it applies `java` and thinking you must apply both manually.

context