Gradle Application Plugin: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 91: Line 91:
==Generate Multiple Start Scripts==
==Generate Multiple Start Scripts==


Use the default "startScripts" task to generate the main start script, or one of the start scripts, if they are all equivalent, and add new CreateStartScripts instances for each additional start script:
We generate multiple start script by using the default "startScript" to create the main start script (or if there's no main, one of the start scripts), and we declare a new CreateStartScripts task instance for each additional script. We use the default "startScript" to read common configuration from, and we make it to depend on all newly added tasks, so they are executed automatically:


<syntaxhighlight lang='groovy'>
<syntaxhighlight lang='groovy'>
...
apply plugin: 'application'
//
//
// this configures the main (or one) of the scripts:
// this generates an additional (not main) wrapper script
//
//
def org.gradle.api.Task task = rootProject.tasks.getByPath('startScripts');
 
task.applicationName = 'some-app-name';
task secondaryStartScript(type: CreateStartScripts) {
task.mainClassName = 'com.example.Main';
 
    applicationName = 'secondary'
    mainClassName = 'com.example.secondary.Main'
 
    //
    // get the rest of the configuration from the already configured 'startScripts' task;
    // except 'applicationName' and 'mainClassName', the rest of the configuration should
    // be similar
    //
    def t = rootProject.tasks.getByPath('startScripts');
    classpath = t.classpath;
    outputDir = t.outputDir;
}


//
//
// these will build additional scripts
// this configures the main 'startScript' task to generate the "main" script
//
//
 
def t = rootProject.tasks.getByPath('startScripts');
 
t.applicationName = 'primary';
t.mainClassName = 'com.example.primary.Main';
t.dependsOn(secondaryStartScript); // trigger 'secondaryStartScript' execution automatically
</syntaxhighlight>
</syntaxhighlight>


==Configure the Start Script Template==
==Configure the Start Script Template==

Revision as of 23:47, 23 July 2018

External

Internal

Overview

The application plugin facilitates creating an executable JVM application. It bundles all application JARS, transitive dependencies and operating system specific scripts into a TAR or ZIP file, and it also generates the bash and Windows wrapper scripts to run the application with. The plugin also allows executing the application from the project's work area with the "run" task.

Typical Setup

This setup describes configuration of a multi-project build, whose sub-project create various components of the application and the top level project bundles all those in a distributable artifact. The dependencies between the sub-projects must be configured in the corresponding build.gradle files. To build the application artifact, we assume that there's a sub-project that contains the "main()" static method that triggers the execution, that method exists in "io.example.Main" class, and the sub-project in question is named "main".

As such, the top-level project build.gradle should contain the following relevant configuration:

...

apply plugin: 'application'

mainClassName = "io.example.Main"

dependencies {

    ...

    implementation project(':main')
}

Provided that the rest of the dependencies between sub-projects are correctly declared in the corresponding build.gradle files, the execution of

gradle distZip

will compile everything and will create a ./build/distributions/<rootProject.name>.zip file. The file includes the sub-project artifacts, their transitive dependencies, and wrapper scripts for bash and Windows.

For more details about rootProject.name, see:

rootProject

Properties

mainClassName

mainClassName = 'greeter.Greeter'

Executing the Application from Project Work Area

gradle run

However, if the application requires command line parameters, they are not propagated. TODO: find a solution. A temporary solution is to unzip the application ZIP in a temp directory and then repeatedly overwrite the relevant JARs

Start Script Customization

This section explains the mechanics behind creating the application start (wrapper) script and shows how the process can be customized: use a different template, create multiple scripts, etc.

Start Script Mechanics

The Application plugin generates by default Unix and Windows start scripts that are capable launching a configured "main" class in an environment where the classpath is correctly set. The default script templates are based on the same scripts used to launch Gradle, which ship as part of the Gradle distribution. The start scripts are completely customizable though. The Application plugin adds a task named "startScripts" to the project's task list. The task can be view with:

 gradle tasks --all

The "startupScripts" task is a CreateStartScripts type task. The actual script generation is implemented in ScriptGenerator instances, returned by CreateStartScripts.getUnixStartScriptGenerator() and CreateStartScripts.getWindowsStartScriptGenerator(). The default generators are of the type TemplateBasedScriptGenerator with default templates. These templates can be changed via the TemplateBasedScriptGenerator.setTemplate(org.gradle.api.resources.TextResource) method.

Configure the Default 'startScripts' Task

Get a reference to the "startScript" task as described in Get the Reference of a Task by Name and then reconfigure state as needed:

def t = rootProject.tasks.getByPath('startScripts');
t.applicationName = 'some-app-name';
t.mainClassName = 'com.example.Main';

The following variables can be configured:

  • applicationName - this will be the name of the script, without (for Linux) and with .bat extension (for Windows).
  • mainClassName
  • outputDir file('build/sample')
  • classpath files('path/to/some.jar')
  • optsEnvironmentVar
  • exitEnvironmentVar
  • defaultJvmOpts
  • appNameSystemProperty
  • appHomeRelativePath

Generate Multiple Start Scripts

We generate multiple start script by using the default "startScript" to create the main start script (or if there's no main, one of the start scripts), and we declare a new CreateStartScripts task instance for each additional script. We use the default "startScript" to read common configuration from, and we make it to depend on all newly added tasks, so they are executed automatically:

...

apply plugin: 'application'

//
// this generates an additional (not main) wrapper script
//

task secondaryStartScript(type: CreateStartScripts) {

    applicationName = 'secondary'
    mainClassName = 'com.example.secondary.Main'

    //
    // get the rest of the configuration from the already configured 'startScripts' task;
    // except 'applicationName' and 'mainClassName', the rest of the configuration should
    // be similar
    //
    def t = rootProject.tasks.getByPath('startScripts');
    classpath = t.classpath;
    outputDir = t.outputDir;
}

//
// this configures the main 'startScript' task to generate the "main" script
//
def t = rootProject.tasks.getByPath('startScripts');
t.applicationName = 'primary';
t.mainClassName = 'com.example.primary.Main';
t.dependsOn(secondaryStartScript); // trigger 'secondaryStartScript' execution automatically

Configure the Start Script Template