## Link

Since Apache Ant 1.10.6

### Description

Assembles jmod files into an executable image. Equivalent to the JDK's jlink tool.

Requires Java 9 or later.

### Parameters

Attribute | Description | Required
--- | --- | ---
destDir | Root directory of created image. | Yes
modulepath | Path-like sequence of jmod files to link in order to create image. | One of these is required, unless a nested `<modulepath>` is present.
modulepathref | Path-like sequence of jmod files to link in order to create image, given as a reference to a path defined elsewhere.
modules | Comma-separated list of modules to place in the linked image. | Yes, unless one or more nested `<module>` elements are present.
observableModules | Comma-separated list of explicit modules that comprise "universe" visible to link tool while linking. | No
launchers | Comma-separated list of commands, each of the form name`=`module or name`=`module`/`mainclass | No
locales | Comma-separated list of extra locales, or wildcard patterns matching multiple locale names, to include. Requires `jdk.localedata` module. | No
excludeResources | Comma-separated list of patterns specifying resources to exclude from source jmods. Each is either a standard PathMatcher pattern or `@`filename, indicating a text file with one resource name per line. | No
excludeFiles | Comma-separated list of patterns specifying files to exclude from linked image. Each is either a standard PathMatcher pattern or `@`filename, indicating a text file with one file name per line. | No
resourceOrder | Comma-separated list of patterns specifying resource search order. Each is either a standard PathMatcher pattern or `@`filename, indicating a text file with one resource name per line. | No
bindServices | Boolean, whether to include in linked image any service providers found in module path corresponding to service provider interfaces used by explicitly linked modules. | No, default is false
ignoreSigning | Boolean, whether to allow signed jar files. (Note: As of Java 11, this is ignored and is always treated as true.) | No, default is false
includeHeaders | Boolean, whether to include header files in linked image. | No, default is true
includeManPages | Boolean, whether to include man pages in linked image. | No, default is true
includeNativeCommands | Boolean, whether to include native executables in linked image. | No, default is true
debug | Boolean, whether to include debug information. | No, default is true
verboseLevel | If set, the linker will produce verbose output, which will be logged at the specified Ant log level (`DEBUG`, `VERBOSE`, `INFO`, `WARN`, or `ERR`). | No, default is no verbose output
compress | Compression level of linked image. One of: `0` or `none` no compression (default) `1` or `strings` constant string sharing `2` or `zip` zip compression | No, default is no compression
endianness | Byte order of linked image, must be `little` or `big` | No, default is native byte order
checkDuplicateLegal | Boolean. When merging legal notices from different modules because they have the same name, verify that their contents are identical. | No, default is false, which means any license files with the same name are assumed to have the same content, and no checking is done.
vmType | Hotspot VM in image. One of: `client` `server` `minimal` `all` | No, default is `all`

### Parameters specified as nested elements

`<link>` can have the following nested elements:

- modulepath
- module
- observableModule
- launcher
- locale
- resourceOrder
- excludeResources
- excludeFiles
- compress
- releaseInfo

#### modulepath

Path-like structure pointing to jmod files to link into image.

#### module

Names a single module to be placed in the linked image. This may be specified multiple times.

Attributes:

Attribute | Description | Required
--- | --- | ---
name | Name of module to add. | Yes

#### observableModule

Names a module visible to the linking process, instead of every module in the module path being considered. This may be specified multiple times.

Attributes:

Attribute | Description | Required
--- | --- | ---
name | Name of module to add to list of observable modules. | Yes

#### launcher

Specifies an executable file which will be added to the linked image, which executes a particular module's main class. Attributes:

Attribute | Description | Required
--- | --- | ---
name | Name of launcher. This typically is used for the name of the executable file. | Yes
module | Name of module to execute. | Yes
mainClass | Name of entry point class in module to execute. | Required unless module has its own main class defined.

#### locale

Specifies locales to include in linked image. May be specified multiple times. Requires `jdk.localedata` module. Attributes:

Attribute | Description | Required
--- | --- | ---
name | Name of locale, or wildcard pattern with `*` that matches multiple locale names. | Yes

#### resourceOrder

Explicit resource search order in linked image. May be specified multiple times. Attributes:

Attribute | Description | Required
--- | --- | ---
pattern | A standard PathMatcher pattern for matching resources | Exactly one of these
listFile | Text file containing list of resource names (not patterns), one per line

If the `resourceOrder` attribute is also present on the task, its patterns are treated as if they occur before patterns in nested `<resourceOrder>` elements.

#### excludeResources

Excludes files from linked image tree. May be specified multiple times. Attributes:

Attribute | Description | Required
--- | --- | ---
pattern | A standard PathMatcher pattern for matching resources | Exactly one of these
listFile | Text file containing list of resource names (not patterns), one per line

#### excludeFiles

Excludes files from linked image. May be specified multiple times. Attributes:

Attribute | Description | Required
--- | --- | ---
pattern | A standard PathMatcher pattern for matching files | Exactly one of these
listFile | Text file containing list of file names (not patterns), one per line

#### compress

Describes how image should be compressed. Attributes:

Attribute | Description | Required
--- | --- | ---
level | Compression level of linked image. One of: `0` or `none` no compression (default) `1` or `strings` constant string sharing `2` or `zip` zip compression | Yes
files | Comma-separated list of patterns matching files to compress. Each pattern either a standard PathMatcher pattern or `@`filename, indicating a text file with one file name per line. | No

`<compress>` can also have any number of nested `<files>` elements, with these attributes:

Attribute | Description | Required
--- | --- | ---
pattern | A standard PathMatcher pattern for matching files | Exactly one of these
listFile | Text file containing list of file names (not patterns), one per line

#### releaseInfo

Replaces, augments, or trims the image's release info properties. Can be specified multiple times. Attributes:

Attribute | Description | Required
--- | --- | ---
file | Java properties file containing new release info properties that will entirely replace the current ones. | No
delete | Comma-separated property keys to remove from application's release info | No

`<releaseInfo>` can also have any number of these nested elements:

##### add

Specifies additional release info properties. Attributes:

Attribute | Description | Required
--- | --- | ---
key | Key of single property to add. | Yes, unless `file` is specified
value | Value of single property to add.
file | Java property file containing any number of properties to add. | Yes, unless `key` and `value` are specified
charset | Character set of property file. | No, default is `ISO_8859_1`, in accordance with java.util.Properties class.

##### delete

Property keys to remove from applicaiton's release info. Attributes:

Attribute | Description | Required
--- | --- | ---
key | Key of property to remove. | Yes

### Examples

#### Basic linking

    <jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/>
    <link destDir="build/image" modulepath="MyApp.jmod"
          modules="com.example.myapp"/>

#### Custom binaries

This will cause a `bin/MyEditor` script to appear in the image:

    <jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/>
    <link destDir="build/image" modulepath="MyApp.jmod"
          modules="com.example.myapp"
          launchers="MyEditor=com.example.myapp/com.example.myapp.editors.EditorMain"/>

Same thing, using a nested launcher element:

    <jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/>
    <link destDir="build/image" modulepath="MyApp.jmod"
          modules="com.example.myapp">

        <launcher name="MyEditor" module="com.example.myapp"
                  mainClass="com.example.myapp.editors.EditorMain"/>

    </link>

#### Limiting locales

Include just the locales needed by the application from the jdk.localedata module:

    <jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/>
    <link destDir="build/image" modulepath="MyApp.jmod"
          modules="com.example.myapp,jdk.localedata"
          locales="zh,jp-*"/>

#### Compressed image

Compress entire image:

    <jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/>
    <link destDir="build/image" modulepath="MyApp.jmod"
          modules="com.example.myapp,jdk.localedata"
          compress="zip"/>

Compress only some files in the image:

    <jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/>
    <link destDir="build/image" modulepath="MyApp.jmod"
          modules="com.example.myapp,jdk.localedata">

        <compress level="zip" files=".*\.xml"/>

    </link>

#### Cross-compiling

To create an image for a different platform:

- Download the JDK for that platform, and expand the archive manually into a directory of your choice. (Downloading a zip or tar.gz version of a JDK instead of an installer will make this easier.)
- Determine the foreign JDK's platform string. This can be done with a command that examines the JDK's `jmods/java.base.jmod` file:

      jmod describe "$FOREIGN_JDK_HOME"/jmods/java.base.jmod | grep '^platform'

- Create your jmod using the foreign JDK's platform string:

      <jmod destfile="MyApp.jmod" classpath="build/myapp.jar" platform="windows-amd64"/>

- Link with the foreign JDK's `jmods` directory in the module path:

      <link destDir="build/image"
            modulepath="MyApp.jmod;${foreign-jdk-home}/jmods"
            modules="com.example.myapp"/>