Introduction

The badass-runtime plugin allows you to create custom runtime images for non-modular applications. It also lets you create an application installer with the jpackage tool introduced in Java 14.

For modular applications use the Badass-JLink plugin.

Creating a custom runtime image for a non-modular application involves the following steps:

  • create a classic (pre-Java-9-style) distribution using a task such as installDist or installShadowDist

  • use jlink to create a custom JRE containing only the modules required by the application

  • merge the pre-Java-9-style distribution into the custom JRE and adjust the start scripts with appropriate JVM settings flags such as --module-path.

The plugin provides a runtime task that automates the above steps and a runtimeZip task that additionally creates a zip archive of the custom runtime image. In addition, a suggestModules task helps you choose the modules to include in your custom JRE. With the jpackage task you can create a platform-specific installer for your application.

The plugin requires Java 11 and Gradle 4.8 or newer. While it might work with some combinations of older Java and Gradle versions, these are not officially supported.

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

plugins {
    id 'org.beryx.runtime' version '1.8.0'
}

Applying this plugin also implicitly applies the Application plugin.

The badass-runtime plugin adds an extension named runtime. The sample below shows a few configuration options.

runtime {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    modules = ['java.naming', 'java.xml']
}

The next sections provide detailed information on how to configure the plugin.

The source code is available on GitHub and is licensed under the Apache-2.0 license.

User Guide

This plugin works with non-modular applications, that is, applications that run on the class-path and don’t make use of module descriptors. Nevertheless, in order to use this plugin, your non-modular application must be compatible with the Java version of your target JRE (11 or newer).

Tasks

runtime

Creates an image containing your application, a custom JRE, and appropriate start scripts.
If the property distDir is not set, this task depends on either installDist or installShadowDist (if the Shadow plugin is applied).

runtimeZip

Creates a zip archive of the custom runtime image.
depends on: runtime

suggestModules

Displays a list of modules that are probably required by your application. This list will be used when creating the custom JRE if you don’t configure the modules property explicitly within the runtime extension.
Setting the modules property explicitly is strongly recommended. The list of modules suggested by this task is a good value to start with, but it may miss some required modules or include unnecessary ones, so you may need to adjust it.
depends on: jar

jpackageImage

Uses the jpackage tool to create a platform-specific application image.
depends on: runtime
This task is experimental.

jpackage

Uses the jpackage tool to create a platform-specific application installer.
depends on: jpackageImage
This task is experimental.

Properties

distDir

The directory containing the application pre-Java-9-style distribution.
You rarely need to set this property explicitly, because the plugin automatically initializes it with the directory in which the installDist or the installShadowDist task (if the Shadow plugin is applied) creates the distribution.
usage example: distDir = file("$buildDir/install/myapp")

imageDir

The directory into which the custom runtime image should be generated.
(If you use the targetPlatform method to generate images for other platforms, the corresponding images will be created in subdirectories of imageDir.)
defaultValue: buildDir/image
usage example: imageDir = file("$buildDir/myapp-image")

imageZip

The file into which a zip archive of the custom runtime image should be created.
defaultValue: buildDir/image.zip"
usage example: imageZip = file("$buildDir/myapp-image.zip")

options

A list of options to be passed to jlink when creating the custom JRE.
defaultValue: empty list
usage example: options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']

javaHome

The path to the JDK providing the tools needed by the plugin (javac, jar, jlink etc.).
defaultValue: the first non-empty value from:
     - the badass.runtime.java.home system property
     - the BADASS_RUNTIME_JAVA_HOME environment variable
     - the java.home system property (only if it points to a JRE containing the javac, jar, and jlink tools)
     - the JAVA_HOME environment variable
usage example: javaHome = '/usr/lib/jvm/open-jdk'

modules

The list of modules to be included in the custom JRE.
defaultValue: empty list (the modules provided by the suggestModules task will be used)
usage example: modules = ['java.naming', 'java.xml']

additive

In many cases, the list of modules provided by the suggestModules task contains exactly the modules required by your application. This means that you don’t need to configure the modules property, because the plugin can figure out by itself which modules are required. In some other cases, the "suggested" list of modules is almost right, in the sense that it only misses one or a few modules. In these cases, you are allowed to specify only the missing modules in the modules property, and you instruct the plugin to add them to the list of suggested modules, by setting the property additive to true.
defaultValue: false
usage example: additive = true

Methods

addOptions(String…​ options)

Adds options to be passed to jlink. It is an alternative way of setting the options property. You can call this method multiple times.
usage example: addOptions '--no-header-files', '--no-man-pages'

targetPlatform(String name, String jdkHome, List<String> options = [])

Instructs the plugin to generate an application image for a specific platform.
By default, the plugin generates an image for the platform it runs on. To create images for other platforms, you need to call the targetPlatform method (one call per target platform).
name: an identifier of your choice that will be appended to the imageDir and imageZip properties to determine the location of the image directory and of the image archive.
jdkHome: the path to the target platform JDK.
options: an optional list of platform-specific options. These options will pe passed to jlink in addition to those provided by the options property of the runtime extension.

Usage example
runtime {
    ...
    targetPlatform('linux-x64', '/usr/lib/jvm/jdk_x64_linux_hotspot_11_28')
    targetPlatform('linux-s390x', '/usr/lib/jvm/jdk_s390x_linux_hotspot_11_28',
                                                               ['--endian', 'big'])
    ...
}

For a project named hello, executing the runtimeZip task with the above configuration, and assuming default values for the other properties, the plugin will generate the platform-specific images in the directories build/image/hello-linux-x64 and build/image/hello-linux-s390x. The archived images will be available in build/image-linux-x64.zip and build/image-linux-s390x.zip.

The jpackage script block

This experimental script block allows you to customize the jpackage-based generation of platform-specific application images and installers.

jpackageHome

The path to the JDK providing the jpackage tool.
defaultValue: the first non-empty value from:
     - the badass.runtime.jpackage.home system property
     - the BADASS_RUNTIME_JPACKAGE_HOME environment variable
     - the java.home system property (only if it points to a JRE containing the jpackage tool)
     - the JAVA_HOME environment variable
usage example: jpackageHome = "/usr/lib/jvm/jdk14"

outputDir

Convenience property for setting both imageOutputDir and installerOutputDir with the value buildDir/outputDir.
defaultValue: "jpackage"
usage example: outputDir = "my-packaging"

imageOutputDir

the directory passed as argument to the --output option when running jpackage to create an application image.
defaultValue: buildDir/outputDir
usage example: imageOutputDir = file("$buildDir/my-packaging-image")

imageName

the argument passed to the --name option when running jpackage to create an application image.
defaultValue: the name value configured in the launcher block or project.name
usage example: imageName = "MyApp"

imageOptions

list of additional options to be passed to the jpackage executable when creating the appliction image.
defaultValue: empty list
usage example: imageOptions = ["--win-console"]

resourceDir

the directory passed as argument to the --resource-dir option when running jpackage to create an application installer. It is also applicable when creating an application image when you want your own application image instead of the default java image.
usage example: resourceDir = file("$buildDir/my-packaging-resources")

skipInstaller

boolean value that lets you generate only the platform-specific application image and skip the generation of the platform-specific application installer.
defaultValue: false
usage example: skipInstaller = true

installerType

the type of installer to be generated.
defaultValue: null (all supported types for the current platform will be generated)
usage example: installerType = "rpm"

installerOutputDir

the directory passed as argument to the --output option when running jpackage to create an application installer.
defaultValue: buildDir/outputDir
usage example: installerOutputDir = file("$buildDir/my-packaging-installer")

installerName

the argument passed to the --name option when running jpackage to create an application installer.
defaultValue: the name value configured in the launcher block or project.name
usage example: installerName = "MyApp"

jvmArgs

list of JVM arguments to be passed to the virtual machine.
defaultValue: the jvmArgs value configured in the launcher block or an empty list

appVersion

the argument passed to the --app-version option when running jpackage when executing the jpackage and jpackageImage tasks.
defaultValue: the project version
usage example: appVersion = "1.0.0"

installerOptions

list of additional options to be passed to the jpackage executable when creating the application installer.
defaultValue: empty list
usage example: installerOptions = ["--win-console"]

targetPlatformName

This property is required only when using the targetPlatform method. It specifies which of the images produced by jlink should be used as runtime image by jpackage. Its value must match the name provided in one of the calls to the targetPlatform method.
defaultValue: null
usage example: targetPlatform = "linux"

mainJar

the argument passed to the --main-jar option when running jpackage to create an application image.
Usually, you don’t need to set this property, unless you also explicitly set distDir.
defaultValue: the name of the JAR file produced by the installDist or the installShadowDist task
usage example: mainJar = "my-app-1.0.1.jar"

mainClass

the argument passed to the --main-class option when running jpackage to create an application image.
Usually, you don’t need to set this property, unless you also explicitly set distDir.
defaultValue: the mainClassName configured for the application plugin
usage example: mainClass = "org.example.hello.Greeter"

Usage example

Groovy
runtime {
    ...
    jpackage {
        jpackageHome = '/usr/lib/jvm/jdk14'
        outputDir = 'my-packaging'
        // imageOutputDir = file("$buildDir/my-packaging-image")
        // installerOutputDir = file("$buildDir/my-packaging-installer")
        imageName = 'MyApp'
        imageOptions = ['--win-console']
        skipInstaller = false
        installerName = 'MyApp'
        installerType = 'msi'
        installerOptions = ['--win-menu', '--win-shortcut']
    }
    ...
}
Kotlin
runtime {
    ...
    jpackage {
        jpackageHome = "/usr/lib/jvm/jdk14"
        outputDir = "my-packaging"
        // imageOutputDir = file("$buildDir/my-packaging-image")
        // installerOutputDir = file("$buildDir/my-packaging-installer")
        imageName = "MyApp"
        imageOptions = listOf("--win-console")
        skipInstaller = false
        installerName = "MyApp"
        installerType = "msi"
        installerOptions = listOf("--win-menu", "--win-shortcut")
    }
    ...
}

Examples

The following projects illustrate how to use this plugin to create custom runtime images: