# The Application Plugin

version 6.5-milestone-1

The Application plugin facilitates creating an executable JVM application. It makes it easy to start the application locally during development, and to package the application as a TAR and/or ZIP including operating system specific start scripts.

Applying the Application plugin also implicitly applies the Java plugin. The `main` source set is effectively the “application”.

Applying the Application plugin also implicitly applies the Distribution plugin. A `main` distribution is created that packages up the application, including code dependencies and generated start scripts.

## Building JVM applications

To use the application plugin, include the following in your build script:

Example 1. Using the application plugin
build.gradle

    plugins {
        id 'application'
    }

build.gradle.kts

    plugins {
        application
    }

The only mandatory configuration for the plugin is the specification of the main class (i.e. entry point) of the application.

Example 2. Configure the application main class
build.gradle

    application {
        mainClass = 'org.gradle.sample.Main'
    }

build.gradle.kts

    application {
        mainClass.set("org.gradle.sample.Main")
    }

You can run the application by executing the `run` task (type: JavaExec). This will compile the main source set, and launch a new JVM with its classes (along with all runtime dependencies) as the classpath and using the specified main class. You can launch the application in debug mode with `gradle run --debug-jvm` (see JavaExec.setDebug(boolean)).

Since Gradle 4.9, the command line arguments can be passed with `--args`. For example, if you want to launch the application with command line arguments `foo --bar`, you can use `gradle run --args="foo --bar"` (see JavaExec.setArgsString(java.lang.String).

If your application requires a specific set of JVM settings or system properties, you can configure the `applicationDefaultJvmArgs` property. These JVM arguments are applied to the `run` task and also considered in the generated start scripts of your distribution.

Example 3. Configure default JVM settings
build.gradle

    application {
        applicationDefaultJvmArgs = ['-Dgreeting.language=en']
    }

build.gradle.kts

    application {
        applicationDefaultJvmArgs = listOf("-Dgreeting.language=en")
    }

If your application’s start scripts should be in a different directory than `bin`, you can configure the `executableDir` property.

Example 4. Configure custom directory for start scripts
build.gradle

    application {
        executableDir = 'custom_bin_dir'
    }

build.gradle.kts

    application {
        executableDir = "custom_bin_dir"
    }

## Building applications using the Java Module System

Gradle supports the building of Java Modules as described in the corresponding section of the Java Library plugin documentation. Java modules can also be runnable and you can use the application plugin to run and package such a modular application. For this, you need to do two things in addition to what you do for a non-modular application.

First, you need to add a `module-info.java` file to describe your application module. Please refer to the Java Library plugin documentation for more details on this topic.

Second, you need to tell Gradle the name of the module you want to run in addition to the main class name like this:

Example 5. Configure the modular application’s main module
build.gradle

    application {
        mainModule = 'org.gradle.sample.app' // name defined in module-info.java
        mainClass = 'org.gradle.sample.Main'
    }

build.gradle.kts

    application {
        mainModule.set("org.gradle.sample.app") // name defined in module-info.java
        mainClass.set("org.gradle.sample.Main")
    }

That’s all. If you run your application, by executing the `run` task or through a generated start script, it will run as module and respect module boundaries at runtime. For example, reflective access to an internal package from another module can fail.

The configured main class is also baked into the `module-info.class` file of your application Jar. If you run the modular application directly using the `java` command, it is then sufficient to provide the module name.

You can also look at a ready made example that includes a modular application as part of a multi-project.

| Java Module System support is an incubating feature and therefore you need to turn on module path inference explicitly as shown below.

Example 6. Activate module path inference
build.gradle

    java {
        modularity.inferModulePath = true
    }

build.gradle.kts

    java {
        modularity.inferModulePath.set(true)
    }

## Building a distribution

A distribution of the application can be created, by way of the Distribution plugin (which is automatically applied). A `main` distribution is created with the following content:

Table 1. Distribution content
Location | Content
--- | ---
(root dir) | `src/dist`
`lib` | All runtime dependencies and main source set class files.
`bin` | Start scripts (generated by `startScripts` task).

Static files to be added to the distribution can be simply added to `src/dist`. More advanced customization can be done by configuring the CopySpec exposed by the main distribution.

Example 7. Include output from other tasks in the application distribution
build.gradle

    task createDocs {
        def docs = file("$buildDir/docs")
        outputs.dir docs
        doLast {
            docs.mkdirs()
            new File(docs, 'readme.txt').write('Read me!')
        }
    }

    distributions {
        main {
            contents {
                from(createDocs) {
                    into 'docs'
                }
            }
        }
    }

build.gradle.kts

    val createDocs by tasks.registering {
        val docs = file("$buildDir/docs")
        outputs.dir(docs)
        doLast {
            docs.mkdirs()
            File(docs, "readme.txt").writeText("Read me!")
        }
    }

    distributions {
        main {
            contents {
                from(createDocs) {
                    into("docs")
                }
            }
        }
    }

By specifying that the distribution should include the task’s output files (see more about tasks), Gradle knows that the task that produces the files must be invoked before the distribution can be assembled and will take care of this for you.

You can run `gradle installDist` to create an image of the application in `build/install/projectName`. You can run `gradle distZip` to create a ZIP containing the distribution, `gradle distTar` to create an application TAR or `gradle assemble` to build both.

### Customizing start script generation

The application plugin can generate Unix (suitable for Linux, macOS etc.) and Windows start scripts out of the box. The start scripts launch a JVM with the specified settings defined as part of the original build and runtime environment (e.g. `JAVA_OPTS` env var). The default script templates are based on the same scripts used to launch Gradle itself, that ship as part of a Gradle distribution.

The start scripts are completely customizable. Please refer to the documentation of CreateStartScripts for more details and customization examples.

## Tasks

The Application plugin adds the following tasks to the project.

`run` — JavaExec

  Depends on: `classes`

  Starts the application.

`startScripts` — CreateStartScripts

  Depends on: `jar`

  Creates OS specific scripts to run the project as a JVM application.

`installDist` — Sync

  Depends on: `jar`, `startScripts`

  Installs the application into a specified directory.

`distZip` — Zip

  Depends on: `jar`, `startScripts`

  Creates a full distribution ZIP archive including runtime libraries and OS specific scripts.

`distTar` — Tar

  Depends on: `jar`, `startScripts`

  Creates a full distribution TAR archive including runtime libraries and OS specific scripts.

## Application extension

The Application Plugin adds an extension to the project, which you can use to configure its behavior. See the JavaApplication DSL documentation for more information on the properties available on the extension.

You can configure the extension via the `application {}` block shown earlier, for example using the following in your build script:

build.gradle

    application {
        executableDir = 'custom_bin_dir'
    }

build.gradle.kts

    application {
        executableDir = "custom_bin_dir"
    }

## Licensing

The Gradle start scripts that are bundled with your application are licensed under the Apache 2.0 Software License. This does not affect your application, which you can license as you choose.

## Convention properties (deprecated)

This plugin also adds some convention properties to the project, which you can use to configure its behavior. These are deprecated and superseded by the extension described above. See the Project DSL documentation for information on them.

Unlike the extension properties, these properties appear as top-level project properties in the build script. For example, to change the application name you can just add the following to your build script:

build.gradle

    applicationName = 'my-app'

build.gradle.kts

    application.applicationName = "my-app"