<!--
  ~ Copyright 2011 the original author or authors.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<chapter id='application_plugin'>
    <title>The Application Plugin</title>
    <para>The Gradle application plugin extends the language plugins with common application related tasks.
    It allows running and bundling applications for the jvm by creating a jvm application <apilink class="org.gradle.api.distribution.Distribution" />.
    </para>

    <section>
        <title>Usage</title>
        <para>To use the application plugin, include the following in your build script:</para>
        <sample id="useApplicationPlugin" dir="application" title="Using the application plugin">
            <sourcefile file="build.gradle" snippet="use-plugin"/>
        </sample>
        <para>To define the main-class for the application you have to set the <literal>mainClassName</literal> property as shown below</para>
        <sample id="useApplicationPlugin" dir="application" title="Configure the application main class">
            <sourcefile file="build.gradle" snippet="mainClassName-conf"/>
        </sample>

        <para>Then, you can run the application by running <userinput>gradle run</userinput>. Gradle will take care of building the application classes,
            along with their runtime dependencies, and starting the application with the correct classpath.
            You can launch the application in debug mode with <userinput>gradle run --debug-jvm</userinput> (see <apilink class="org.gradle.api.tasks.JavaExec" method="setDebug(boolean)" />).
        </para>

        <para>The plugin can also build a distribution for your application. The <apilink class="org.gradle.api.distribution.Distribution" /> will package up the runtime dependencies of the application
            along with some OS specific start scripts. All files stored in <filename>src/dist</filename> will be added to the root of the
            distribution. You can run <userinput>gradle installDist</userinput> to create an image of the application in
            <filename>build/install/<replaceable>projectName</replaceable></filename>. You can run <userinput>gradle distZip</userinput> to create a
            ZIP containing the distribution, <userinput>gradle distTar</userinput> to create an application TAR or <userinput>gradle assemble</userinput> to build both.
        </para>

        <para>
            If your Java application requires a specific set of JVM settings or system properties, you can configure the <literal>applicationDefaultJvmArgs</literal> property.
            These JVM arguments are applied to the <literal>run</literal> task and also considered in the generated start scripts of your distribution.
        </para>
        <sample id="configureApplicationDefaultJvmArgs" dir="application" title="Configure default JVM settings">
            <sourcefile file="build.gradle" snippet="application-defaultjvmargs"/>
        </sample>

    </section>

    <section>
        <title>Tasks</title>
        <para>The Application plugin adds the following tasks to the project.</para>
        <table>
            <title>Application plugin - tasks</title>
            <thead>
                <tr>
                    <td>Task name</td>
                    <td>Depends on</td>
                    <td>Type</td>
                    <td>Description</td>
                </tr>
            </thead>
            <tr>
                <td>
                    <literal>run</literal>
                </td>
                <td>
                    <literal>classes</literal>
                </td>
                <td><apilink class="org.gradle.api.tasks.JavaExec"/></td>
                <td>Starts the application.</td>
            </tr>
            <tr>
                <td>
                    <literal>startScripts</literal>
                </td>
                <td>
                    <literal>jar</literal>
                </td>
                <td><apilink class="org.gradle.api.tasks.application.CreateStartScripts"/></td>
                <td>Creates OS specific scripts to run the project as a JVM application.</td>
            </tr>
            <tr>
                <td>
                    <literal>installDist</literal>
                </td>
                <td>
                    <literal>jar</literal>, <literal>startScripts</literal>
                </td>
                <td><apilink class="org.gradle.api.tasks.Sync"/></td>
                <td>Installs the application into a specified directory.</td>
            </tr>
            <tr>
                <td>
                    <literal>distZip</literal>
                </td>
                <td>
                    <literal>jar</literal>, <literal>startScripts</literal>
                </td>
                <td><apilink class="org.gradle.api.tasks.bundling.Zip"/></td>
                <td>Creates a full distribution ZIP archive including runtime libraries and OS specific scripts.</td>
            </tr>
            <tr>
                <td>
                    <literal>distTar</literal>
                </td>
                <td>
                    <literal>jar</literal>, <literal>startScripts</literal>
                </td>
                <td><apilink class="org.gradle.api.tasks.bundling.Tar"/></td>
                <td>Creates a full distribution TAR archive including runtime libraries and OS specific scripts.</td>
            </tr>
        </table>
    </section>

    <section>
            <title>Convention properties</title>
            <para>The application plugin adds some properties to the project, which you can use to configure
            its behaviour. See the <apilink class="org.gradle.api.Project"/> class in the API documentation.
            </para>
    </section>

    <section id="application_distribution_resources">
            <title>Including other resources in the distribution</title>
            <para>
                One of the convention properties added by the plugin is <literal>applicationDistribution</literal> which is a <apilink class="org.gradle.api.file.CopySpec"/>.
                This specification is used by the <literal>installDist</literal> and <literal>distZip</literal> tasks as the specification of what is to be
                included in the distribution. In addition to copying the start scripts to the <filename>bin</filename> dir and necessary jars to <filename>lib</filename> 
                in the distribution, all of the files from the <filename>src/dist</filename> directory are also copied. To include any static files in the 
                distribution, simply arrange them in the <filename>src/dist</filename> directory.
            </para>
            <para>
                If your project generates files to be included in the distribution, e.g. documentation, you can add these files to the distribution by adding to the 
                <literal>applicationDistribution</literal> copy spec.
            </para>
            <sample id="includeTaskOutputInApplicationDistribution" dir="application" title="Include output from other tasks in the application distribution">
                <sourcefile file="build.gradle" snippet="distribution-spec"/>
            </sample>
            <para>
                By specifying that the distribution should include the task's output files (see <xref linkend="sec:task_inputs_outputs"/>), 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.
            </para>
            <sample id="dependentTaskForApplicationDistributionOutput" dir="application" title="Automatically creating files for distribution">
                <output args="distZip"/>
            </sample>
    </section>
    
</chapter>
