8218055: Use ToolProvider instead of AppRuntimeImageBuilder. JDK-8200758-branch
authorherrick
Mon, 25 Feb 2019 08:21:37 -0500
branchJDK-8200758-branch
changeset 57213 8ff0a29bf9bc
parent 57198 fac5bd3a361d
child 57214 cb63761b7079
8218055: Use ToolProvider instead of AppRuntimeImageBuilder. Reviewed-by: almatvee
src/jdk.jlink/linux/classes/module-info.java.extra
src/jdk.jlink/macosx/classes/module-info.java.extra
src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java
src/jdk.jlink/windows/classes/module-info.java.extra
src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractImageBundler.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties
src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties
src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties
src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties
src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties
src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsBundlerParam.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties
test/jdk/tools/jpackage/createimage/JPackageCreateImageModularJarTest.java
--- a/src/jdk.jlink/linux/classes/module-info.java.extra	Wed Feb 20 14:01:37 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-    exports jdk.tools.jlink.internal.packager to
-        jdk.jpackage;
--- a/src/jdk.jlink/macosx/classes/module-info.java.extra	Wed Feb 20 14:01:37 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-    exports jdk.tools.jlink.internal.packager to
-        jdk.jpackage;
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java	Wed Feb 20 14:01:37 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.tools.jlink.internal.packager;
-
-
-import jdk.tools.jlink.builder.DefaultImageBuilder;
-import jdk.tools.jlink.internal.Jlink;
-import jdk.tools.jlink.internal.JlinkTask;
-import jdk.tools.jlink.plugin.Plugin;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.module.ModuleFinder;
-import java.nio.ByteOrder;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * AppRuntimeImageBuilder is a private API used only by the Java Packager to generate
- * a Java runtime image using jlink. AppRuntimeImageBuilder encapsulates the
- * arguments that jlink requires to generate this image. To create the image call the
- * build() method.
- */
-public final class AppRuntimeImageBuilder {
-    private Path outputDir = null;
-    private Map<String, String> launchers = Collections.emptyMap();
-    private List<Path> modulePath = null;
-    private Set<String> addModules = null;
-    private Set<String> limitModules = null;
-    private String excludeFileList = null;
-    private Map<String, String> userArguments = null;
-    private Boolean stripNativeCommands = null;
-
-    public AppRuntimeImageBuilder() {}
-
-    public void setOutputDir(Path value) {
-        outputDir = value;
-    }
-
-    public void setLaunchers(Map<String, String> value) {
-        launchers = value;
-    }
-
-    public void setModulePath(List<Path> value) {
-        modulePath = value;
-    }
-
-    public void setAddModules(Set<String> value) {
-        addModules = value;
-    }
-
-    public void setLimitModules(Set<String> value) {
-        limitModules = value;
-    }
-
-    public void setExcludeFileList(String value) {
-        excludeFileList = value;
-    }
-
-    public void setStripNativeCommands(boolean value) {
-        stripNativeCommands = value;
-    }
-
-    public void setUserArguments(Map<String, String> value) {
-        userArguments = value;
-    }
-
-    public void build() throws IOException {
-        // jlink main arguments
-        Jlink.JlinkConfiguration jlinkConfig =
-            new Jlink.JlinkConfiguration(new File("").toPath(), // Unused
-                                         addModules,
-                                         ByteOrder.nativeOrder(),
-                                         moduleFinder(modulePath,
-                                             limitModules, addModules));
-
-        // plugin configuration
-        List<Plugin> plugins = new ArrayList<Plugin>();
-
-        if (stripNativeCommands) {
-            plugins.add(Jlink.newPlugin(
-                        "strip-native-commands",
-                        Collections.singletonMap("strip-native-commands", "on"),
-                        null));
-        }
-
-        if (excludeFileList != null && !excludeFileList.isEmpty()) {
-            plugins.add(Jlink.newPlugin(
-                        "exclude-files",
-                        Collections.singletonMap("exclude-files", excludeFileList),
-                        null));
-        }
-
-        // add user supplied jlink arguments
-        for (Map.Entry<String, String> entry : userArguments.entrySet()) {
-            String key = entry.getKey();
-            String value = entry.getValue();
-            plugins.add(Jlink.newPlugin(key,
-                                        Collections.singletonMap(key, value),
-                                        null));
-        }
-
-        // build the image
-        Jlink.PluginsConfiguration pluginConfig = new Jlink.PluginsConfiguration(
-            plugins, new DefaultImageBuilder(outputDir, launchers), null);
-        Jlink jlink = new Jlink();
-        jlink.build(jlinkConfig, pluginConfig);
-    }
-
-    /*
-     * Returns a ModuleFinder that limits observability to the given root
-     * modules, their transitive dependences, plus a set of other modules.
-     */
-    public static ModuleFinder moduleFinder(List<Path> modulepaths,
-                                            Set<String> roots,
-                                            Set<String> otherModules) {
-        return JlinkTask.newModuleFinder(modulepaths, roots, otherModules);
-    }
-}
--- a/src/jdk.jlink/windows/classes/module-info.java.extra	Wed Feb 20 14:01:37 2019 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-    exports jdk.tools.jlink.internal.packager to
-        jdk.jpackage;
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java	Mon Feb 25 08:21:37 2019 -0500
@@ -223,15 +223,6 @@
             }
         }
 
-        String version = JLinkBundlerHelper.getJDKVersion(params);
-
-        if (!version.isEmpty()) {
-            out.println("app.java.version=" + version);
-        }
-
-        out.println("jpackage.java.version="
-                + System.getProperty("java.version"));
-
         Integer port = JLinkBundlerHelper.DEBUG.fetchFrom(params);
 
         if (port != null) {
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractImageBundler.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractImageBundler.java	Mon Feb 25 08:21:37 2019 -0500
@@ -155,10 +155,6 @@
         }
         rootDirectory.mkdirs();
 
-        if (!p.containsKey(JLinkBundlerHelper.JLINK_BUILDER.getID())) {
-            p.put(JLinkBundlerHelper.JLINK_BUILDER.getID(), jlinkKey);
-        }
-
         return rootDirectory;
     }
 
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java	Mon Feb 25 08:21:37 2019 -0500
@@ -25,10 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.*;
-import jdk.jpackage.internal.BundlerType;
-import jdk.jpackage.internal.JLinkBundlerHelper;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.*;
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java	Mon Feb 25 08:21:37 2019 -0500
@@ -28,9 +28,12 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.StringReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -48,14 +51,14 @@
 import java.util.Arrays;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import java.util.regex.Matcher;
+import java.util.spi.ToolProvider;
 import java.lang.module.Configuration;
 import java.lang.module.ResolvedModule;
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReference;
 
-import jdk.tools.jlink.internal.packager.AppRuntimeImageBuilder;
-
 final class JLinkBundlerHelper {
 
     private static final ResourceBundle I18N = ResourceBundle.getBundle(
@@ -65,17 +68,10 @@
     private static final String SERVER_JRE_MODULES_FILENAME =
             "jdk/jpackage/internal/resources/jre.module.list";
 
-    private JLinkBundlerHelper() {}
+    static final ToolProvider JLINK_TOOL =
+            ToolProvider.findFirst("jlink").orElseThrow();
 
-    @SuppressWarnings("unchecked")
-    static final BundlerParamInfo<String> JLINK_BUILDER =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.jlink-builder.name"),
-                    I18N.getString("param.jlink-builder.description"),
-                    "jlink.builder",
-                    String.class,
-                    null,
-                    (s, p) -> s);
+    private JLinkBundlerHelper() {}
 
     @SuppressWarnings("unchecked")
     static final BundlerParamInfo<Integer> DEBUG =
@@ -178,62 +174,6 @@
         return result;
     }
 
-    static String getJDKVersion(Map<String, ? super Object> params) {
-        String result = "";
-        List<Path> modulePath =
-                StandardBundlerParam.MODULE_PATH.fetchFrom(params);
-        Set<String> limitModules =
-                StandardBundlerParam.LIMIT_MODULES.fetchFrom(params);
-        Path javaBasePath = findPathOfModule(modulePath,
-                "java.base.jmod").resolve("java.base.jmod");
-        Set<String> addModules = getValidModules(modulePath,
-                StandardBundlerParam.ADD_MODULES.fetchFrom(params),
-                limitModules);
-
-
-        if (javaBasePath != null && javaBasePath.toFile().exists()) {
-            result = getModuleVersion(javaBasePath.toFile(),
-                    modulePath, addModules, limitModules);
-        }
-        return result;
-    }
-
-    static Path getJDKHome(Map<String, ? super Object> params) {
-        Path result = null;
-        List<Path> modulePath =
-                StandardBundlerParam.MODULE_PATH.fetchFrom(params);
-        Path javaBasePath = findPathOfModule(modulePath, "java.base.jmod");
-
-        if (javaBasePath != null && javaBasePath.toFile().exists()) {
-            result = javaBasePath.getParent();
-
-            // On a developer build the JDK Home isn't where we expect it
-            // relative to the jmods directory. Do some extra
-            // processing to find it.
-            if (result != null) {
-                boolean found = false;
-                Path bin = result.resolve("bin");
-
-                if (Files.exists(bin)) {
-                    final String exe =
-                            (Platform.getPlatform() == Platform.WINDOWS) ?
-                            ".exe" : "";
-                    Path javaExe = bin.resolve("java" + exe);
-
-                    if (Files.exists(javaExe)) {
-                        found = true;
-                    }
-                }
-
-                if (!found) {
-                    result = result.resolve(".." + File.separator + "jdk");
-                }
-            }
-        }
-
-        return result;
-    }
-
     private static Set<String> getValidModules(List<Path> modulePath,
             Set<String> addModules, Set<String> limitModules) {
         ModuleHelper moduleHelper = new ModuleHelper(
@@ -285,19 +225,14 @@
         Log.verbose(MessageFormat.format(
                 I18N.getString("message.modules"), validModules.toString()));
 
-        AppRuntimeImageBuilder appRuntimeBuilder = new AppRuntimeImageBuilder();
-        appRuntimeBuilder.setOutputDir(outputDir);
-        appRuntimeBuilder.setModulePath(modulePath);
-        appRuntimeBuilder.setAddModules(validModules);
-        appRuntimeBuilder.setLimitModules(limitModules);
-        appRuntimeBuilder.setExcludeFileList(excludeFileList);
-        appRuntimeBuilder.setStripNativeCommands(stripNativeCommands);
-        appRuntimeBuilder.setUserArguments(new HashMap<String,String>());
+        runJLink(outputDir, modulePath, validModules, limitModules,
+                excludeFileList, stripNativeCommands,
+                new HashMap<String,String>());
 
-        appRuntimeBuilder.build();
         imageBuilder.prepareApplicationFiles();
     }
 
+
     static void generateJre(Map<String, ? super Object> params,
             AbstractAppImageBuilder imageBuilder)
             throws IOException, Exception {
@@ -318,16 +253,9 @@
         Log.verbose(MessageFormat.format(
                 I18N.getString("message.modules"), addModules.toString()));
 
-        AppRuntimeImageBuilder appRuntimeBuilder = new AppRuntimeImageBuilder();
-        appRuntimeBuilder.setOutputDir(outputDir);
-        appRuntimeBuilder.setModulePath(modulePath);
-        appRuntimeBuilder.setAddModules(addModules);
-        appRuntimeBuilder.setLimitModules(limitModules);
-        appRuntimeBuilder.setStripNativeCommands(stripNativeCommands);
-        appRuntimeBuilder.setExcludeFileList("");
-        appRuntimeBuilder.setUserArguments(new HashMap<String,String>());
+        runJLink(outputDir, modulePath, addModules, limitModules,
+                null, stripNativeCommands, new HashMap<String,String>());
 
-        appRuntimeBuilder.build();
         imageBuilder.prepareJreFiles();
     }
 
@@ -417,31 +345,6 @@
         return result;
     }
 
-    private static String getModuleVersion(File moduleFile,
-            List<Path> modulePath, Set<String> addModules,
-            Set<String> limitModules) {
-        String result = "";
-
-        ModFile modFile = new ModFile(moduleFile);
-        ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath,
-                addModules, limitModules);
-        Optional<ModuleReference> mref = finder.find(modFile.getModName());
-
-        if (mref.isPresent()) {
-            ModuleDescriptor descriptor = mref.get().descriptor();
-
-            if (descriptor != null) {
-                Optional<ModuleDescriptor.Version> version =
-                        descriptor.version();
-
-                if (version.isPresent()) {
-                    result = version.get().toString();
-                }
-            }
-        }
-        return result;
-    }
-
     private static class ModuleHelper {
         // The token for "all modules on the module path".
         private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
@@ -502,4 +405,81 @@
             return result;
         }
     }
+
+    private static void runJLink(Path output, List<Path> modulePath,
+            Set<String> modules, Set<String> limitModules, String excludes,
+            boolean strip, HashMap<String, String> user) throws IOException {
+
+        // This is just to ensure jlink is given a non-existant directory
+        // The passed in output path should be non-existant or empty directory
+        IOUtils.deleteRecursive(output.toFile());
+
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("--output");
+        args.add(output.toString());
+        if (modulePath != null && !modulePath.isEmpty()) {
+            args.add("--module-path");
+            args.add(getPathList(modulePath));
+        }
+        if (modules != null && !modules.isEmpty()) {
+            args.add("--add-modules");
+            args.add(getStringList(modules));
+        }
+        if (limitModules != null && !limitModules.isEmpty()) {
+            args.add("--limit-modules");
+            args.add(getStringList(limitModules));
+        }
+        if (excludes != null) {
+            args.add("--exclude-files");
+            args.add(excludes);
+        }
+        if (strip) {
+            args.add("--strip-native-commands");
+        }
+        for (Map.Entry<String, String> entry : user.entrySet()) {
+            args.add(entry.getKey());
+            args.add(entry.getValue());
+        }
+        args.add("--strip-debug");
+        args.add("--no-header-files");
+        args.add("--bind-services");
+        
+        StringWriter writer = new StringWriter();
+        PrintWriter pw = new PrintWriter(writer);
+
+        Log.verbose("jlink arguments: " + args);
+        int retVal = JLINK_TOOL.run(pw, pw, args.toArray(new String[0]));
+        String jlinkOut = writer.toString();
+
+        if (retVal != 0) {
+            throw new IOException("jlink failed with: " + jlinkOut);
+        } else if (jlinkOut.length() > 0) {
+            Log.verbose("jlink output: " + jlinkOut);
+        }
+    }
+
+    private static String getPathList(List<Path> pathList) {
+        String ret = null;
+        for (Path p : pathList) {
+            String s =  Matcher.quoteReplacement(p.toString());
+            if (ret == null) {
+                ret = s;
+            } else {
+                ret += File.pathSeparator +  s;
+            }
+        }
+        return ret;
+    }
+
+    private static String getStringList(Set<String> strings) {
+        String ret = null;
+        for (String s : strings) {
+            if (ret == null) {
+                ret = s;
+            } else {
+                ret += "," + s;
+            }
+        }
+        return (ret == null) ? null : Matcher.quoteReplacement(ret);
+    }
 }
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -36,7 +36,7 @@
 --------------\n\
 \    Generate a modular application image:\n\
 \        jpackage create-image --output outputdir --name AppName \\\n\
-\            --main-class package.ClassName -module moduleName -p modulePath\n\
+\            --main-class package.ClassName --module moduleName -p modulePath\n\
 \        jpackage create-image --o outputdir -n AppName \\\n\
 \            -c package.ClassName -m moduleName -p modulePath\n\
 \    Generate a non-modular application image:\n\
@@ -162,7 +162,7 @@
 \          This module must contain the main-class,\n\
 \          and be located on the module path.\n\
 \  --module-path -p <module path>\n\
-\          Path JLink looks in for modules when packaging the Java Runtime\n\
+\          Path jlink looks in for modules when packaging the Java Runtime\n\
 \          (absolute path or relative to the current directory)\n\
 \  --add-modules <module name>[,<module name>...]\n\
 \          A comma (",") separated list of modules to add.\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -36,7 +36,7 @@
 --------------\n\
 \    Generate a modular application image:\n\
 \        jpackage create-image --output outputdir --name AppName \\\n\
-\            --main-class package.ClassName -module moduleName -p modulePath\n\
+\            --main-class package.ClassName --module moduleName -p modulePath\n\
 \        jpackage create-image --o outputdir -n AppName \\\n\
 \            -c package.ClassName -m moduleName -p modulePath\n\
 \    Generate a non-modular application image:\n\
@@ -162,7 +162,7 @@
 \          This module must contain the main-class,\n\
 \          and be located on the module path.\n\
 \  --module-path -p <module path>\n\
-\          Path JLink looks in for modules when packaging the Java Runtime\n\
+\          Path jlink looks in for modules when packaging the Java Runtime\n\
 \          (absolute path or relative to the current directory)\n\
 \  --add-modules <module name>[,<module name>...]\n\
 \          A comma (",") separated list of modules to add.\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -36,7 +36,7 @@
 --------------\n\
 \    Generate a modular application image:\n\
 \        jpackage create-image --output outputdir --name AppName \\\n\
-\            --main-class package.ClassName -module moduleName -p modulePath\n\
+\            --main-class package.ClassName --module moduleName -p modulePath\n\
 \        jpackage create-image --o outputdir -n AppName \\\n\
 \            -c package.ClassName -m moduleName -p modulePath\n\
 \    Generate a non-modular application image:\n\
@@ -162,7 +162,7 @@
 \          This module must contain the main-class,\n\
 \          and be located on the module path.\n\
 \  --module-path -p <module path>\n\
-\          Path JLink looks in for modules when packaging the Java Runtime\n\
+\          Path jlink looks in for modules when packaging the Java Runtime\n\
 \          (absolute path or relative to the current directory)\n\
 \  --add-modules <module name>[,<module name>...]\n\
 \          A comma (",") separated list of modules to add.\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -34,8 +34,6 @@
 param.create-installer.description=Creates platform-specific installer for the application.
 param.create-jre-installer.name=Create JRE Installer
 param.create-jre-installer.description=Creates platform-specific JRE installer.
-param.jlink-builder.name=JLink Builder
-param.jlink-builder.description=Name of the JLink Builder to build the applicaiton image with.
 param.app-name.name=App Name
 param.app-name.description=The name of the application.
 param.app-resource.description=All of the files to place in the resources directory.  Including all needed jars as assets.
@@ -110,7 +108,7 @@
 param.source-dir.name=Source Directory
 param.source-dir.description=Path to the directory containing the files to be bundled.
 param.module-path.name=Module Path
-param.module-path.description=When packaging the Java Runtime, this is the path JLink will look in for modules.
+param.module-path.description=When packaging the Java Runtime, this is the path jlink will look in for modules.
 param.add-modules.name=Add Modules
 param.add-modules.description=List of Modules to add to JImage creation, including possible services.
 param.limit-modules.name=Limit Modules
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -34,8 +34,6 @@
 param.create-installer.description=Creates platform-specific installer for the application.
 param.create-jre-installer.name=Create JRE Installer
 param.create-jre-installer.description=Creates platform-specific JRE installer.
-param.jlink-builder.name=JLink Builder
-param.jlink-builder.description=Name of the JLink Builder to build the applicaiton image with.
 param.app-name.name=App Name
 param.app-name.description=The name of the application.
 param.app-resource.description=All of the files to place in the resources directory.  Including all needed jars as assets.
@@ -110,7 +108,7 @@
 param.source-dir.name=Source Directory
 param.source-dir.description=Path to the directory containing the files to be bundled.
 param.module-path.name=Module Path
-param.module-path.description=When packaging the Java Runtime, this is the path JLink will look in for modules.
+param.module-path.description=When packaging the Java Runtime, this is the path jlink will look in for modules.
 param.add-modules.name=Add Modules
 param.add-modules.description=List of Modules to add to JImage creation, including possible services.
 param.limit-modules.name=Limit Modules
@@ -149,7 +147,7 @@
 error.main-jar-does-not-exist=The configured main jar does not exist {0}
 error.main-jar-does-not-exist.advice=The main jar must be specified relative to the app resources (not an absolute path), and must exist within those resources.
 
-warning.module.does.not.exist=Module {0} does not exist.
+warning.module.does.not.exist=Module [{0}] does not exist.
 warning.no.jdk.modules.found=Warning: No JDK Modules found.
 warning.unsupported.option=Warning: Option [{0}] is not supported on this platform.
 warning.unsupported.mode.option=Warning: Option [{0}] is not supported in {1} mode.
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -34,8 +34,6 @@
 param.create-installer.description=Creates platform-specific installer for the application.
 param.create-jre-installer.name=Create JRE Installer
 param.create-jre-installer.description=Creates platform-specific JRE installer.
-param.jlink-builder.name=JLink Builder
-param.jlink-builder.description=Name of the JLink Builder to build the applicaiton image with.
 param.app-name.name=App Name
 param.app-name.description=The name of the application.
 param.app-resource.description=All of the files to place in the resources directory.  Including all needed jars as assets.
@@ -110,7 +108,7 @@
 param.source-dir.name=Source Directory
 param.source-dir.description=Path to the directory containing the files to be bundled.
 param.module-path.name=Module Path
-param.module-path.description=When packaging the Java Runtime, this is the path JLink will look in for modules.
+param.module-path.description=When packaging the Java Runtime, this is the path jlink will look in for modules.
 param.add-modules.name=Add Modules
 param.add-modules.description=List of Modules to add to JImage creation, including possible services.
 param.limit-modules.name=Limit Modules
@@ -149,7 +147,7 @@
 error.main-jar-does-not-exist=The configured main jar does not exist {0}
 error.main-jar-does-not-exist.advice=The main jar must be specified relative to the app resources (not an absolute path), and must exist within those resources.
 
-warning.module.does.not.exist=Module {0} does not exist.
+warning.module.does.not.exist=Module [{0}] does not exist.
 warning.no.jdk.modules.found=Warning: No JDK Modules found.
 warning.unsupported.option=Warning: Option [{0}] is not supported on this platform.
 warning.unsupported.mode.option=Warning: Option [{0}] is not supported in {1} mode.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java	Mon Feb 25 08:21:37 2019 -0500
@@ -102,23 +102,9 @@
                     I18N.getString("error.no-windows-resources.advice"));
         }
 
-        // validate runtime bit-architectire
-        testRuntimeBitArchitecture(p);
-
         return true;
     }
 
-    private static void testRuntimeBitArchitecture(
-            Map<String, ? super Object> params) throws ConfigException {
-
-        if ((BIT_ARCH_64.fetchFrom(params) !=
-                BIT_ARCH_64_RUNTIME.fetchFrom(params))) {
-            throw new ConfigException(
-                    I18N.getString("error.bit-architecture-mismatch"),
-                    I18N.getString("error.bit-architecture-mismatch.advice"));
-        }
-    }
-
     private static boolean usePredefineAppName(Map<String, ? super Object> p) {
         return (PREDEFINED_APP_IMAGE.fetchFrom(p) != null);
     }
@@ -231,36 +217,6 @@
         }
     }
 
-    private static final String RUNTIME_AUTO_DETECT = ".runtime.autodetect";
-
-    public static void extractFlagsFromRuntime(
-            Map<String, ? super Object> params) {
-        if (params.containsKey(".runtime.autodetect")) return;
-
-        params.put(RUNTIME_AUTO_DETECT, "attempted");
-
-        String commandline;
-        File runtimePath = JLinkBundlerHelper.getJDKHome(params).toFile();
-        File launcherPath = new File(runtimePath, "bin\\java.exe");
-
-        ProcessBuilder pb =
-                 new ProcessBuilder(launcherPath.getAbsolutePath(), "-version");
-        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-            try (PrintStream pout = new PrintStream(baos)) {
-                IOUtils.exec(pb, Log.isDebug(), true, pout);
-            }
-
-            commandline = baos.toString();
-        } catch (IOException e) {
-            e.printStackTrace();
-            params.put(RUNTIME_AUTO_DETECT, "failed");
-            return;
-        }
-
-        AbstractImageBundler.extractFlagsFromVersion(params, commandline);
-        params.put(RUNTIME_AUTO_DETECT, "succeeded");
-    }
-
     @Override
     public String getName() {
         return I18N.getString("app.bundler.name");
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Mon Feb 25 08:21:37 2019 -0500
@@ -540,11 +540,8 @@
             data.put("APPLICATION_INSTALL_PRIVILEGE", "lowest");
         }
 
-        if (BIT_ARCH_64.fetchFrom(p)) {
-            data.put("ARCHITECTURE_BIT_MODE", "x64");
-        } else {
-            data.put("ARCHITECTURE_BIT_MODE", "");
-        }
+        data.put("ARCHITECTURE_BIT_MODE", "x64");
+
         validateValueAndPut(data, "RUN_FILENAME", APP_NAME, p);
 
         validateValueAndPut(data, "APPLICATION_DESCRIPTION",
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Mon Feb 25 08:21:37 2019 -0500
@@ -609,13 +609,8 @@
             data.put("INSTALL_SCOPE", "perUser");
         }
 
-        if (BIT_ARCH_64.fetchFrom(params)) {
-            data.put("PLATFORM", "x64");
-            data.put("WIN64", "yes");
-        } else {
-            data.put("PLATFORM", "x86");
-            data.put("WIN64", "no");
-        }
+        data.put("PLATFORM", "x64");
+        data.put("WIN64", "yes");
 
         data.put("UI_BLOCK", getUIBlock(params));
 
@@ -748,7 +743,7 @@
         out.println(prefix + " <Component Id=\"comp" + (compId++)
                 + "\" DiskId=\"1\""
                 + " Guid=\"" + UUID.randomUUID().toString() + "\""
-                + (BIT_ARCH_64.fetchFrom(params) ? " Win64=\"yes\"" : "")
+                + " Win64=\"yes\"" 
                 + ">");
         out.println(prefix + "  <CreateFolder/>");
         out.println(prefix + "  <RemoveFolder Id=\"RemoveDir"
@@ -805,8 +800,7 @@
                     thisFileId + "\""
                     + " Name=\"" + f.getName() + "\" "
                     + " Source=\"" + relativePath(imageRootDir, f) + "\""
-                    + (BIT_ARCH_64.fetchFrom(params) ?
-                    " ProcessorArchitecture=\"x64\"" : "") + ">");
+                    + " ProcessorArchitecture=\"x64\"" + ">");
             if (doShortcuts && desktopShortcut) {
                 out.println(prefix
                         + "  <Shortcut Id=\"desktopShortcut\" Directory="
@@ -963,13 +957,8 @@
         out.println(" <Directory Id=\"TARGETDIR\" Name=\"SourceDir\">");
         if (MSI_SYSTEM_WIDE.fetchFrom(params)) {
             // install to programfiles
-            if (BIT_ARCH_64.fetchFrom(params)) {
-                out.println("  <Directory Id=\"ProgramFiles64Folder\" "
+            out.println("  <Directory Id=\"ProgramFiles64Folder\" "
                         + "Name=\"PFiles\">");
-            } else {
-                out.println("  <Directory Id=\"ProgramFilesFolder\" "
-                        + "Name=\"PFiles\">");
-            }
         } else {
             // install to user folder
             out.println(
@@ -997,7 +986,7 @@
                     + MENU_GROUP.fetchFrom(params) + "\">");
             out.println("      <Component Id=\"comp" + (compId++) + "\""
                     + " Guid=\"" + UUID.randomUUID().toString() + "\""
-                    + (BIT_ARCH_64.fetchFrom(params) ? " Win64=\"yes\"" : "")
+                    + " Win64=\"yes\""
                     + ">");
             out.println("        <RemoveFolder Id=\"ProgramMenuDir\" "
                     + "On=\"uninstall\" />");
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsBundlerParam.java	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsBundlerParam.java	Mon Feb 25 08:21:37 2019 -0500
@@ -91,29 +91,6 @@
                     (s, p) -> s
             );
 
-    static final StandardBundlerParam<Boolean> BIT_ARCH_64 =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.64-bit.name"),
-                    I18N.getString("param.64-bit.description"),
-                    "win.64Bit",
-                    Boolean.class,
-                    params -> System.getProperty("os.arch").contains("64"),
-                    (s, p) -> Boolean.valueOf(s)
-            );
-
-    static final StandardBundlerParam<Boolean> BIT_ARCH_64_RUNTIME =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.runtime-64-bit.name"),
-                    I18N.getString("param.runtime-64-bit.description"),
-                    "win.64BitJreRuntime",
-                    Boolean.class,
-                    params -> {
-                        WinAppBundler.extractFlagsFromRuntime(params);
-                        return "64".equals(params.get(".runtime.bit-arch"));
-                    },
-                    (s, p) -> Boolean.valueOf(s)
-            );
-
     static final BundlerParamInfo<Boolean> INSTALLDIR_CHOOSER =
             new StandardBundlerParam<> (
             I18N.getString("param.installdir-chooser.name"),
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -42,10 +42,6 @@
 param.menu-group.name=Menu Group
 param.menu-group.description=The Start Menu group this application should be placed in
 param.menu-group.default=Unknown
-param.64-bit.name=64-bit
-param.64-bit.description=Prepare the bundles for 64 bit windows.
-param.runtime-64-bit.name=runtime 64-bit
-param.runtime-64-bit.description=Embedded JRE runtime is 64-bit, used to detect bit architecture mismatches.
 param.installer-name.name=Installer Name
 param.installer-name.description=The filename of the generated installer without the file type extension.  Default is <App Name>-<Version>.
 param.registry-name.name=Registry Name
@@ -90,8 +86,6 @@
 error.parameters-null.advice=Pass in a non-null parameters map.
 error.no-windows-resources=This copy of the JDK does not support Windows.
 error.no-windows-resources.advice=Please use the Oracle JDK for Windows.
-error.bit-architecture-mismatch=Bit architecture mismatch between FX SDK and JRE runtime.
-error.bit-architecture-mismatch.advice=Make sure to use JRE runtime with correct bit architecture.
 error.cannot-find-launcher=Cannot find cfg file in predefined app image directory {0}.
 error.cannot-create-output-dir=Output directory {0} cannot be created.
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
@@ -114,7 +108,6 @@
 
 
 message.result-dir=Result application bundle\: {0}
-message.disable-bit-architecture-check=Disabled check for bit architecture mismatch.
 message.icon-not-ico=The specified icon "{0}" is not an ICO file and will not be used.  The default icon will be used in it's place.
 message.multiple-launchers=Multiple launchers found in predefined app-image.  {0} will be used as primary launcher.
 message.potential.windows.defender.issue=Warning: Windows Defender may prevent jpackage from functioning. If there is an issue, it can be addressed by either disabling realtime monitoring, or adding an exclusion for the directory "{0}".
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -42,10 +42,6 @@
 param.menu-group.name=Menu Group
 param.menu-group.description=The Start Menu group this application should be placed in
 param.menu-group.default=Unknown
-param.64-bit.name=64-bit
-param.64-bit.description=Prepare the bundles for 64 bit windows.
-param.runtime-64-bit.name=runtime 64-bit
-param.runtime-64-bit.description=Embedded JRE runtime is 64-bit, used to detect bit architecture mismatches.
 param.installer-name.name=Installer Name
 param.installer-name.description=The filename of the generated installer without the file type extension.  Default is <App Name>-<Version>.
 param.registry-name.name=Registry Name
@@ -90,8 +86,6 @@
 error.parameters-null.advice=Pass in a non-null parameters map.
 error.no-windows-resources=This copy of the JDK does not support Windows.
 error.no-windows-resources.advice=Please use the Oracle JDK for Windows.
-error.bit-architecture-mismatch=Bit architecture mismatch between FX SDK and JRE runtime.
-error.bit-architecture-mismatch.advice=Make sure to use JRE runtime with correct bit architecture.
 error.cannot-find-launcher=Cannot find cfg file in predefined app image directory {0}.
 error.cannot-create-output-dir=Output directory {0} cannot be created.
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
@@ -114,7 +108,6 @@
 
 
 message.result-dir=Result application bundle\: {0}
-message.disable-bit-architecture-check=Disabled check for bit architecture mismatch.
 message.icon-not-ico=The specified icon "{0}" is not an ICO file and will not be used.  The default icon will be used in it's place.
 message.multiple-launchers=Multiple launchers found in predefined app-image.  {0} will be used as primary launcher.
 message.potential.windows.defender.issue=Warning: Windows Defender may prevent jpackage from functioning. If there is an issue, it can be addressed by either disabling realtime monitoring, or adding an exclusion for the directory "{0}".
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties	Wed Feb 20 14:01:37 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties	Mon Feb 25 08:21:37 2019 -0500
@@ -42,10 +42,6 @@
 param.menu-group.name=Menu Group
 param.menu-group.description=The Start Menu group this application should be placed in
 param.menu-group.default=Unknown
-param.64-bit.name=64-bit
-param.64-bit.description=Prepare the bundles for 64 bit windows.
-param.runtime-64-bit.name=runtime 64-bit
-param.runtime-64-bit.description=Embedded JRE runtime is 64-bit, used to detect bit architecture mismatches.
 param.installer-name.name=Installer Name
 param.installer-name.description=The filename of the generated installer without the file type extension.  Default is <App Name>-<Version>.
 param.registry-name.name=Registry Name
@@ -90,8 +86,6 @@
 error.parameters-null.advice=Pass in a non-null parameters map.
 error.no-windows-resources=This copy of the JDK does not support Windows.
 error.no-windows-resources.advice=Please use the Oracle JDK for Windows.
-error.bit-architecture-mismatch=Bit architecture mismatch between FX SDK and JRE runtime.
-error.bit-architecture-mismatch.advice=Make sure to use JRE runtime with correct bit architecture.
 error.cannot-find-launcher=Cannot find cfg file in predefined app image directory {0}.
 error.cannot-create-output-dir=Output directory {0} cannot be created.
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
@@ -114,7 +108,6 @@
 
 
 message.result-dir=Result application bundle\: {0}
-message.disable-bit-architecture-check=Disabled check for bit architecture mismatch.
 message.icon-not-ico=The specified icon "{0}" is not an ICO file and will not be used.  The default icon will be used in it's place.
 message.multiple-launchers=Multiple launchers found in predefined app-image.  {0} will be used as primary launcher.
 message.potential.windows.defender.issue=Warning: Windows Defender may prevent jpackage from functioning. If there is an issue, it can be addressed by either disabling realtime monitoring, or adding an exclusion for the directory "{0}".
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/createimage/JPackageCreateImageModularJarTest.java	Mon Feb 25 08:21:37 2019 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @summary jpackage create image modular jar test
+ * @library ../helpers
+ * @build JPackageHelper
+ * @build JPackagePath
+ * @build JPackageCreateImageBase
+ * @modules jdk.jpackage
+ * @run main/othervm -Xmx512m JPackageCreateImageModularJarTest
+ */
+public class JPackageCreateImageModularJarTest {
+
+    private static final String [] CMD1 = {
+        "create-image",
+        "--input", "input",
+        "--output", "output",
+        "--name", "test",
+        "--main-jar", "com.hello.jar",
+        "--main-class", "com.hello.Hello",
+        "--files", "com.hello.jar",
+        "--overwrite"
+    };
+
+    private static final String [] CMD2 = {
+        "create-image",
+        "--output", "output",
+        "--name", "test",
+        "--module", "com.hello/com.hello.Hello",
+        "--module-path", "input/com.hello.jar",
+        "--overwrite"
+    };
+
+    public static void main(String[] args) throws Exception {
+        JPackageHelper.createHelloModule();
+
+        JPackageCreateImageBase.testCreateImage(CMD1);
+        JPackageCreateImageBase.testCreateImageToolProvider(CMD1);
+
+        JPackageCreateImageBase.testCreateImage(CMD2);
+        JPackageCreateImageBase.testCreateImageToolProvider(CMD2);
+    }
+
+}