Using the gradle-jnlp-plugin – part 2

This collection of articles describe the gradle-jnlp-plugin from Tobias Schulte, hosted at Github.

The plugin produces a webstart distribution for a JavaSE application as required by the webstart specification. It creates the jnlp file and compresses/signs the jar files. The directory created by the plugin may then be uploaded to your static web server or embedded into your war file.

Describe jar signing process

Following options are available within the jnlp and describe the certificate that will sign the jar files.

signJarParams A map of key/value pairs that describe the certificate that signs the jar files.
Optional. If omitted, or if the map is empty, no jar file becomes signed.
The plugin uses the Ant signjar task. Any of the options described at signjar documentation may be used as entry in this map. The relevant attributes are:
keystore Path of file that contains the keystore with the certificate.
Required.
storepass Password to decrypt the keystore file.
Required.
alias Alias that identifies the certificate within the keystore file.
Required.
keypass Password to decrypt the certificate within the keystore file.
Optional. If omitted, defaults to the value passed to storepass.
tsaurl URL of webservice that provides timestamp authority.
Optional. If omitted, the jar file signature will expire together with the certificate.
signJarAddedManifestEntries A map of key/value pairs to be added as properties to each manifest in jars distributed by the application.
Optional. Defaults to [ 'Codebase': '*', 'Permissions' : 'all-permissions', 'Application-Name': "${project.name}" ].
signJarFilteredMetaInfFiles Optional. Defaults to '(?:SIG-.*|.*[.](?:DSA|SF|RSA)|INDEX.LIST)'
signJarRemovedManifestEntries A regular expression that matches names of properties that are to be removed from each manifest in jars distributed by the application.
Optional. Defaults to '(?:Trusted-Only|Trusted-Library)'
signJarRemovedNamedManifestEntries A regular expression that matches names of properties that are to be removed from each manifest in jars distributed by the application.
Optional. Defaults to '(?:.*-Digest)'.

The default values for signJarAddedManifestEntries and signJarRemovedManifestEntries are the most permissive (less secure) configuration available at the webstart specification. It allows the jar files to access user’s system resources (like reading and writing local files). I allows reusing the jar files on other domains and other applications.

These two permissions should be fine for most common webstart applications. Recent webstart environment requires jar files, even for dependencies, to declare required permissions to validate successfully while loading application. I would only change their values if sandboxing your application is really a requirement or if someone must not reuse any of your jar files. If so, see Preventing RIAs from Being Repurposed.

Further, I experienced some rare situations where invalid manifest entries from thard party jar files were not accepted by the target webstart JVM. I had to remove these entries using signJarRemovedManifestEntries.

The default values for signJarFilteredMetaInfFiles and signJarRemovedNamedManifestEntries remove any existing signature from third party jar files. Such signatures (or self-signatures) may not be recognized by the target webstart JVM, preventing your application from launching. This default options will conservatively replace any existing signature by a signature from your own certificate.

This should be fine if you own a valid certificate, unless licensing issues would prevent you from redistributing third party jar files using your own certificate.

You may provide the signing options within one line:

jnlp {
   signJarParams = [keystore: '../keystore.ks', alias: 'myalias', storepass: 'mystorepass']
}

Or as individual attributes:

jnlp {
   signJarParams. keystore = '../keystore.ks'
   signJarParams. alias= 'myalias'
   signJarParams. storepass = 'mystorepass'
}

Describe branding

A user will expect to recognize your application on several branding artifacts that identify your application. Typically, such artifacts are application name, splash screen and icons that appear on the OS’s taskbar/desktop/main menu.

Such artifacts are defined within the jnlp file. Instead of providing a large set of options for this purpose, the gradle-jnlp-plugin maintainer preferred to let you write own XML snippet to be placed within the jnlp file. The XML elements are documented at Structure of the JNLP File – Information element.

Such XML snippet is described as groovy script as documented at Processing XML – Creating XML. For simplicity, I present an example that will cover most relevant branding artifacts.

jnlp {
    withXml {
       information {
          /* Application name that is shown while downloading the application,
           * on webstart security dialogs, on OS's desktop icon and 
           * OS's main menu entry. */
          title project.name

          /* Company name and homepage that is shown while downloading the 
           * application, on webstart security dialogs. */
          vendor project.group ?: project.name
          homepage (href: 'www.example.com.br')

          /* Several text versions that explain the application purpose. */
          description (kind: 'one-line', 'One line description.')
          description (kind: 'short', 'More than one line description.')
          description (kind: 'tool-tip', 'Tooltip description.')

          /* Application icon, of several sizes. The target JVM will choose the
           * one that best fits for each situation. This example assumes 
           * 3 versions of the same icone with sizes: 16x16, 32x32 and 
           * 48x48 pixels. The icon is described by a href relative to the 
           * JNLP file. If the jnlp is hosted at www.example.com/app/launch.jnlp,
           * the first icon will be downloaded from 
           * www.example.com/app/images/main-16.png. 
           * All icons should be png files. */
          icon (href: 'images/main-16.png')
          icon (href: 'images/main-32.png')
          icon (href: 'images/main-48.png')

          /* Image for application splash screen, presented while downloading
           * and verifying the jar files. */
          icon (href: 'images/splash.png', kind: 'splash')

          shortcut {
             /* Add shortcut with icon to OS's desktop. */
             desktop()
             /* Add shortcut with icon to submenu inside the OS's main menu. */
             menu (submenu: 'submenu-name')
          }
       }
       /* Through the jar files declare permissions, these permissions
        * must be declared again in the JNLP file. */
       security {
           'all-permissions'()
       }
   }
}

Leave a comment