skip to content

Application Plugin

The application plugin: declaring a main class and default JVM arguments, and the run task it contributes. The standard answer for making a Gradle project executable.

on this pageshow

questions

5

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

open as a page

How does the 'run' task build the classpath it launches with, and how would you customise it (e.g. add a config directory, change JVM args, or set the working directory)?

level: middleimportance: must knowfreq 50%

basics

~20 s

The 'run' task is a JavaExec whose classpath is the main source set's runtimeClasspath (compiled classes + runtime dependencies). You customise it by configuring the run task: tasks.named<JavaExec>("run") { jvmArgs(...); workingDir = ...; classpath += files(...) }.

open as a page

What is applicationDefaultJvmArgs, how does it differ from program arguments and ad-hoc JVM flags, and when is it actually applied?

level: middleimportance: should knowfreq 45%

basics

~10 s

applicationDefaultJvmArgs is a list of JVM options (like -Xmx512m) baked into the application. They apply both to the 'run' task and to the launched app, unlike --args which sets program arguments.

open as a page

When is the built-in application plugin the right choice versus a framework launcher like Spring Boot's bootRun, and what are common ways teams misuse it?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Use the application plugin for plain executable JVM apps where you control main(). Frameworks like Spring Boot provide their own bootRun task and packaging, so you usually rely on those instead. Misuse: forcing both, or expecting application to build an executable fat jar.

open as a page

How do you configure the application plugin for a JPMS (Java module) application, and what changes about mainClass and the launch?

level: seniorimportance: nice to knowfreq 22%

basics

~10 s

For a modular app you also set application { mainModule = "com.example.app" } alongside mainClass. Gradle then launches with --module-path and -m instead of the classpath, running the named module's main class.

open as a page