skip to content

How do you configure Gradle's 'application' plugin to launch an executable JVM app, and what is the minimal configuration required?

level: juniorimportance: must knowfreq 70%

answer

  1. apply 'application' → pulls in 'java'
  2. application { mainClass = ... }
  3. mainClass is a Property<String>
  4. registers the 'run' task (JavaExec)
  5. --args passes program args

basics

~10 s

Apply the 'application' plugin and set the entry point: application { mainClass = "com.example.Main" }. Then run ./gradlew run to compile and launch the app's main method.

solid answer

~30 s

Apply `application` (it pulls in the `java` plugin) and configure the `application {}` extension. The one required property is `mainClass` — the fully qualified name of the class with `public static void main`. In modern Gradle (7.5+) `mainClass` is a `Property<String>` you assign with `=`; older syntax used `mainClassName`. Once configured, the plugin adds a `run` task that compiles the code, builds the `runtimeClasspath`, and forks a JVM to execute that main class. You can pass args with `--args`, e.g. `./gradlew run --args="--port 8080"`. The plugin also wires up `installDist`/`distZip` for packaging, but the core developer loop is just `run`.

code

kotlin · 9 lines
kotlin
plugins {
    application
}

application {
    mainClass = "com.example.App"
}

// ./gradlew run --args="--port 8080"

go deeper

for a junior

Know to apply the plugin, set mainClass, and run ./gradlew run.

for a middle

Explain that 'run' is a JavaExec task, that the java plugin is applied transitively, and how --args works.

for a senior

Discuss the lazy Property<String> semantics of mainClass vs the deprecated mainClassName and why a single entry-point source of truth matters.

for a principal

Frame the plugin as the standard contract for runnable JVM services across a multi-module build and how it underpins reproducible launch configs in CI.

## What the application plugin does Gradle's built-in `application` plugin turns a project into a runnable JVM program. It is a thin layer on top of the `java` plugin: applying `application` automatically applies `java`, so you get `compileJava`, `jar`, `test`, the `main`/`test` source sets, and the standard dependency configurations. Its job is to answer one question: *which class is the entry point, and how do I launch it with the right classpath?* ## The application extension The plugin registers an extension object named `application`. Its core property: - **`mainClass`** — a `Property<String>` holding the fully-qualified name of the class containing `public static void main(String[])`. This is the only strictly required setting. Because `mainClass` is a lazy `Property`, you assign it with `=` (Kotlin DSL) and it is only resolved when actually needed. The older flat property `mainClassName` (a plain `String`) is deprecated in favour of `mainClass`. ## The run task Configuring the extension causes the plugin to register a `JavaExec` task named **`run`**. When you execute `./gradlew run`, Gradle: 1. Compiles `main` (and its dependencies via task dependencies). 2. Resolves the `runtimeClasspath` configuration into a set of files. 3. Forks a new JVM with that classpath and invokes `mainClass`'s `main` method. Pass program arguments with `--args`: ```bash ./gradlew run --args="--env prod --verbose" ``` ## Why a separate plugin instead of just JavaExec? You *could* register your own `JavaExec` task, but the application plugin standardizes the entry point, wires the classpath, and additionally provides the packaging tasks (`installDist`, `distZip`, start scripts) so the same `mainClass` drives both local runs and distributable artifacts — a single source of truth for the entry point.

  • What is the difference between mainClass and the old mainClassName?
    mainClassName was a plain String property; mainClass is a lazy Property<String> assigned with =. mainClassName is deprecated. Lazy evaluation lets the value be computed/overridden before the run task actually resolves it.
  • Does applying 'application' require also applying 'java'?
    No — the application plugin applies the java plugin for you. Adding 'java' explicitly is redundant but harmless.

saying these in an interview costs you the question

  • Saying you must register your own JavaExec task — the plugin already provides 'run'.
  • Claiming mainClass must point to a file path rather than a fully-qualified class name.
  • Insisting mainClassName is still the recommended property.

context