<!--
  ~ 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.
	</para>

    <section>
        <title>Usage</title>
        <para>To use the application plugin, include 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.
        </para>

        <para>The plugin can also build a distribution for your application. The 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 installApp</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.
        </para>
    </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>installApp</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 <apilink class="org.gradle.api.Project"/>.
            </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>installApp</literal> and <literal>distZip</literal> tasks as the specification of what is to be 
                include in the distribution. Above copying the starting 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>
