8210439: Unable to create an installer from a previously created app image on Windows JDK-8200758-branch
authorherrick
Sat, 08 Sep 2018 09:20:34 -0400
branchJDK-8200758-branch
changeset 56882 0ec8559f599a
parent 56870 6668bbc41155
child 56883 0d9b95700522
8210439: Unable to create an installer from a previously created app image on Windows Reviewed-by: almatvee, kcr
src/jdk.packager/share/classes/jdk/packager/internal/Arguments.java
src/jdk.packager/share/classes/jdk/packager/internal/DeployParams.java
src/jdk.packager/share/classes/jdk/packager/internal/JLinkBundlerHelper.java
src/jdk.packager/share/classes/jdk/packager/internal/RelativeFileSet.java
src/jdk.packager/share/classes/jdk/packager/internal/StandardBundlerParam.java
src/jdk.packager/share/classes/jdk/packager/internal/bundlers/BundleParams.java
src/jdk.packager/windows/classes/jdk/packager/internal/windows/WinMsiBundler.java
--- a/src/jdk.packager/share/classes/jdk/packager/internal/Arguments.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/share/classes/jdk/packager/internal/Arguments.java	Sat Sep 08 09:20:34 2018 -0400
@@ -114,6 +114,7 @@
     private boolean hasMainClass = false;
     private boolean hasMainModule = false;
     private boolean hasTargetFormat = false;
+    private boolean hasAppImage = false;
 
     private String mainJarPath = null;
     
@@ -305,7 +306,10 @@
             setOptionValue("echo-mode", true);
         }),
 
-        PREDEFINED_APP_IMAGE ("app-image", OptionCategories.PROPERTY),
+        PREDEFINED_APP_IMAGE ("app-image", OptionCategories.PROPERTY, ()-> {
+            setOptionValue("app-image", popArg());
+            context().hasAppImage = true;
+        }),
         
         PREDEFINED_RUNTIME_IMAGE ("runtime-image", OptionCategories.PROPERTY),
 
@@ -536,9 +540,9 @@
                 return false;
             }
 
-            if (!hasMainJar && !hasMainModule &&
+            if (!hasAppImage && !hasMainJar && !hasMainModule &&
                     !hasMainClass && !jreInstaller) {
-                Log.info("ERROR: Main jar or main class or main module "
+                Log.info("ERROR: Main jar, main class, main module, or app-image "
                         + "must be specified.");
             } else if (!hasMainModule && !hasMainClass) {
                 // try to get main-class from manifest
--- a/src/jdk.packager/share/classes/jdk/packager/internal/DeployParams.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/share/classes/jdk/packager/internal/DeployParams.java	Sat Sep 08 09:20:34 2018 -0400
@@ -470,18 +470,6 @@
         if (outdir == null) {
             throw new PackagerException("ERR_MissingArgument", "--output");
         }
-
-        if (bundlerArguments.get(
-                Arguments.CLIOptions.MODULE.getId()) == null && !jreInstaller) {
-            if (resources.isEmpty()) {
-                throw new PackagerException("ERR_MissingAppResources");
-            }
-
-            if (bundlerArguments.get(
-                    Arguments.CLIOptions.APPCLASS.getId()) == null) {
-                throw new PackagerException("ERR_MissingArgument", "--class");
-            }
-        }
     }
 
     public boolean validateForBundle() {
@@ -571,7 +559,6 @@
             StandardBundlerParam.MODULE_PATH.getID(),
             StandardBundlerParam.ADD_MODULES.getID(),
             StandardBundlerParam.LIMIT_MODULES.getID(),
-            StandardBundlerParam.STRIP_NATIVE_COMMANDS.getID(),
             StandardBundlerParam.FILE_ASSOCIATIONS.getID(),
             JLinkBundlerHelper.DETECT_MODULES.getID()
     ));
--- a/src/jdk.packager/share/classes/jdk/packager/internal/JLinkBundlerHelper.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/share/classes/jdk/packager/internal/JLinkBundlerHelper.java	Sat Sep 08 09:20:34 2018 -0400
@@ -171,7 +171,13 @@
                 result = mainModule.substring(index + 1);
             }
         } else {
-            result = StandardBundlerParam.MAIN_CLASS.fetchFrom(params);
+            RelativeFileSet fileset =
+                    StandardBundlerParam.MAIN_JAR.fetchFrom(params);
+            if (fileset != null) {
+                result = StandardBundlerParam.MAIN_CLASS.fetchFrom(params);
+            } else {
+                // possibly app-image
+            }
         }
 
         return result;
--- a/src/jdk.packager/share/classes/jdk/packager/internal/RelativeFileSet.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/share/classes/jdk/packager/internal/RelativeFileSet.java	Sat Sep 08 09:20:34 2018 -0400
@@ -90,7 +90,7 @@
 
         for(String fname: requiredFiles) {
             if (!files.contains(fname)) {
-                Log.debug("  Runtime does not contain [" + fname + "]");
+                Log.debug("  RelativeFileSet does not contain [" + fname + "]");
                 result = false;
             }
         }
@@ -102,7 +102,7 @@
         if (files.contains(requiredFile)) {
             return true;
         } else {
-            Log.debug("  Runtime does not contain [" + requiredFile + "]");
+            Log.debug("  RelativeFileSet does not contain [" + requiredFile + "]");
             return false;
         }
     }
--- a/src/jdk.packager/share/classes/jdk/packager/internal/StandardBundlerParam.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/share/classes/jdk/packager/internal/StandardBundlerParam.java	Sat Sep 08 09:20:34 2018 -0400
@@ -790,11 +790,12 @@
         boolean hasMainJar = params.containsKey(MAIN_JAR.getID());
         boolean hasMainJarClassPath = params.containsKey(CLASSPATH.getID());
         boolean hasModule = params.containsKey(MODULE.getID());
+        boolean hasAppImage = params.containsKey(PREDEFINED_APP_IMAGE.getID());
         boolean jreInstaller =
                 params.containsKey(Arguments.CREATE_JRE_INSTALLER.getID());
 
         if (hasMainClass && hasMainJar && hasMainJarClassPath ||
-                hasModule || jreInstaller) {
+               hasModule || jreInstaller || hasAppImage) {
             return;
         }
 
--- a/src/jdk.packager/share/classes/jdk/packager/internal/bundlers/BundleParams.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/share/classes/jdk/packager/internal/bundlers/BundleParams.java	Sat Sep 08 09:20:34 2018 -0400
@@ -508,11 +508,24 @@
     //As long as main "application" entry point is the same it is main class
     // (i.e. for FX jar we will use JavaFX manifest entry ...)
     public String getMainApplicationJar() {
+        jdk.packager.internal.RelativeFileSet appResources = getAppResource();
         if (mainJar != null) {
+            if (getApplicationClass() == null) try {
+                if (appResources != null) {
+                    File srcdir = appResources.getBaseDirectory();
+                    JarFile jf = new JarFile(new File(srcdir, mainJar));
+                    Manifest m = jf.getManifest();
+                    Attributes attrs = (m != null) ? m.getMainAttributes() : null;
+                    if (attrs != null) {
+                        setApplicationClass(
+                                attrs.getValue(Attributes.Name.MAIN_CLASS));
+                    }
+                }
+            } catch (IOException ignore) {
+            }
             return mainJar;
         }
 
-        jdk.packager.internal.RelativeFileSet appResources = getAppResource();
         String applicationClass = getApplicationClass();
 
         if (appResources == null || applicationClass == null) {
--- a/src/jdk.packager/windows/classes/jdk/packager/internal/windows/WinMsiBundler.java	Mon Aug 27 16:02:55 2018 -0400
+++ b/src/jdk.packager/windows/classes/jdk/packager/internal/windows/WinMsiBundler.java	Sat Sep 08 09:20:34 2018 -0400
@@ -477,9 +477,15 @@
 
     private boolean prepareProto(Map<String, ? super Object> p)
                 throws IOException {
-        File appDir = StandardBundlerParam.getPredefinedAppImage(p);
+        File appImage = StandardBundlerParam.getPredefinedAppImage(p);
+        File appDir = null;
 
-        if (appDir == null) {
+        // we either have an application image or need to build one
+        if (appImage != null) {
+            appDir = new File(MSI_IMAGE_DIR.fetchFrom(p), APP_NAME.fetchFrom(p));
+            // copy everything from appImage dir into appDir/name
+            IOUtils.copyRecursive(appImage.toPath(), appDir.toPath());
+        } else {
             appDir = APP_BUNDLER.fetchFrom(p).doBundle(p,
                     MSI_IMAGE_DIR.fetchFrom(p), true);
         }