You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2018/12/15 16:28:15 UTC

[5/6] ant git commit: Added tasks for JDK's jmod and jlink tools.

Added tasks for JDK's jmod and jlink tools.


Project: http://git-wip-us.apache.org/repos/asf/ant/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant/commit/343dff90
Tree: http://git-wip-us.apache.org/repos/asf/ant/tree/343dff90
Diff: http://git-wip-us.apache.org/repos/asf/ant/diff/343dff90

Branch: refs/heads/master
Commit: 343dff90f2a06a14a5e3d8f787de87d4446af3d9
Parents: 7b29e8f
Author: VGR <vg...@gmail.com>
Authored: Thu Dec 6 23:32:57 2018 -0500
Committer: Stefan Bodewig <bo...@apache.org>
Committed: Sat Dec 15 17:13:58 2018 +0100

----------------------------------------------------------------------
 build.xml                                       |    6 +
 manual/Tasks/jlink.html                         |    7 +-
 manual/Tasks/jmod.html                          |  330 +++
 manual/Tasks/link.html                          |  579 +++++
 manual/tasklist.html                            |    2 +
 src/etc/testcases/taskdefs/jar.xml              |    8 +-
 src/etc/testcases/taskdefs/jmod.xml             |  992 ++++++++
 src/etc/testcases/taskdefs/link.xml             | 1088 +++++++++
 .../tools/ant/taskdefs/defaults.properties      |    2 +
 .../apache/tools/ant/taskdefs/modules/Jmod.java | 1282 +++++++++++
 .../apache/tools/ant/taskdefs/modules/Link.java | 2120 ++++++++++++++++++
 .../ant/taskdefs/modules/package-info.java      |   23 +
 .../ant/taskdefs/optional/jlink/JlinkTask.java  |    6 +-
 .../apache/tools/ant/types/ModuleVersion.java   |  147 ++
 .../tools/ant/taskdefs/modules/JmodTest.java    |  690 ++++++
 .../tools/ant/taskdefs/modules/LinkTest.java    |  984 ++++++++
 .../tools/ant/types/ModuleVersionTest.java      |  115 +
 17 files changed, 8374 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index b34bbca..aebcb4a 100644
--- a/build.xml
+++ b/build.xml
@@ -42,6 +42,7 @@
   <property name="ant.package" value="org/apache/tools/ant"/>
   <property name="taskdefs.package" value="${ant.package}/taskdefs"/>
   <property name="condition.package" value="${taskdefs.package}/condition"/>
+  <property name="modules.package" value="${taskdefs.package}/modules"/>
   <property name="optional.package" value="${taskdefs.package}/optional"/>
   <property name="type.package" value="${ant.package}/types"/>
   <property name="optional.type.package" value="${type.package}/optional"/>
@@ -178,6 +179,10 @@
        ===================================================================
   -->
 
+  <selector id="needs.jdk9+">
+    <filename name="${modules.package}/"/>
+  </selector>
+
   <!-- Kaffe has some JDK 1.5 features including java.lang.Readable,
        but not all of them -->
   <selector id="not.in.kaffe">
@@ -609,6 +614,7 @@
       <selector id="conditional-patterns">
         <not>
           <or>
+            <selector refid="needs.jdk9+" unless="jdk9+"/>
             <selector refid="not.in.kaffe" if="kaffe"/>
             <selector refid="needs.apache-resolver" unless="apache.resolver.present"/>
             <selector refid="needs.junit" unless="junit.present"/> <!-- TODO should perhaps use -source 1.4? -->

http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/manual/Tasks/jlink.html
----------------------------------------------------------------------
diff --git a/manual/Tasks/jlink.html b/manual/Tasks/jlink.html
index 76978fb..2c3b49c 100644
--- a/manual/Tasks/jlink.html
+++ b/manual/Tasks/jlink.html
@@ -26,9 +26,14 @@
 <p><em>This task has been <u>deprecated</u>. Use a <a href="../Types/zipfileset.html">zipfileset</a>
 or <a href="../Tasks/zip.html#zipgroupfileset">zipgroupfileset</a> with
 the <a href="../Tasks/jar.html">Jar task</a> or <a href="../Tasks/zip.html">Zip task</a>
-instead.</em></p>
+instead.  For a task based on the JDK's jlink tool, see
+<a href="link.html">Link</a>.</em></p>
 
 <h3>Description</h3>
+<p><strong>For a task based on the JDK's jlink tool, see
+<a href="link.html">Link</a>.  This task is for something else
+entirely.</strong></p>
+
 <p>Links entries from sub-builds and libraries.</p>
 
 <p>The <code>jlink</code> task can be used to build jar and zip files, similar to

http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/manual/Tasks/jmod.html
----------------------------------------------------------------------
diff --git a/manual/Tasks/jmod.html b/manual/Tasks/jmod.html
new file mode 100644
index 0000000..0540918
--- /dev/null
+++ b/manual/Tasks/jmod.html
@@ -0,0 +1,330 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Jmod Task</title>
+</head>
+
+<body>
+
+<h2 id="jmod">Jmod</h2>
+<h3>Description</h3>
+<p>Creates a linkable jmod file from a modular jar file, and optionally from
+other application files such as native libraries and license documents.
+Equivalent to the JDK's
+<a href="https://docs.oracle.com/en/java/javase/11/tools/jmod.html">jmod</a>
+tool.</p>
+<p>Requires Java 9 or later.</p>
+
+<h3>Parameters</h3>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>destFile</td>
+    <td>jmod file to create.</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>classpath</td>
+    <td>Files to be placed in the jmod file.  Usually a single module.</td>
+    <td rowspan="2">One of these is required, unless a nested
+                    <code>&lt;classpath&gt;</code> is present.</td>
+  </tr>
+  <tr>
+    <td>classpathref</td>
+    <td class="left">Files to be placed in the jmod file, given as a 
+        <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+  </tr>
+  <tr>
+    <td>modulepath</td>
+    <td>Locations of modules on which classpath modules depend.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>modulepathref</td>
+    <td>Locations of modules on which classpath modules depend,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>commandpath</td>
+    <td>Directories containing native commands to include in jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>commandpathref</td>
+    <td>Directories containing native commands to include in jmod,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>headerpath</td>
+    <td>Directories containing header files to include in jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>headerpathref</td>
+    <td>Directories containing header files to include in jmod,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>configpath</td>
+    <td>Directories containing user-editable configuration files
+        to include in jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>configpathref</td>
+    <td>Directories containing user-editable configuration files
+        to include in jmod,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>legalpath</td>
+    <td>Directories containing legal licenses and notices to include in jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>legalpathref</td>
+    <td>Directories containing legal licenses and notices to include in jmod,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>nativelibpath</td>
+    <td>Directories containing native libraries to include in jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>nativelibpathref</td>
+    <td>Directories containing native libraries to include in jmod,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>manpath</td>
+    <td>Directories containing man pages to include in jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>manpathref</td>
+    <td>Directories containing man pages to include in jmod,
+        given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>version</td>
+    <td><a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/module/ModuleDescriptor.Version.html">Module version</a> of jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>mainclass</td>
+    <td>Class that acts as executable entry point of module.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>platform</td>
+    <td>The target platform for the jmod.  Typically takes the form
+        <var>OS</var><code>-</code><var>architecture</var>.  A particular JDK's
+        platform can be seen by running a command like
+        <samp>jmod describe $JDK_HOME/jmods/java.base.jmod | grep -i platform</samp></td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>hashModulesPattern</td>
+    <td>Regular expression for names of modules in the module path
+        which depend on the jmod being created, and which should have
+        hashes generated for them and included in the new jmod.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>resolveByDefault</td>
+    <td>Boolean indicating whether the jmod should be one of
+        the default resolved modules when it is in a module path
+        searched by tools and applications.</td>
+    <td>No.  Default is true.</td>
+  </tr>
+  <tr>
+    <td>moduleWarnings</td>
+    <td>Whether to emit warnings when resolving modules which are
+        not recommended for use.  Comma-separated list of one of more of
+        the following:
+        <dl>
+        <dt><code>deprecated</code></dt>
+        <dd>Warn if module is deprecated</dd>
+        <dt><code>leaving</code></dt>
+        <dd>Warn if module is deprecated for removal</dd>
+        <dt><code>incubating</code></dt>
+        <dd>Warn if module is an incubating (not yet official) module</dd>
+        </dl>
+    </td>
+    <td>No, default is no warnings.</td>
+  </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath, modulepath, commandpath, headerpath, configpath, legalpath, nativelibpath, manpath</h4>
+<p>The 
+   <code>classpath</code>,
+   <code>modulepath</code>,
+   <code>commandpath</code>,
+   <code>headerpath</code>,
+   <code>configpath</code>,
+   <code>legalpath</code>,
+   <code>nativelibpath</code>, and
+   <code>manpath</code>
+   attributes are <a href="../using.html#path">path-like structures</a>
+   and can also be set via nested
+   <code>&lt;classpath&gt;</code>,
+   <code>&lt;modulepath&gt;</code>,
+   <code>&lt;commandpath&gt;</code>,
+   <code>&lt;headerpath&gt;</code>,
+   <code>&lt;configpath&gt;</code>,
+   <code>&lt;legalpath&gt;</code>,
+   <code>&lt;nativelibpath&gt;</code>, and
+   <code>&lt;manpath&gt;</code>
+   elements, respectively.</p>
+
+<h4>version</h4>
+<p>Fine-grained alternative to the <code>version</code> attribute.  This
+nested element has these attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>number</td>
+    <td>Primary version number.  Can be any text, as long as it does not
+        contain a hyphen (<code>-</code>) or plus (<code>+</code>).</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>preRelease</td>
+    <td>Pre-release version.  Can be any text, as long as it does not
+        contain a plus (<code>+</code>).</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>build</td>
+    <td>Build version.  Can be any text.
+    <td>No</td>
+  </tr>
+</table>
+
+<p>See the <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/module/ModuleDescriptor.Version.html">ModuleDescriptor.Version documentation</a>
+for a full description of the meaning of each version component.</p>
+
+<h4>moduleWarning</h4>
+<p>Like the <code>moduleWarnings</code> attribute, but only specifies a single
+basis for emitting warnings.  This child element may appear multiple times,
+to specify multiple conditions under which warnings should be emitted by the
+jmod tool.</p>
+
+<p>Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>reason</td>
+    <td>Condition which will cause jmod tool to emit warnings.  One of:
+        <dl>
+        <dt><code>deprecated</code></dt>
+        <dd>Warn if module is deprecated</dd>
+        <dt><code>leaving</code></dt>
+        <dd>Warn if module is deprecated for removal</dd>
+        <dt><code>incubating</code></dt>
+        <dd>Warn if module is an incubating (not yet official) module</dd>
+        </dl>
+    <td>Yes</td>
+  </tr>
+</table>
+
+<h3>Examples</h3>
+
+<h4>Basic jmod</h4>
+<p>Create a jmod from a single modular jar file:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+</pre>
+
+<h4>With dependencies</h4>
+<p>Create a jmod from a modular jar file which depends on another module:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"&gt;
+    &lt;modulepath&gt;
+        &lt;pathelement location="libs/thirdpartyutils.jar"/&gt;
+    &lt;/modulepath&gt;
+&lt;/jmod&gt;
+</pre>
+
+<h4>With version</h4>
+<p>Create a jmod with a module version:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"
+      version="1.2.1-ea+29"/&gt;
+</pre>
+
+<p>Create a versioned jmod from module version components:</p>
+<pre>
+&lt;property name="version" value="1.2.1"/&gt;
+&lt;buildnumber/&gt;
+&lt;loadfile property="buildnum" srcFile="build.number"/&gt;
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"&gt;
+    &lt;version number="${version}" build="${buildnum}"/&gt;
+&lt;/jmod&gt;
+</pre>
+
+<h4>Main class</h4>
+<p>Create a jmod with a main class:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"
+      mainclass="com.example.myapp.MainWindow"/&gt;
+</pre>
+
+<h4>Target platform</h4>
+<p>Create a jmod for a specific platform, possibly different from the
+current platform:</p>
+
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"
+      platform="windows-amd64"/&gt;
+</pre>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/manual/Tasks/link.html
----------------------------------------------------------------------
diff --git a/manual/Tasks/link.html b/manual/Tasks/link.html
new file mode 100644
index 0000000..078acc1
--- /dev/null
+++ b/manual/Tasks/link.html
@@ -0,0 +1,579 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Link Task</title>
+</head>
+
+<body>
+
+<h2 id="link">Link</h2>
+<h3>Description</h3>
+<p>Assembles jmod files into an executable image.  Equivalent to the JDK's
+<a href="https://docs.oracle.com/en/java/javase/11/tools/jlink.html">jlink</a>
+tool.
+</p>
+<p>Requires Java 9 or later.</p>
+
+<h3>Parameters</h3>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>destDir</td>
+    <td>Root directory of created image.</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>modulepath</td>
+    <td>Path-like sequence of jmod files to link in order to create image.</td>
+    <td rowspan="2">One of these is required, unless a nested
+        <code>&lt;modulepath&gt;</code> is present.</td>
+  </tr>
+  <tr>
+    <td>modulepathref</td>
+    <td class="left">Path-like sequence of jmod files to link in order to
+        create image, given as a <a href="../using.html#references">reference</a>
+        to a path defined elsewhere.</td>
+  </tr>
+  <tr>
+    <td>modules</td>
+    <td>Comma-separated list of modules to place in the linked image.</td>
+    <td>Yes, unless one or more nested <code>&lt;module&gt;</code> elements
+        are present.</td>
+  </tr>
+  <tr>
+    <td>observableModules</td>
+    <td>Comma-separated list of explicit modules that comprise
+        "universe" visible to link tool while linking.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>launchers</td>
+    <td>Comma-separated list of commands, each of the form
+        <var>name</var><code>=</code><var>module</var> or
+        <var>name</var><code>=</code><var>module</var><code>/</code><var>mainclass</var></td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>locales</td>
+    <td>Comma-separated list of extra locales, or wildcard patterns matching
+        multiple locale names, to include.
+        Requires <code>jdk.localedata</code> module.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>excludeResources</td>
+    <td>Comma-separated list of patterns specifying resources to exclude
+        from source jmods.  Each is either a
+        <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        or <code>@</code><var>filename</var>, indicating a text file with
+        one resource name per line.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>excludeFiles</td>
+    <td>Comma-separated list of patterns specifying files to exclude
+        from linked image.  Each is either a
+        <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        or <code>@</code><var>filename</var>, indicating a text file with
+        one file name per line.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>resourceOrder</td>
+    <td>Comma-separated list of patterns specifying resource search order.
+        Each is either a
+        <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        or <code>@</code><var>filename</var>, indicating a text file with
+        one resource name per line.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>bindServices</td>
+    <td>Boolean, whether to include in linked image any service providers
+        found in module path corresponding to service provider interfaces
+        used by explicitly linked modules.</td>
+    <td>No, default is false</td>
+  </tr>
+  <tr>
+    <td>ignoreSigning</td>
+    <td>Boolean, whether to allow signed jar files.
+        (Note: As of Java 11, this is ignored and is always treated as true.)</td>
+    <td>No, default is false</td>
+  </tr>
+  <tr>
+    <td>includeHeaders</td>
+    <td>Boolean, whether to include header files in linked image.</td>
+    <td>No, default is true</td>
+  </tr>
+  <tr>
+    <td>includeManPages</td>
+    <td>Boolean, whether to include man pages in linked image.</td>
+    <td>No, default is true</td>
+  </tr>
+  <tr>
+    <td>includeNativeCommands</td>
+    <td>Boolean, whether to include native executables in linked image.</td>
+    <td>No, default is true</td>
+  </tr>
+  <tr>
+    <td>debug</td>
+    <td>Boolean, whether to include debug information.</td>
+    <td>No, default is true</td>
+  </tr>
+  <tr>
+    <td>verboseLevel</td>
+    <td>If set, the linker will produce verbose output, which will be logged at
+        the specified Ant log level (<code>DEBUG</code>, <code>VERBOSE</code>,
+        <code>INFO</code>, <code>WARN</code>, or <code>ERR</code>).</td>
+    <td>No, default is no verbose output</td>
+  </tr>
+  <tr>
+    <td>compress</td>
+    <td>Compression level of linked image. One of:
+        <dl>
+        <dt><code>0</code> or
+            <code>none</code></dt>
+        <dd>no compression (default)</dd>
+        <dt><code>1</code> or
+            <code>strings</code></dt>
+        <dd>constant string sharing</dd>
+        <dt><code>2</code> or
+            <code>zip</code></dt>
+        <dd>zip compression</dd>
+        </dl>
+    </td>
+    <td>No, default is no compression</td>
+  </tr>
+  <tr>
+    <td>endianness</td>
+    <td>Byte order of linked image, must be <code>little</code> or <code>big</code>
+    <td>No, default is native byte order</td>
+  </tr>
+  <tr>
+    <td>checkDuplicateLegal</td>
+    <td>Boolean.  When merging legal notices from different modules
+        because they have the same name, verify that their contents
+        are identical.</td>
+    <td>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.</td>
+  </tr>
+  <tr>
+    <td>vmType</td>
+    <td>Hotspot VM in image. One of:
+        <ul>
+        <li><code>client</code>
+        <li><code>server</code>
+        <li><code>minimal</code>
+        <li><code>all</code>
+        </ul>
+    </td>
+    <td>No, default is <code>all</code></td>
+  </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<p><code>&lt;link&gt;</code> can have the following nested elements:</p>
+<ul>
+<li><a href="#nested-modulepath">modulepath</a></li>
+<li><a href="#nested-module">module</a></li>
+<li><a href="#nested-observableModule">observableModule</a></li>
+<li><a href="#nested-launcher">launcher</a></li>
+<li><a href="#nested-locale">locale</a></li>
+<li><a href="#nested-resourceOrder">resourceOrder</a></li>
+<li><a href="#nested-excludeResources">excludeResources</a></li>
+<li><a href="#nested-excludeFiles">excludeFiles</a></li>
+<li><a href="#nested-compress">compress</a></li>
+<li><a href="#nested-releaseInfo">releaseInfo</a></li>
+</ul>
+
+<h4 id="nested-modulepath">modulepath</h4>
+<p><a href="../using.html#path">Path-like structure</a> pointing to
+    jmod files to link into image.</p>
+
+<h4 id="nested-module">module</h4>
+<p>Names a single module to be placed in the linked image.  This may be
+specified multiple times.</p>
+<p>Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>name</td>
+    <td>Name of module to add.</td>
+    <td>Yes</td>
+  </tr>
+</table>
+
+<h4 id="nested-observableModule">observableModule</h4>
+<p>Names a module visible to the linking process, instead of every module
+in the module path being considered.  This may be specified multiple times.
+<p>Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>name</td>
+    <td>Name of module to add to list of observable modules.</td>
+    <td>Yes</td>
+  </tr>
+</table>
+
+<h4 id="nested-launcher">launcher</h4>
+<p>Specifies an executable file which will be added to the linked image,
+which executes a particular module's main class.  Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>name</td>
+    <td>Name of launcher.  This typically is used for the name of the
+        executable file.</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>module</td>
+    <td>Name of module to execute.</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>mainClass</td>
+    <td>Name of entry point class in module to execute.</td>
+    <td>Required unless module has its own main class defined.</td>
+  </tr>
+</table>
+
+<h4 id="nested-locale">locale</h4>
+<p>Specifies locales to include in linked image.  May be specified multiple
+times.  Requires <code>jdk.localedata</code> module.  Attributes:
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>name</td>
+    <td>Name of locale, or wildcard pattern with <q><code>*</code></q>
+        that matches multiple locale names.</td>
+    <td>Yes</td>
+  </tr>
+</table>
+
+<h4 id="nested-resourceOrder">resourceOrder</h4>
+<p>Explicit resource search order in linked image.  May be specified multiple 
+times.  Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>pattern</td>
+    <td>A <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        for matching resources</td>
+    <td rowspan="2">Exactly one of these</td>
+  </tr>
+  <tr>
+    <td>listFile</td>
+    <td class="left">Text file containing list of resource names (not patterns),
+        one per line</td>
+  </tr>
+</table>
+
+<p>If the <code>resourceOrder</code> attribute is also present on the task, its
+patterns are treated as if they occur before patterns in nested
+<code><resourceOrder></code> elements.</p>
+
+<h4 id="nested-excludeResources">excludeResources</h4>
+<p>Excludes files from linked image tree.  May be specified multiple times.
+   Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>pattern</td>
+    <td>A <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        for matching resources</td>
+    <td rowspan="2">Exactly one of these</td>
+  </tr>
+  <tr>
+    <td>listFile</td>
+    <td class="left">Text file containing list of resource names (not patterns),
+        one per line</td>
+  </tr>
+</table>
+
+<h4 id="nested-excludeFiles">excludeFiles</h4>
+<p>Excludes files from linked image.  May be specified multiple times.
+   Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>pattern</td>
+    <td>A <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        for matching files</td>
+    <td rowspan="2">Exactly one of these</td>
+  </tr>
+  <tr>
+    <td>listFile</td>
+    <td class="left">Text file containing list of file names (not patterns),
+        one per line</td>
+  </tr>
+</table>
+
+<h4 id="nested-compress">compress</h4>
+<p>Describes how image should be compressed.  Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>level</td>
+    <td>Compression level of linked image. One of:
+        <dl>
+        <dt><code>0</code> or
+            <code>none</code></dt>
+        <dd>no compression (default)</dd>
+        <dt><code>1</code> or
+            <code>strings</code></dt>
+        <dd>constant string sharing</dd>
+        <dt><code>2</code> or
+            <code>zip</code></dt>
+        <dd>zip compression</dd>
+        </dl>
+    </td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>files</td>
+    <td>Comma-separated list of patterns matching files to compress.
+        Each pattern either a
+        <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        or <code>@</code><var>filename</var>, indicating a text file with
+        one file name per line.</td>
+    <td>No</td>
+  </tr>
+</table>
+
+<p><code>&lt;compress&gt;</code> can also have any number of nested
+<code>&lt;files&gt;</code> elements, with these attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>pattern</td>
+    <td>A <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29">standard PathMatcher pattern</a>
+        for matching files</td>
+    <td rowspan="2">Exactly one of these</td>
+  </tr>
+  <tr>
+    <td>listFile</td>
+    <td class="left">Text file containing list of file names (not patterns),
+        one per line</td>
+  </tr>
+</table>
+
+<h4 id="nested-releaseInfo">releaseInfo</h4>
+<p>Replaces, augments, or trims the image's release info properties.
+Can be specified multiple times.  Attributes:
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>file</td>
+    <td>Java properties file containing new release info properties
+        that will entirely replace the current ones.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>delete</td>
+    <td>Comma-separated property keys to remove from application's
+        release info
+    <td>No</td>
+  </tr>
+</table>
+
+<p><code>&lt;releaseInfo&gt;</code> can also have any number of these nested elements:</p>
+<h5>add</h5>
+<p>Specifies additional release info properties.  Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>key</td>
+    <td>Key of single property to add.</td>
+    <td rowspan="2">Yes, unless <code>file</code> is specified</td>
+  </tr>
+  <tr>
+    <td>value</td>
+    <td class="left">Value of single property to add.</td>
+  </tr>
+  <tr>
+    <td>file</td>
+    <td>Java property file containing any number of properties to add.</td>
+    <td>Yes, unless <code>key</code> and <code>value</code> are specified</td>
+  </tr>
+  <tr>
+    <td>charset</td>
+    <td>Character set of property file.</td>
+    <td>No, default is <code>ISO_8859_1</code>, in accordance with
+        java.util.Properties class.</td>
+  </tr>
+</table>
+
+<h5>delete</h5>
+<p>Property keys to remove from applicaiton's release info.  Attributes:</p>
+<table class="attr">
+  <tr>
+    <th scope="col">Attribute</th>
+    <th scope="col">Description</th>
+    <th scope="col">Required</th>
+  </tr>
+  <tr>
+    <td>key</td>
+    <td>Key of property to remove.</td>
+    <td>Yes</td>
+  </tr>
+</table>
+
+<h3>Examples</h3>
+<h4>Basic linking</h4>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+&lt;link destDir="build/image" modulepath="MyApp.jmod"
+      modules="com.example.myapp"/&gt;
+</pre>
+
+<h4>Custom binaries</h4>
+<p>This will cause a <samp>bin/MyEditor</samp> script to appear in the
+image:
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+&lt;link destDir="build/image" modulepath="MyApp.jmod"
+      modules="com.example.myapp"
+      launchers="MyEditor=com.example.myapp/com.example.myapp.editors.EditorMain"/&gt;
+</pre>
+
+<p>Same thing, using a nested launcher element:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+&lt;link destDir="build/image" modulepath="MyApp.jmod"
+      modules="com.example.myapp"&gt;
+
+    &lt;launcher name="MyEditor" module="com.example.myapp"
+              mainClass="com.example.myapp.editors.EditorMain"/&gt;
+
+&lt;/link&gt;
+</pre>
+
+<h4>Limiting locales</h4>
+<p>Include just the locales needed by the application from the <a href="https://docs.oracle.com/en/java/javase/11/docs/api/jdk.localedata/module-summary.html">jdk.localedata</a> module:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+&lt;link destDir="build/image" modulepath="MyApp.jmod"
+      modules="com.example.myapp,jdk.localedata"
+      locales="zh,jp-*"/&gt;
+</pre>
+
+<h4>Compressed image</h4>
+<p>Compress entire image:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+&lt;link destDir="build/image" modulepath="MyApp.jmod"
+      modules="com.example.myapp,jdk.localedata"
+      compress="zip"/&gt;
+</pre>
+
+<p>Compress only some files in the image:</p>
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar"/&gt;
+&lt;link destDir="build/image" modulepath="MyApp.jmod"
+      modules="com.example.myapp,jdk.localedata"&gt;
+
+    &lt;compress level="zip" files=".*\.xml"/&gt;
+
+&lt;/link&gt;
+</pre>
+
+<h4>Cross-compiling</h4>
+<p>To create an image for a different platform:
+
+<ul>
+<li>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.)</li>
+<li>Determine the foreign JDK's platform string.  This can be done with
+a command that examines the JDK's <samp>jmods/java.base.jmod</samp> file:
+<pre>
+jmod describe "$FOREIGN_JDK_HOME"/jmods/java.base.jmod | grep '^platform'
+</pre>
+</li>
+<li>Create your jmod using the foreign JDK's platform string:
+<pre>
+&lt;jmod destfile="MyApp.jmod" classpath="build/myapp.jar" platform="windows-amd64"/&gt;
+</pre>
+</li>
+<li>Link with the foreign JDK's <samp>jmods</samp> directory in the module path:
+<pre>
+&lt;link destDir="build/image"
+      modulepath="MyApp.jmod;${foreign-jdk-home}/jmods"
+      modules="com.example.myapp"/&gt;
+</pre>
+</li>
+</ul>
+<ul>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/manual/tasklist.html
----------------------------------------------------------------------
diff --git a/manual/tasklist.html b/manual/tasklist.html
index 5325e38..8194bdb 100644
--- a/manual/tasklist.html
+++ b/manual/tasklist.html
@@ -108,11 +108,13 @@
   <li><a href="Tasks/jjdoc.html">JJDoc</a></li>
   <li><a href="Tasks/jjtree.html">JJTree</a></li>
   <li><a href="Tasks/jlink.html"><em>Jlink</em></a></li>
+  <li><a href="Tasks/jmod.html">Jmod</a></li>
   <li><a href="Tasks/jspc.html"><em>JspC</em></a></li>
   <li><a href="Tasks/junit.html">JUnit</a> (3 &amp; 4)</li>
   <li><a href="Tasks/junitlauncher.html">JUnitLauncher</a> (JUnit 5)</li>
   <li><a href="Tasks/junitreport.html">JUnitReport</a></li>
   <li><a href="Tasks/length.html">Length</a><br/></li>
+  <li><a href="Tasks/link.html">Link</a><br/></li>
   <li><a href="Tasks/loadfile.html">LoadFile</a></li>
   <li><a href="Tasks/loadproperties.html">LoadProperties</a></li>
   <li><a href="Tasks/loadresource.html">LoadResource</a></li>

http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/src/etc/testcases/taskdefs/jar.xml
----------------------------------------------------------------------
diff --git a/src/etc/testcases/taskdefs/jar.xml b/src/etc/testcases/taskdefs/jar.xml
index 78d1abc..cb686f7 100644
--- a/src/etc/testcases/taskdefs/jar.xml
+++ b/src/etc/testcases/taskdefs/jar.xml
@@ -121,7 +121,7 @@
          destfile="${tmp.jar}"
          basedir="."
          includes="j*.xml"
-         excludes="java.xml"
+         excludes="java.xml,jmod.xml"
          update="true"
     />
   </target>
@@ -131,7 +131,7 @@
          destfile="${tmp.jar}"
          basedir="."
          includes="j*.xml"
-         excludes="java.xml"
+         excludes="java.xml,jmod.xml"
     />
   </target>
 
@@ -144,14 +144,14 @@
           depends="makezip">
     <jar destfile="${tmp.jar}"
          update="true">
-      <zipfileset src="${tmp.zip}" excludes="java.xml"/>
+      <zipfileset src="${tmp.zip}" excludes="java.xml,jmod.xml"/>
     </jar>
   </target>
 
   <target name="testNoRecreateZipfilesetExcludesWithoutUpdate"
           depends="makezip">
     <jar destfile="${tmp.jar}">
-      <zipfileset src="${tmp.zip}" excludes="java.xml"/>
+      <zipfileset src="${tmp.zip}" excludes="java.xml,jmod.xml"/>
     </jar>
   </target>
 

http://git-wip-us.apache.org/repos/asf/ant/blob/343dff90/src/etc/testcases/taskdefs/jmod.xml
----------------------------------------------------------------------
diff --git a/src/etc/testcases/taskdefs/jmod.xml b/src/etc/testcases/taskdefs/jmod.xml
new file mode 100644
index 0000000..2a22998
--- /dev/null
+++ b/src/etc/testcases/taskdefs/jmod.xml
@@ -0,0 +1,992 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project name="jmodtest" default="nil" >
+  <import file="../buildfiletest-base.xml"/>
+
+  <target name="nil"/>
+
+  <target name="-dirs">
+    <mkdir dir="${input}"/>
+    <mkdir dir="${output}"/>
+    <property name="jmod" value="${output}/test.jmod"/>
+    <property name="version" value="1.0.1-+99"/>
+  </target>
+
+  <target name="setUp" depends="-dirs">
+  </target>
+
+  <!-- Creates simple modular jar, with only Java SE dependencies. -->
+  <target name="-hello" depends="-dirs">
+
+    <property name="hello.root" value="${input}/hello"/>
+
+    <property name="hello.src" value="${hello.root}/src"/>
+    <property name="hello.classes" value="${hello.root}/classes"/>
+    <property name="hello.jar.dir" value="${hello.root}/jars"/>
+    <property name="hello.jar" value="${hello.jar.dir}/hello.jar"/>
+
+    <property name="hello.pkg"     value=             "org.apache.tools.ant.test.hello"/>
+    <property name="hello.pkg.dir" value="${hello.src}/org/apache/tools/ant/test/hello"/>
+
+    <property name="hello.main-class" value="${hello.pkg}.HelloWorld"/>
+
+    <mkdir dir="${hello.pkg.dir}"/>
+    <echo file="${hello.pkg.dir}/HelloWorld.java">
+package ${hello.pkg};
+
+import java.util.logging.Logger;
+
+public class HelloWorld {
+    public void run() {
+        Logger logger = Logger.getLogger(HelloWorld.class.getName());
+        logger.info("HELLO WORLD");
+    }
+
+    public static void main(String[] args) {
+        new HelloWorld().run();
+    }
+}
+    </echo>
+    <echo file="${hello.src}/module-info.java">
+module ${hello.pkg} {
+    exports ${hello.pkg};
+    requires java.logging;
+}
+    </echo>
+
+    <mkdir dir="${hello.classes}"/>
+    <javac srcdir="${hello.src}" destdir="${hello.classes}" includeAntRuntime="false"/>
+
+    <mkdir dir="${hello.jar.dir}"/>
+    <jar destfile="${hello.jar}" basedir="${hello.classes}"/>
+  </target>
+
+  <!-- Creates modular jar with dependency on hello module. -->
+  <target name="-smile" depends="-dirs,-hello">
+    <property name="smile.root" value="${input}/smile"/>
+
+    <property name="smile.src" value="${smile.root}/src"/>
+    <property name="smile.classes" value="${smile.root}/classes"/>
+    <property name="smile.jar.dir" value="${smile.root}/jars"/>
+    <property name="smile.jar" value="${smile.jar.dir}/smile.jar"/>
+
+    <property name="smile.pkg"     value=             "org.apache.tools.ant.test.smile"/>
+    <property name="smile.pkg.dir" value="${smile.src}/org/apache/tools/ant/test/smile"/>
+
+    <property name="smile.main-class" value="${smile.pkg}.Smile"/>
+
+    <mkdir dir="${smile.pkg.dir}"/>
+    <echo file="${smile.pkg.dir}/Smile.java">
+package ${smile.pkg};
+
+import java.util.logging.Logger;
+import ${hello.pkg}.HelloWorld;
+
+public class Smile {
+    public void run() {
+        Logger logger = Logger.getLogger(Smile.class.getName());
+        logger.info("\u263a\u263b\u263a\u263b");
+    }
+
+    public static void main(String[] args) {
+        new Smile().run();
+        new HelloWorld().run();
+    }
+}
+    </echo>
+    <echo file="${smile.src}/module-info.java">
+module ${smile.pkg} {
+    exports ${smile.pkg};
+    requires java.logging;
+    requires ${hello.pkg};
+}
+    </echo>
+
+    <mkdir dir="${smile.classes}"/>
+    <javac srcdir="${smile.src}" destdir="${smile.classes}"
+           includeAntRuntime="false"
+           modulepath="${hello.jar}"/>
+
+    <mkdir dir="${smile.jar.dir}"/>
+    <jar destfile="${smile.jar}" basedir="${smile.classes}"/>
+  </target>
+
+  <!-- Creates additional modular jar, with only Java SE dependencies. -->
+  <target name="-foobar" depends="-smile">
+
+    <property name="foobar.root" value="${input}/foobar"/>
+
+    <property name="foobar.src" value="${foobar.root}/src"/>
+    <property name="foobar.classes" value="${foobar.root}/classes"/>
+    <property name="foobar.jar.dir" value="${foobar.root}/jars"/>
+    <property name="foobar.jar" value="${foobar.jar.dir}/foobar.jar"/>
+
+    <property name="foobar.pkg"     value=             "org.apache.tools.ant.test.foobar"/>
+    <property name="foobar.pkg.dir" value="${foobar.src}/org/apache/tools/ant/test/foobar"/>
+
+    <property name="foobar.main-class" value="${foobar.pkg}.FooBar"/>
+
+    <mkdir dir="${foobar.pkg.dir}"/>
+    <echo file="${foobar.pkg.dir}/FooBar.java">
+package ${foobar.pkg};
+
+import ${hello.main-class};
+import ${smile.main-class};
+
+public class FooBar {
+    public void run() {
+        new HelloWorld().run();
+        new Smile().run();
+    }
+
+    public static void main(String[] args) {
+        new FooBar().run();
+    }
+}
+    </echo>
+    <echo file="${foobar.src}/module-info.java">
+module ${foobar.pkg} {
+    exports ${foobar.pkg};
+    requires java.logging;
+    requires ${hello.pkg};
+    requires ${smile.pkg};
+}
+    </echo>
+
+    <mkdir dir="${foobar.classes}"/>
+    <javac srcdir="${foobar.src}" destdir="${foobar.classes}"
+           includeAntRuntime="false" modulepath="${hello.jar};${smile.jar}"/>
+
+    <mkdir dir="${foobar.jar.dir}"/>
+    <jar destfile="${foobar.jar}" basedir="${foobar.classes}"/>
+  </target>
+
+  <target name="destAndClasspathNoJmod" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}"/>
+  </target>
+
+  <target name="destAndClasspathOlderThanJmod" depends="-hello">
+    <property name="dateformat" value="yyyy-MM-dd HH:mm:ss.SSS"/>
+    <tstamp>
+      <format property="future" pattern="${dateformat}" offset="1" unit="hour"/>
+    </tstamp>
+    <touch file="${jmod}" datetime="${future}" pattern="${dateformat}"/>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"/>
+  </target>
+
+  <target name="noDestFile">
+    <jmod classpath="."/>
+  </target>
+
+  <target name="noClasspath">
+    <jmod destfile="${jmod}"/>
+  </target>
+
+  <target name="emptyClasspath">
+    <jmod destfile="${jmod}" classpath=""/>
+  </target>
+
+  <target name="nonexistentClasspath">
+    <jmod destfile="${jmod}" classpath="dummy:dummy2"/>
+  </target>
+
+  <target name="classpathref" depends="-hello">
+    <path id="classpathref.testpath">
+      <pathelement location="${hello.jar}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpathref="classpathref.testpath"/>
+  </target>
+
+  <target name="classpath-nested" depends="-hello">
+    <jmod destfile="${jmod}">
+      <classpath>
+        <pathelement location="${hello.jar}"/>
+      </classpath>
+    </jmod>
+  </target>
+
+  <target name="classpath-both" depends="-smile">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <classpath>
+        <pathelement location="${smile.classes}"/>
+      </classpath>
+    </jmod>
+  </target>
+
+  <!-- modulepath targets -->
+
+  <target name="modulepath" depends="-smile">
+    <jmod destfile="${jmod}" classpath="${smile.jar}"
+        modulepath="${hello.jar.dir}"/>
+  </target>
+
+  <target name="modulepathref" depends="-smile">
+    <path id="modulepathref.testpath">
+      <pathelement location="${hello.jar.dir}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${smile.jar}"
+          modulepathref="modulepathref.testpath"/>
+  </target>
+
+  <target name="modulepath-nested" depends="-smile">
+    <jmod destfile="${jmod}" classpath="${smile.jar}">
+      <modulepath>
+        <pathelement location="${hello.jar.dir}"/>
+      </modulepath>
+    </jmod>
+  </target>
+
+  <target name="modulepath-both" depends="-smile,-foobar">
+    <jmod destfile="${jmod}" classpath="${foobar.jar}"
+          modulepath="${hello.jar.dir}">
+      <modulepath>
+        <pathelement location="${smile.jar.dir}"/>
+      </modulepath>
+    </jmod>
+  </target>
+
+  <target name="modulepathnondir" depends="-smile">
+    <jmod destfile="${jmod}" classpath="${smile.jar}"
+          modulepath="${hello.jar}"/>
+  </target>
+
+  <!-- commandpath targets -->
+
+  <target name="commandpath" depends="-hello">
+    <property name="commands" value="${output}/commands"/>
+    <mkdir dir="${commands}"/>
+
+    <property name="command1" value="${commands}/command1"/>
+
+    <echo file="${command1}">
+#!/bin/bash
+`dirname "$0"`/java -m ${hello.pkg}/${hello.pkg}.HelloWorld
+    </echo>
+    <setpermissions mode="777" nonPosixMode="tryDosOrPass">
+      <file file="${command1}"/>
+    </setpermissions>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          commandpath="${commands}"/>
+  </target>
+
+  <target name="commandpathref" depends="-hello">
+    <property name="commands" value="${output}/commands"/>
+    <mkdir dir="${commands}"/>
+
+    <property name="command2" value="${commands}/command2"/>
+
+    <echo file="${command2}">
+#!/bin/bash
+`dirname "$0"`/java -m ${hello.pkg}/${hello.pkg}.HelloWorld
+    </echo>
+    <setpermissions mode="777" nonPosixMode="tryDosOrPass">
+      <file file="${command2}"/>
+    </setpermissions>
+
+    <path id="commandpathref.testpath">
+      <pathelement location="${commands}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          commandpathref="commandpathref.testpath"/>
+  </target>
+
+  <target name="commandpath-nested" depends="-hello">
+    <property name="commands" value="${output}/commands"/>
+    <mkdir dir="${commands}"/>
+
+    <property name="command3" value="${commands}/command3"/>
+
+    <echo file="${command3}">
+#!/bin/bash
+`dirname "$0"`/java -m ${hello.pkg}/${hello.pkg}.HelloWorld
+    </echo>
+    <setpermissions mode="777" nonPosixMode="tryDosOrPass">
+      <file file="${command3}"/>
+    </setpermissions>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <commandpath>
+        <pathelement location="${commands}"/>
+      </commandpath>
+    </jmod>
+  </target>
+
+  <target name="commandpath-both" depends="-hello">
+    <property name="commands1" value="${output}/commands1"/>
+    <property name="commands2" value="${output}/commands2"/>
+    <mkdir dir="${commands1}"/>
+    <mkdir dir="${commands2}"/>
+
+    <property name="command4" value="${commands1}/command4"/>
+    <echo file="${command4}">
+#!/bin/bash
+`dirname "$0"`/java -m ${hello.pkg}/${hello.pkg}.HelloWorld
+    </echo>
+    <setpermissions mode="777" nonPosixMode="tryDosOrPass">
+      <file file="${command4}"/>
+    </setpermissions>
+
+    <property name="command5" value="${commands2}/command5"/>
+    <echo file="${command5}">
+#!/bin/bash
+`dirname "$0"`/java -m ${hello.pkg}/${hello.pkg}.HelloWorld
+    </echo>
+    <setpermissions mode="777" nonPosixMode="tryDosOrPass">
+      <file file="${command5}"/>
+    </setpermissions>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          commandpath="${commands1}">
+      <commandpath>
+        <pathelement location="${commands2}"/>
+      </commandpath>
+    </jmod>
+  </target>
+
+  <!-- headerpath targets -->
+
+  <target name="headerpath" depends="-hello">
+    <property name="headers" value="${output}/headers"/>
+    <mkdir dir="${headers}"/>
+
+    <property name="header1" value="${headers}/header1.h"/>
+
+    <echo file="${header1}">
+typedef int index_t;
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          headerpath="${headers}"/>
+  </target>
+
+  <target name="headerpathref" depends="-hello">
+    <property name="headers" value="${output}/headers"/>
+    <mkdir dir="${headers}"/>
+
+    <property name="header2" value="${headers}/header2.h"/>
+
+    <echo file="${header2}">
+typedef char * string_t;
+    </echo>
+
+    <path id="headerpathref.testpath">
+      <pathelement location="${headers}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          headerpathref="headerpathref.testpath"/>
+  </target>
+
+  <target name="headerpath-nested" depends="-hello">
+    <property name="headers" value="${output}/headers"/>
+    <mkdir dir="${headers}"/>
+
+    <property name="header3" value="${headers}/header3.h"/>
+
+    <echo file="${header3}">
+typedef char * string_t;
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <headerpath>
+        <pathelement location="${headers}"/>
+      </headerpath>
+    </jmod>
+  </target>
+
+  <target name="headerpath-both" depends="-hello">
+    <property name="headers4" value="${output}/headers4"/>
+    <property name="headers5" value="${output}/headers5"/>
+    <mkdir dir="${headers4}"/>
+    <mkdir dir="${headers5}"/>
+
+    <property name="header4" value="${headers4}/header4.h"/>
+    <property name="header5" value="${headers5}/header5.h"/>
+
+    <echo file="${header4}">
+typedef int index_t;
+    </echo>
+    <echo file="${header5}">
+typedef char * string_t;
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" headerpath="${headers4}">
+      <headerpath>
+        <pathelement location="${headers5}"/>
+      </headerpath>
+    </jmod>
+  </target>
+
+  <!-- configpath targets -->
+
+  <target name="configpath" depends="-hello">
+    <property name="config" value="${output}/config"/>
+    <mkdir dir="${config}"/>
+
+    <property name="config1" value="${config}/config1.properties"/>
+
+    <echo file="${config1}">
+timeout=3600
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" configpath="${config}"/>
+  </target>
+
+  <target name="configpathref" depends="-hello">
+    <property name="config" value="${output}/config"/>
+    <mkdir dir="${config}"/>
+
+    <property name="config2" value="${config}/config2.properties"/>
+
+    <echo file="${config2}">
+timeout=7200
+    </echo>
+
+    <path id="configpathref.testpath">
+      <pathelement location="${config}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          configpathref="configpathref.testpath"/>
+  </target>
+
+  <target name="configpath-nested" depends="-hello">
+    <property name="config" value="${output}/config"/>
+    <mkdir dir="${config}"/>
+
+    <property name="config3" value="${config}/config3.properties"/>
+
+    <echo file="${config3}">
+timeout=7200
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <configpath>
+        <pathelement location="${config}"/>
+      </configpath>
+    </jmod>
+  </target>
+
+  <target name="configpath-both" depends="-hello">
+    <property name="config4" value="${output}/config4"/>
+    <property name="config5" value="${output}/config5"/>
+    <mkdir dir="${config4}"/>
+    <mkdir dir="${config5}"/>
+
+    <property name="configfile4" value="${config4}/config4.properties"/>
+    <property name="configfile5" value="${config5}/config5.properties"/>
+
+    <echo file="${configfile4}">
+timeout=3600
+    </echo>
+    <echo file="${configfile5}">
+timeout=7200
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" configpath="${config4}">
+      <configpath>
+        <pathelement location="${config5}"/>
+      </configpath>
+    </jmod>
+  </target>
+
+  <!-- legalpath targets -->
+
+  <target name="legalpath" depends="-hello">
+    <property name="legal" value="${output}/legal"/>
+    <mkdir dir="${legal}"/>
+
+    <property name="legal1" value="${legal}/legal1.txt"/>
+
+    <echo file="${legal1}">
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" legalpath="${legal}"/>
+  </target>
+
+  <target name="legalpathref" depends="-hello">
+    <property name="legal" value="${output}/legal"/>
+    <mkdir dir="${legal}"/>
+
+    <property name="legal2" value="${legal}/legal2.txt"/>
+
+    <echo file="${legal2}">
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+    </echo>
+
+    <path id="legalpathref.testpath">
+      <pathelement location="${legal}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          legalpathref="legalpathref.testpath"/>
+  </target>
+
+  <target name="legalpath-nested" depends="-hello">
+    <property name="legal" value="${output}/legal"/>
+    <mkdir dir="${legal}"/>
+
+    <property name="legal3" value="${legal}/legal3.txt"/>
+
+    <echo file="${legal3}">
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+    </echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <legalpath>
+        <pathelement location="${legal}"/>
+      </legalpath>
+    </jmod>
+  </target>
+
+  <target name="legalpath-both" depends="-hello">
+    <property name="legal4" value="${output}/legal4"/>
+    <property name="legal5" value="${output}/legal5"/>
+    <mkdir dir="${legal4}"/>
+    <mkdir dir="${legal5}"/>
+
+    <property name="legalfile4" value="${legal4}/legal4.txt"/>
+    <property name="legalfile5" value="${legal5}/legal5.txt"/>
+
+    <echo file="${legalfile4}">
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+    </echo>
+    <copy file="${legalfile4}" tofile="${legalfile5}"/>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" legalpath="${legal4}">
+      <legalpath>
+        <pathelement location="${legal5}"/>
+      </legalpath>
+    </jmod>
+  </target>
+
+  <!-- manpath targets -->
+
+  <target name="manpath" depends="-hello">
+    <property name="manpages" value="${output}/manpages"/>
+    <mkdir dir="${manpages}"/>
+
+    <property name="man1" value="${manpages}/man1.1"/>
+
+    <echo file="${man1}"><!--
+--><![CDATA[.TH TRUE "1" "February 2017" "GNU coreutils 8.26" "User Commands"
+.SH NAME
+true \- do nothing, successfully
+.SH SYNOPSIS
+.B true
+[\fI\,ignored command line arguments\/\fR]
+.br
+.B true
+\fI\,OPTION\/\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Exit with a status code indicating success.
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.PP
+NOTE: your shell may have its own version of true, which usually supersedes
+the version described here.  Please refer to your shell's documentation
+for details about the options it supports.
+.SH AUTHOR
+Written by Jim Meyering.
+.SH "REPORTING BUGS"
+GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
+.br
+Report true translation bugs to <http://translationproject.org/team/>
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+.SH "SEE ALSO"
+Full documentation at: <http://www.gnu.org/software/coreutils/true>
+]]><!--
+    --></echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" manpath="${manpages}"/>
+  </target>
+
+  <target name="manpathref" depends="-hello">
+    <property name="manpages" value="${output}/manpages"/>
+    <mkdir dir="${manpages}"/>
+
+    <property name="man2" value="${manpages}/man2.1"/>
+
+    <echo file="${man2}"><!--
+--><![CDATA[.TH FALSE "1" "February 2017" "GNU coreutils 8.26" "User Commands"
+.SH NAME
+false \- do nothing, unsuccessfully
+.SH SYNOPSIS
+.B false
+[\fI\,ignored command line arguments\/\fR]
+.br
+.B false
+\fI\,OPTION\/\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Exit with a status code indicating failure.
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.PP
+NOTE: your shell may have its own version of false, which usually supersedes
+the version described here.  Please refer to your shell's documentation
+for details about the options it supports.
+.SH AUTHOR
+Written by Jim Meyering.
+.SH "REPORTING BUGS"
+GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
+.br
+Report false translation bugs to <http://translationproject.org/team/>
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+.SH "SEE ALSO"
+Full documentation at: <http://www.gnu.org/software/coreutils/false>
+]]><!--
+    --></echo>
+
+    <path id="manpathref.testpath">
+      <pathelement location="${manpages}"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          manpathref="manpathref.testpath"/>
+  </target>
+
+  <target name="manpath-nested" depends="-hello">
+    <property name="manpages" value="${output}/manpages"/>
+    <mkdir dir="${manpages}"/>
+
+    <property name="man3" value="${manpages}/man3.1"/>
+
+    <echo file="${man3}"><!--
+--><![CDATA[.TH FALSE "1" "February 2017" "GNU coreutils 8.26" "User Commands"
+.SH NAME
+false \- do nothing, unsuccessfully
+.SH SYNOPSIS
+.B false
+[\fI\,ignored command line arguments\/\fR]
+.br
+.B false
+\fI\,OPTION\/\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Exit with a status code indicating failure.
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.PP
+NOTE: your shell may have its own version of false, which usually supersedes
+the version described here.  Please refer to your shell's documentation
+for details about the options it supports.
+.SH AUTHOR
+Written by Jim Meyering.
+.SH "REPORTING BUGS"
+GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
+.br
+Report false translation bugs to <http://translationproject.org/team/>
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+.SH "SEE ALSO"
+Full documentation at: <http://www.gnu.org/software/coreutils/false>
+]]><!--
+    --></echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <manpath>
+        <pathelement location="${manpages}"/>
+      </manpath>
+    </jmod>
+  </target>
+
+  <target name="manpath-both" depends="-hello">
+    <property name="manpages4" value="${output}/manpages4"/>
+    <property name="manpages5" value="${output}/manpages5"/>
+    <mkdir dir="${manpages4}"/>
+    <mkdir dir="${manpages5}"/>
+
+    <property name="man4" value="${manpages4}/man4.1"/>
+    <property name="man5" value="${manpages5}/man5.1"/>
+
+    <echo file="${man4}"><!--
+--><![CDATA[.TH TRUE "1" "February 2017" "GNU coreutils 8.26" "User Commands"
+.SH NAME
+true \- do nothing, successfully
+.SH SYNOPSIS
+.B true
+[\fI\,ignored command line arguments\/\fR]
+.br
+.B true
+\fI\,OPTION\/\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Exit with a status code indicating success.
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.PP
+NOTE: your shell may have its own version of true, which usually supersedes
+the version described here.  Please refer to your shell's documentation
+for details about the options it supports.
+.SH AUTHOR
+Written by Jim Meyering.
+.SH "REPORTING BUGS"
+GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
+.br
+Report true translation bugs to <http://translationproject.org/team/>
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+.SH "SEE ALSO"
+Full documentation at: <http://www.gnu.org/software/coreutils/true>
+]]><!--
+    --></echo>
+    <echo file="${man5}"><!--
+--><![CDATA[.TH FALSE "1" "February 2017" "GNU coreutils 8.26" "User Commands"
+.SH NAME
+false \- do nothing, unsuccessfully
+.SH SYNOPSIS
+.B false
+[\fI\,ignored command line arguments\/\fR]
+.br
+.B false
+\fI\,OPTION\/\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Exit with a status code indicating failure.
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.PP
+NOTE: your shell may have its own version of false, which usually supersedes
+the version described here.  Please refer to your shell's documentation
+for details about the options it supports.
+.SH AUTHOR
+Written by Jim Meyering.
+.SH "REPORTING BUGS"
+GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
+.br
+Report false translation bugs to <http://translationproject.org/team/>
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+.SH "SEE ALSO"
+Full documentation at: <http://www.gnu.org/software/coreutils/false>
+]]><!--
+    --></echo>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}" manpath="${manpages4}">
+      <manpath>
+        <pathelement location="${manpages5}"/>
+      </manpath>
+    </jmod>
+  </target>
+
+  <!-- nativelibpath targets -->
+
+  <target name="nativelibpath" depends="-hello">
+    <property name="nativelib" location="${java.home}/lib;${java.home}/bin"/>
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          nativelibpath="${nativelib}"/>
+  </target>
+
+  <target name="nativelibpathref" depends="-hello">
+
+    <path id="nativelibpathref.testpath">
+      <pathelement location="${java.home}/lib"/>
+      <pathelement location="${java.home}/bin"/>
+    </path>
+
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          nativelibpathref="nativelibpathref.testpath"/>
+  </target>
+
+  <target name="nativelibpath-nested" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <nativelibpath>
+        <pathelement location="${java.home}/lib"/>
+        <pathelement location="${java.home}/bin"/>
+      </nativelibpath>
+    </jmod>
+  </target>
+
+  <target name="nativelibpath-both" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          nativelibpath="${java.home}/lib;${java.home}/bin">
+      <nativelibpath>
+        <dirset dir="${java.home}">
+          <include name="lib/server"/>
+          <include name="bin/server"/>
+        </dirset>
+      </nativelibpath>
+    </jmod>
+  </target>
+
+  <!-- non-path targets -->
+
+  <target name="version" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}" version="${version}"/>
+  </target>
+
+  <target name="version-nested" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <version number="1.0.1" build="99"/>
+    </jmod>
+  </target>
+
+  <target name="version-nested-number" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <version number="1.0.1"/>
+    </jmod>
+  </target>
+
+  <target name="version-nested-no-number" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <version build="99"/>
+    </jmod>
+  </target>
+
+  <target name="version-nested-invalid-number" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <version number="1-0-1" build="99"/>
+    </jmod>
+  </target>
+
+  <target name="version-nested-invalid-prerelease" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}">
+      <version number="1.0.1" build="99" prerelease="unit+testing"/>
+    </jmod>
+  </target>
+
+  <target name="version-both" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}" version="${version}">
+      <version number="1.0.1" build="99"/>
+    </jmod>
+  </target>
+
+  <target name="mainclass" depends="-hello">
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          mainclass="${hello.main-class}"/>
+  </target>
+
+  <target name="platform" depends="-smile">
+    <property name="target-platform" value="windows-amd64"/>
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          platform="${target-platform}"/>
+  </target>
+
+  <target name="hashing" depends="-smile">
+    <jmod destfile="${jmod}" classpath="${hello.jar}"
+          modulepath="${smile.jar.dir}"
+          hashModulesPattern=".*smile.*"/>
+  </target>
+</project>