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.
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 7.0 or newer. While it might work with some combinations of older Java and Gradle versions, these are not officially supported. If you are forced to work with an older Gradle release, you should use the version 1.12.7 of this plugin. |
To use the plugin, include the following in your build script:
plugins {
id 'org.beryx.runtime' version '1.13.1'
}
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 propertydistDir
is not set, this task depends on eitherinstallDist
orinstallShadowDist
(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 theruntime
extension.
Setting themodules
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
- jpackage
-
Uses the jpackage tool to create a platform-specific application installer.
depends on:jpackageImage
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 theinstallDist
or theinstallShadowDist
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 thetargetPlatform
method to generate images for other platforms, the corresponding images will be created in subdirectories ofimageDir
.)
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:
- thebadass.runtime.java.home
system property
- theBADASS_RUNTIME_JAVA_HOME
environment variable
- the Java toolchain configured in the Gradle script
- thejava.home
system property (only if it points to a JRE containing thejavac
,jar
, andjlink
tools)
- theJAVA_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 thesuggestModules
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 themodules
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 themodules
property, and you instruct the plugin to add them to the list of suggested modules, by setting the propertyadditive
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 use jlink to generate an application image for a specific platform.
This method is not for configuring the installable packages produced by jpackage. See details
By default, the plugin generates an image for the platform it runs on. To create images for other platforms, you need to call thetargetPlatform
method (one call per target platform).
name: an identifier of your choice that will be appended to theimageDir
andimageZip
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 theoptions
property of theruntime
extension.
NOTE: This is only a convenience method. There is a more powerfultargetPlatform
method (described below), which allows configuring additional parameters of the target platform.
Usage example
For a project named |
- targetPlatform(String name, Action<TargetPlatform> action)
-
This more powerful version of the
targetPlatform
method allows configuring the target platform parameters using a script block.
name: an identifier of your choice that will be appended to theimageDir
andimageZip
properties to determine the location of the image directory and of the image archive.
action: a script block for configuring the target platform parameters.
Parameters:
jdkHome: the path to the target platform JDK.
options: an optional list of platform-specific options.
Methods:
addOptions(String… options): an alternative way of setting theoptions
property.
jdkDownload(String downloadUrl, Closure downloadConfig=null): helper method for setting jdkHome.
It downloads and unpacks a JDK distribution from the given URL.
The optional closure allows configuring the following parameters:
- downloadDir: the directory in which the distribution is downloaded and unpacked.
defaultValue:buildDir/jdks/targetPlatform-name
- archiveName: the name under which the archived distribution should be saved.
defaultValue:jdk
- archiveExtension: accepted values:tar.gz
andzip
.
defaultValue:null
(inferred from the URL)
- pathToHome: the relative path to the JDK home in the unpacked distribution.
defaultValue:null
(inferred by scanning the unpacked distribution)
- overwrite: iftrue
, the plugin overwrites an already existing distribution.
defaultValue:false
Usage example
|
- enableCds(Action<CdsData> action = null)
-
Experimental - requires Java 13 or newer
Enables Class Data Sharing (CDS).
action: an optional script block for configuring the class data sharing.
Parameters:
sharedArchiveFile: the path and name of the class data sharing archive file.
It supports the Mustache syntax and placeholders described in the launcher section.
defaultValue:
lib/server/<appName>.jsa
on Unix-like systems
bin\server\<appName>.jsa
on Windows
Usage example
or
When the The plugin also configures a dynamic AppCDS archive in the start scripts.
If no file is found at the NOTE: Start scripts are not included in the installable packages generated by |
Script blocks
The runtime
extension can also contain the script blocks detailed below.
launcher
The plugin generates script files for launching your application.
These script files can be customized by configuring the launcher
block.
Environment variables can be included by using the Mustache syntax,
that is, by enclosing their name between {{
and }}
.
Additionally, you can use the following placeholders:
-
{{BIN_DIR}}
- the bin directory of the custom runtime image -
{{HOME_DIR}}
- user’s home directory ($HOME
on Unix-like systems,%USERPROFILE%
on Windows)- jvmArgs
-
list of JVM arguments to be passed to the java executable.
defaultValue: the arguments configured in theapplicationDefaultJvmArgs
property of theapplication
extension - noConsole
-
This boolean property has an effect only on Windows. It is ignored on other platforms.
If true, the application will be launched without an associated console window (usingjavaw
instead ofjava
).
defaultValue: false - runInBinDir
-
If true, the start script will
cd
in thebin
directory of the image before executing the application.
defaultValue: false - unixScriptTemplate
-
the template for generating the script file for Unix-like systems.
defaultValue: null (the plugin uses its own template) - windowsScriptTemplate
-
the template for generating the script file for Windows-based systems.
defaultValue: null (the plugin uses its own template)
The plugin uses Groovy’s SimpleTemplateEngine to parse the templates, with the following variables available:
-
applicationName
-
mainClassName
Usage example
runtime {
...
launcher {
jvmArgs = [
'-Dlog4j.debug=true', '-Dlog4j.configurationFile={{BIN_DIR}}/log4j2.xml',
'-DdbHost', '{{PGHOST}}'
]
unixScriptTemplate = file('unixStartScript.txt')
windowsScriptTemplate = file('windowsStartScript.txt')
}
...
}
runtime {
...
launcher {
jvmArgs = listOf(
"-Dlog4j.debug=true", "-Dlog4j.configurationFile={{BIN_DIR}}/log4j2.xml",
"-DdbHost", "{{PGHOST}}"
)
unixScriptTemplate = file("unixStartScript.txt")
windowsScriptTemplate = file("windowsStartScript.txt")
}
...
}
jpackage
This script block allows you to customize the jpackage-based generation of platform-specific installable packages.
- jpackageHome
-
The path to the JDK providing the jpackage tool.
defaultValue: the first non-empty value from:
- thebadass.runtime.jpackage.home
system property
- theBADASS_RUNTIME_JPACKAGE_HOME
environment variable
- the Java toolchain configured in the Gradle script
- thejava.home
system property (only if it points to a JRE containing thejpackage
tool)
- theJAVA_HOME
environment variable
usage example:jpackageHome = "/usr/lib/jvm/jdk16"
- outputDir
-
Convenience property for setting both
imageOutputDir
andinstallerOutputDir
with the value buildDir/outputDir.
defaultValue:"jpackage"
usage example:outputDir = "my-packaging"
- imageOutputDir
-
the directory passed as argument to the
--output
option when runningjpackage
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 runningjpackage
to create an application image.
defaultValue: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 runningjpackage
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 runningjpackage
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 runningjpackage
to create an application installer.
defaultValue:project.name
usage example:installerName = "MyApp"
- jvmArgs
-
list of JVM arguments to be passed to the virtual machine.
defaultValue: thejvmArgs
value configured in thelauncher
block, or the arguments configured in theapplicationDefaultJvmArgs
property of theapplication
extension.
NOTE: If the default value is used, and it contains the placeholder{{BIN_DIR}}
, the plugin replaces this placeholder with$APPDIR/..
when passing the arguments tojpackage
. This is the correct approach in most cases. If it doesn’t work in your case, you need to explicitly configure jvmArgs in thejpackage
block.
Currently, jpackage doesn’t support environment variables in--java-options
. Therefore, you cannot use environment variable names enclosed between{{
and}}
injvmArgs
. - args
-
list of arguments to be passed to the application.
defaultValue: the arguments configured in theargs
property of therun
task - appVersion
-
the argument passed to the
--app-version
option when runningjpackage
when executing thejpackage
andjpackageImage
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 thetargetPlatform
method.
defaultValue: null
usage example:targetPlatformName = "linux"
In contrast to jlink, jpackage is not able to produce installers for other platforms. For example, to create an installer for Linux, you must run jpackage on a Linux machine. You cannot do it on a Windows or Mac platform. |
If you need to create installers for more than one platform, it’s probably better not to use targetPlatform. Instead, you run the same build on different machines. If your project is on GitHub, you can automate this by using GitHub Actions, as seen in this example. |
- mainJar
-
the argument passed to the
--main-jar
option when runningjpackage
to create an application image.
Usually, you don’t need to set this property, unless you also explicitly setdistDir
.
defaultValue: the name of the JAR file produced by theinstallDist
or theinstallShadowDist
task
usage example:mainJar = "my-app-1.0.1.jar"
- mainClass
-
the argument passed to the
--main-class
option when runningjpackage
to create an application image.
Usually, you don’t need to set this property, unless you also explicitly setdistDir
.
defaultValue: themainClass
configured for theapplication
plugin
usage example:mainClass = "org.example.hello.Greeter"
Usage example
runtime {
...
jpackage {
jpackageHome = '/usr/lib/jvm/jdk16'
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']
}
...
}
runtime {
...
jpackage {
jpackageHome = "/usr/lib/jvm/jdk16"
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:
-
badass-runtime-example - a 'Hello world' application using slf4j and logback.
-
badass-runtime-example-javafx - a 'Hello world' JavaFX application.
-
badass-runtime-example-kotlin-tornadofx - a 'Hello world' application written in Kotlin using tornadofx.
-
badass-runtime-spring-petclinic - creates a custom runtime image of the Spring PetClinic application.
-
badass-runtime-pacman - creates a custom runtime image of Pacman from the FXGLGames repository.