8215903: modify behavior of retaining temporary output dir JDK-8200758-branch
authorherrick
Mon, 07 Jan 2019 16:39:30 -0500
branchJDK-8200758-branch
changeset 57096 d06bec27f8c9
parent 57095 1e18c850b591
child 57097 6e5eb7855fe2
8215903: modify behavior of retaining temporary output dir Reviewed-by: almatvee, kcr
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.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/WinExeBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.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/JPackageCreateImageBuildRootTest.java
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -366,25 +366,6 @@
         } catch (IOException ex) {
             ex.printStackTrace();
             return null;
-        } finally {
-            try {
-                if (imageDir != null &&
-                        PREDEFINED_APP_IMAGE.fetchFrom(p) == null &&
-                        (PREDEFINED_RUNTIME_IMAGE.fetchFrom(p) == null ||
-                        !Arguments.CREATE_JRE_INSTALLER.fetchFrom(p)) &&
-                        !Log.isDebug() &&
-                        !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(imageDir);
-                } else if (imageDir != null) {
-                    Log.verbose(MessageFormat.format(I18N.getString(
-                            "message.debug-working-directory"),
-                            imageDir.getAbsolutePath()));
-                }
-            } catch (IOException ex) {
-                //noinspection ReturnInsideFinallyBlock
-                Log.debug(ex.getMessage());
-                return null;
-            }
         }
     }
 
@@ -519,7 +500,7 @@
                     secondaryLauncherData.get("APPLICATION_LAUNCHER_FILENAME"));
             installScripts.append(".desktop\n");
 
-            //postrm cleanup of desktop icon
+            // postrm cleanup of desktop icon
             removeScripts.append(
                     "        xdg-desktop-menu uninstall --novendor ");
             removeScripts.append(LINUX_INSTALL_DIR.fetchFrom(params));
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -287,25 +287,6 @@
         } catch (IOException ex) {
             ex.printStackTrace();
             return null;
-        } finally {
-            try {
-                if (imageDir != null &&
-                        PREDEFINED_APP_IMAGE.fetchFrom(p) == null &&
-                        (PREDEFINED_RUNTIME_IMAGE.fetchFrom(p) == null ||
-                        !Arguments.CREATE_JRE_INSTALLER.fetchFrom(p)) &&
-                        !Log.isDebug() &&
-                        !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(imageDir);
-                } else if (imageDir != null) {
-                    Log.verbose(MessageFormat.format(I18N.getString(
-                            "message.debug-working-directory"),
-                            imageDir.getAbsolutePath()));
-                }
-            } catch (IOException ex) {
-                // noinspection ReturnInsideFinallyBlock
-                Log.debug(ex.getMessage());
-                return null;
-            }
         }
     }
 
@@ -668,10 +649,6 @@
         pb = pb.directory(RPM_IMAGE_DIR.fetchFrom(params));
         IOUtils.exec(pb, false);
 
-        if (!Log.isDebug() && !Log.isVerbose()) {
-            IOUtils.deleteRecursive(broot);
-        }
-
         Log.verbose(MessageFormat.format(
                 I18N.getString("message.output-bundle-location"),
                 outdir.getAbsolutePath()));
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -102,7 +102,6 @@
 
 message.icon-not-png=The specified icon "{0}" is not a PNG file and will not be used.  The default icon will be used in it's place.
 message.test-for-tool=Test for [{0}]. Result\: {1}
-message.debug-working-directory=Kept working directory for debug\: {0}
 message.outputting-to-location=Generating DEB for installer to\: {0}
 message.output-to-location=Package (.deb) saved to\: {0}
 message.debs-like-licenses=Debian packages should specify a license.  The absence of a license will cause some linux distributions to complain about the quality of the application.
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -102,7 +102,6 @@
 
 message.icon-not-png=The specified icon "{0}" is not a PNG file and will not be used.  The default icon will be used in it's place.
 message.test-for-tool=Test for [{0}]. Result\: {1}
-message.debug-working-directory=Kept working directory for debug\: {0}
 message.outputting-to-location=Generating DEB for installer to\: {0}
 message.output-to-location=Package (.deb) saved to\: {0}
 message.debs-like-licenses=Debian packages should specify a license.  The absence of a license will cause some linux distributions to complain about the quality of the application.
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -102,7 +102,6 @@
 
 message.icon-not-png=The specified icon "{0}" is not a PNG file and will not be used.  The default icon will be used in it's place.
 message.test-for-tool=Test for [{0}]. Result\: {1}
-message.debug-working-directory=Kept working directory for debug\: {0}
 message.outputting-to-location=Generating DEB for installer to\: {0}
 message.output-to-location=Package (.deb) saved to\: {0}
 message.debs-like-licenses=Debian packages should specify a license.  The absence of a license will cause some linux distributions to complain about the quality of the application.
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -143,20 +143,6 @@
                     },
                     (s, p) -> s);
 
-    public static final BundlerParamInfo<File> CONFIG_ROOT =
-            new StandardBundlerParam<>(
-            I18N.getString("param.config-root.name"),
-            I18N.getString("param.config-root.description"),
-            "configRoot",
-            File.class,
-            params -> {
-                File configRoot =
-                        new File(BUILD_ROOT.fetchFrom(params), "macosx");
-                configRoot.mkdirs();
-                return configRoot;
-            },
-            (s, p) -> new File(s));
-
     public static final BundlerParamInfo<String> DEFAULT_ICNS_ICON =
             new StandardBundlerParam<>(
             I18N.getString("param.default-icon-icns"),
@@ -318,15 +304,6 @@
         return true;
     }
 
-    private File getConfig_InfoPlist(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params), "Info.plist");
-    }
-
-    private File getConfig_Icon(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params),
-                APP_NAME.fetchFrom(params) + ".icns");
-    }
-
     File doBundle(Map<String, ? super Object> p, File outputDirectory,
             boolean dependentTask) {
         if (Arguments.CREATE_JRE_INSTALLER.fetchFrom(p)) {
@@ -377,17 +354,6 @@
         }
     }
 
-    public void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        if (CONFIG_ROOT.fetchFrom(params) != null) {
-            getConfig_Icon(params).delete();
-            getConfig_InfoPlist(params).delete();
-        }
-    }
-
     /////////////////////////////////////////////////////////////////////////
     // Implement Bundler
     /////////////////////////////////////////////////////////////////////////
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java	Mon Jan 07 16:39:30 2019 -0500
@@ -39,6 +39,7 @@
 import java.math.BigInteger;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.PosixFilePermission;
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -139,20 +140,6 @@
                     },
                     (s, p) -> s);
 
-    public static final BundlerParamInfo<File> CONFIG_ROOT =
-            new StandardBundlerParam<>(
-            I18N.getString("param.config-root.name"),
-            I18N.getString("param.config-root.description"),
-            "configRoot",
-            File.class,
-            params -> {
-                File configRoot =
-                        new File(BUILD_ROOT.fetchFrom(params), "macosx");
-                configRoot.mkdirs();
-                return configRoot;
-            },
-            (s, p) -> new File(s));
-
     public static final BundlerParamInfo<String> DEFAULT_ICNS_ICON =
             new StandardBundlerParam<>(
             I18N.getString("param.default-icon-icns"),
@@ -371,6 +358,7 @@
 
         /*********** Take care of "config" files *******/
         File icon = ICON_ICNS.fetchFrom(params);
+
         InputStream in = locateResource(
                 APP_NAME.fetchFrom(params) + ".icns",
                 "icon",
@@ -379,7 +367,8 @@
                 VERBOSE.fetchFrom(params),
                 RESOURCE_DIR.fetchFrom(params));
         Files.copy(in,
-                resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns"));
+                resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns"),
+                StandardCopyOption.REPLACE_EXISTING);
 
         // copy file association icons
         for (Map<String, ?
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -206,44 +206,6 @@
             Log.error("App Store Ready Bundle failed : " + ex.getMessage());
             Log.verbose(ex);
             return null;
-        } finally {
-            try {
-                if (appImageDir != null &&
-                       PREDEFINED_APP_IMAGE.fetchFrom(p) == null &&
-                       (PREDEFINED_RUNTIME_IMAGE.fetchFrom(p) == null ||
-                       !Arguments.CREATE_JRE_INSTALLER.fetchFrom(p)) &&
-                       !Log.isDebug() &&
-                       !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(appImageDir);
-                } else if (appImageDir != null) {
-                    Log.verbose(MessageFormat.format(I18N.getString(
-                            "mesasge.intermediate-bundle-location"),
-                            appImageDir.getAbsolutePath()));
-                }
-
-                //cleanup
-                cleanupConfigFiles(p);
-            } catch (IOException ex) {
-                //noinspection ReturnInsideFinallyBlock
-                Log.debug(ex.getMessage());
-                return null;
-            }
-        }
-    }
-
-    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        if (getConfig_Entitlements(params) != null) {
-            getConfig_Entitlements(params).delete();
-        }
-        if (getConfig_Inherit_Entitlements(params) != null) {
-            getConfig_Inherit_Entitlements(params).delete();
-        }
-        if (PREDEFINED_APP_IMAGE.fetchFrom(params) == null) {
-            APP_BUNDLER.fetchFrom(params).cleanupConfigFiles(params);
         }
     }
 
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -86,55 +86,9 @@
         } catch (IOException ex) {
             Log.verbose(ex);
             return null;
-        } finally {
-            try {
-                if (appImageDir != null &&
-                        PREDEFINED_APP_IMAGE.fetchFrom(params) == null &&
-                        (PREDEFINED_RUNTIME_IMAGE.fetchFrom(params) == null ||
-                        !Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) &&
-                        !Log.isDebug() &&
-                        !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(appImageDir);
-                } else if (appImageDir != null) {
-                    Log.verbose(MessageFormat.format(I18N.getString(
-                            "message.intermediate-image-location"),
-                            appImageDir.getAbsolutePath()));
-                }
-
-                //cleanup
-                cleanupConfigFiles(params);
-            } catch (IOException ex) {
-                Log.debug(ex);
-                //noinspection ReturnInsideFinallyBlock
-                return null;
-            }
         }
     }
 
-    //remove
-    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        if (getConfig_VolumeBackground(params) != null) {
-            getConfig_VolumeBackground(params).delete();
-        }
-        if (getConfig_VolumeIcon(params) != null) {
-            getConfig_VolumeIcon(params).delete();
-        }
-        if (getConfig_VolumeScript(params) != null) {
-            getConfig_VolumeScript(params).delete();
-        }
-        if (getConfig_Script(params) != null) {
-            getConfig_Script(params).delete();
-        }
-        if (getConfig_LicenseFile(params) != null) {
-            getConfig_LicenseFile(params).delete();
-        }
-        APP_BUNDLER.fetchFrom(params).cleanupConfigFiles(params);
-    }
-
     private static final String hdiutil = "/usr/bin/hdiutil";
 
     private void prepareDMGSetupScript(String volumeName,
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -173,28 +173,6 @@
         } catch (IOException ex) {
             Log.verbose(ex);
             return null;
-        } finally {
-            try {
-                if (appImageDir != null &&
-                        PREDEFINED_APP_IMAGE.fetchFrom(params) == null &&
-                        (PREDEFINED_RUNTIME_IMAGE.fetchFrom(params) == null ||
-                        !Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) &&
-                        !Log.isDebug() &&
-                        !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(appImageDir);
-                } else if (appImageDir != null) {
-                    Log.verbose(MessageFormat.format(I18N.getString(
-                            "message.intermediate-image-location"),
-                            appImageDir.getAbsolutePath()));
-                }
-
-                // cleanup
-                cleanupConfigFiles(params);
-            } catch (IOException ex) {
-                Log.debug(ex);
-                // noinspection ReturnInsideFinallyBlock
-                return null;
-            }
         }
     }
 
@@ -208,19 +186,6 @@
                 APP_FS_NAME.fetchFrom(params) + "-daemon.pkg");
     }
 
-    private void cleanupPackagesFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        if (getPackages_AppPackage(params) != null) {
-            getPackages_AppPackage(params).delete();
-        }
-        if (getPackages_DaemonPackage(params) != null) {
-            getPackages_DaemonPackage(params).delete();
-        }
-    }
-
     private File getConfig_DistributionXMLFile(
             Map<String, ? super Object> params) {
         return new File(CONFIG_ROOT.fetchFrom(params), "distribution.dist");
@@ -240,19 +205,6 @@
         return new File(SCRIPTS_DIR.fetchFrom(params), "postinstall");
     }
 
-    private void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        if (getConfig_DistributionXMLFile(params) != null) {
-            getConfig_DistributionXMLFile(params).delete();
-        }
-        if (getConfig_BackgroundImage(params) != null) {
-            getConfig_BackgroundImage(params).delete();
-        }
-    }
-
     private String getAppIdentifier(Map<String, ? super Object> params) {
         return IDENTIFIER.fetchFrom(params);
     }
@@ -452,9 +404,6 @@
         } catch (Exception ignored) {
             Log.verbose(ignored);
             return null;
-        } finally {
-            cleanupPackagesFiles(params);
-            cleanupConfigFiles(params);
         }
     }
 
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -187,10 +187,8 @@
     @Override
     public void cleanup(Map<String, ? super Object> params) {
         try {
-            if (!Log.isDebug() && !Log.isVerbose()) {
-                IOUtils.deleteRecursive(
-                        StandardBundlerParam.BUILD_ROOT.fetchFrom(params));
-            }
+            IOUtils.deleteRecursive(
+                    StandardBundlerParam.BUILD_ROOT.fetchFrom(params));
         } catch (IOException e) {
             Log.debug(e.getMessage());
         }
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java	Mon Jan 07 16:39:30 2019 -0500
@@ -125,7 +125,9 @@
     private boolean hasMainModule = false;
     private boolean hasTargetFormat = false;
     private boolean hasAppImage = false;
+    private boolean retainBuildRoot = false;
 
+    private String buildRoot = null; 
     private String mainJarPath = null;
 
     private static boolean jreInstaller = false;
@@ -310,7 +312,11 @@
                 new SecondaryLauncherArguments(popArg()));
         }),
 
-        BUILD_ROOT ("build-root", OptionCategories.PROPERTY),
+        BUILD_ROOT ("build-root", OptionCategories.PROPERTY, () -> {
+            context().buildRoot = popArg();
+            context().retainBuildRoot = true;
+            setOptionValue("build-root", context().buildRoot);
+        }),
 
         INSTALL_DIR ("install-dir", OptionCategories.PROPERTY),
 
@@ -718,6 +724,7 @@
     private boolean generateBundle(Map<String,? super Object> params)
             throws PackagerException {
         boolean bundleCreated = false;
+        File imageDir = null;
 
         for (jdk.jpackage.internal.Bundler bundler : getPlatformBundlers()) {
             Map<String, ? super Object> localParams = new HashMap<>(params);
@@ -725,12 +732,14 @@
                 if (bundler.validate(localParams)) {
                     File result =
                             bundler.execute(localParams, deployParams.outdir);
-                    bundler.cleanup(localParams);
+                    if (!retainBuildRoot) {
+                        bundler.cleanup(localParams);
+                    }
                     if (result == null) {
                         throw new PackagerException("MSG_BundlerFailed",
                                 bundler.getID(), bundler.getName());
                     }
-                    bundleCreated = true; // Set that at least one bundle was created
+                    bundleCreated = true; // at least one bundle was created
                 }
             } catch (UnsupportedPlatformException e) {
                 Log.debug(MessageFormat.format(
@@ -752,6 +761,12 @@
                         I18N.getString("MSG_BundlerRuntimeException"),
                         bundler.getName(), re.toString()));
                 Log.debug(re);
+            } finally {
+                if (retainBuildRoot) {
+                    Log.verbose(MessageFormat.format(
+                            I18N.getString("message.debug-working-directory"),
+                            (new File(buildRoot)).getAbsolutePath()));
+                }
             }
         }
 
@@ -769,7 +784,7 @@
 
         if (!baseDir.isDirectory()) {
             Log.error(
-                    "Unable to add resources: \"-srcdir\" is not a directory.");
+                    "Unable to add resources: \"--input\" is not a directory.");
             return;
         }
 
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java	Mon Jan 07 16:39:30 2019 -0500
@@ -302,18 +302,21 @@
         for (int i = 0; i < s.length(); i++) {
             char a = s.charAt(i);
             // We check for ASCII codes first which we accept. If check fails,
-            // then check if it is acceptable extended ASCII or unicode character.
+            // check if it is acceptable extended ASCII or unicode character.
             if (a < ' ' || a > '~' || a == '%') {
                 // Reject '%', whitespaces and ISO Control.
-                // Accept anything else including special characters like copyright
+                // Accept anything else including special chars like copyright
                 // symbols. Note: space will be included by ASCII check above,
                 // but other whitespace like tabs or new line will be ignored.
-                if (Character.isISOControl(a) || Character.isWhitespace(a) || a == '%') {
-                    throw new PackagerException("ERR_InvalidCharacterInArgument", "--name");
+                if (Character.isISOControl(a) ||
+                        Character.isWhitespace(a) || a == '%') {
+                    throw new PackagerException(
+                            "ERR_InvalidCharacterInArgument", "--name");
                 }
             }
             if (a == '"') {
-                throw new PackagerException("ERR_InvalidCharacterInArgument", "--name");
+                throw new PackagerException(
+                        "ERR_InvalidCharacterInArgument", "--name");
             }
         }
     }
@@ -349,7 +352,8 @@
                 }
             } else {
                 if (!hasInput) {
-                    throw new PackagerException("ERR_MissingArgument", "--input");
+                    throw new PackagerException(
+                           "ERR_MissingArgument", "--input");
                 }
             }
         } else if (getBundleType() == BundlerType.INSTALLER) {
@@ -361,7 +365,8 @@
                     }
                 } else {
                     if (!hasInput && !hasAppImage) {
-                        throw new PackagerException("ERR_MissingArgument", "--input or --app-image");
+                        throw new PackagerException("ERR_MissingArgument",
+                                "--input or --app-image");
                     }
                 }
             }
@@ -382,7 +387,8 @@
             }
         }
 
-        String name = (String)bundlerArguments.get(Arguments.CLIOptions.NAME.getId());
+        String name = (String)bundlerArguments.get(
+                Arguments.CLIOptions.NAME.getId());
         validateAppName(name);
 
         // Validate app image if set
@@ -402,6 +408,17 @@
             }
         }
 
+        // Validate build-root
+        String root = (String)bundlerArguments.get(
+                Arguments.CLIOptions.BUILD_ROOT.getId());
+        if (root != null) {
+            String [] contents = (new File(root)).list();
+
+            if (contents != null && contents.length > 0) {
+                throw new PackagerException("ERR_BuildRootInvalid", root);
+            }
+        }
+
         // Validate license file if set
         String license = (String)bundlerArguments.get(
                 Arguments.CLIOptions.LICENSE_FILE.getId());
@@ -490,8 +507,7 @@
     BundleParams getBundleParams() {
         BundleParams bundleParams = new BundleParams();
 
-        //construct app resources
-        //  relative to output folder!
+        // construct app resources relative to output folder!
         String currentOS = System.getProperty("os.name").toLowerCase();
         String currentArch = getArch();
 
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -123,8 +123,10 @@
 \          "win-shortcut", and "win-console" can be used to describe\n\
 \          the secondary launcher.\n\
 \  --build-root <file path>\n\
-\          Path of the directory used to create temporary files\n\
+\          Path of a new or empty directory used to create temporary files\n\
 \          (absolute path or relative to the current directory)\n\
+\          If not specified, a temporary directory will be created and\n\
+\          removed upon the task completion.\n\
 \  --runtime-image <file path>\n\
 \          Path of the predefined runtime image that is used to build\n\
 \          an application image and installable package\n\
@@ -148,7 +150,8 @@
 \          Category or group of the application\n\
 \  --vendor <vendor string>\n\
 \          Vendor of the application\n\
-\  --force Allow the deletion of any existing output root directory\n\
+\  --force\n\
+\          Allow the deletion of any existing output root directory\n\
 \          when creating an Application image\n\
 \  --resource-dir <path>\n\
 \          Path to override jpackage resources\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -123,8 +123,10 @@
 \          "win-shortcut", and "win-console" can be used to describe\n\
 \          the secondary launcher.\n\
 \  --build-root <file path>\n\
-\          Path of the directory used to create temporary files\n\
+\          Path of a new or empty directory used to create temporary files\n\
 \          (absolute path or relative to the current directory)\n\
+\          If not specified, a temporary directory will be created and\n\
+\          removed upon the task completion.\n\
 \  --runtime-image <file path>\n\
 \          Path of the predefined runtime image that is used to build\n\
 \          an application image and installable package\n\
@@ -148,7 +150,8 @@
 \          Category or group of the application\n\
 \  --vendor <vendor string>\n\
 \          Vendor of the application\n\
-\  --force Allow the deletion of any existing output root directory\n\
+\  --force\n\
+\          Allow the deletion of any existing output root directory\n\
 \          when creating an Application image\n\
 \  --resource-dir <path>\n\
 \          Path to override jpackage resources\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -123,8 +123,10 @@
 \          "win-shortcut", and "win-console" can be used to describe\n\
 \          the secondary launcher.\n\
 \  --build-root <file path>\n\
-\          Path of the directory used to create temporary files\n\
+\          Path of a new or empty directory used to create temporary files\n\
 \          (absolute path or relative to the current directory)\n\
+\          If not specified, a temporary directory will be created and\n\
+\          removed upon the task completion.\n\
 \  --runtime-image <file path>\n\
 \          Path of the predefined runtime image that is used to build\n\
 \          an application image and installable package\n\
@@ -148,7 +150,8 @@
 \          Category or group of the application\n\
 \  --vendor <vendor string>\n\
 \          Vendor of the application\n\
-\  --force Allow the deletion of any existing output root directory\n\
+\  --force\n\
+\          Allow the deletion of any existing output root directory\n\
 \          when creating an Application image\n\
 \  --resource-dir <path>\n\
 \          Path to override jpackage resources\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -135,6 +135,7 @@
 message.app-image-dir-does-not-exist.advice=Confirm that the value for {0} exists
 message.runtime-image-dir-does-not-exist=Specified runtime image directory {0}\: {1} does not exists
 message.runtime-image-dir-does-not-exist.advice=Confirm that the value for {0} exists
+message.debug-working-directory=Kept working directory for debug\: {0}
 
 error.cannot-create-output-dir=Output directory {0} cannot be created.
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
@@ -172,3 +173,4 @@
 ERR_NoJreInstallerName=Jre Installers require a name parameter.
 ERR_InvalidCharacterInArgument=Error: Invalid character found in {0} argument
 ERR_LicenseFileNotExit=Error: Specified license file does not exist.
+ERR_BuildRootInvalid=Error: build-root ({0}) must be empty directory.
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -135,6 +135,7 @@
 message.app-image-dir-does-not-exist.advice=Confirm that the value for {0} exists
 message.runtime-image-dir-does-not-exist=Specified runtime image directory {0}\: {1} does not exists
 message.runtime-image-dir-does-not-exist.advice=Confirm that the value for {0} exists
+message.debug-working-directory=Kept working directory for debug\: {0}
 
 error.cannot-create-output-dir=Output directory {0} cannot be created.
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
@@ -172,3 +173,4 @@
 ERR_NoJreInstallerName=Jre Installers require a name parameter.
 ERR_InvalidCharacterInArgument=Error: Invalid character found in {0} argument
 ERR_LicenseFileNotExit=Error: Specified license file does not exist.
+ERR_BuildRootInvalid=Error: build-root ({0}) must be empty directory.
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -135,6 +135,7 @@
 message.app-image-dir-does-not-exist.advice=Confirm that the value for {0} exists
 message.runtime-image-dir-does-not-exist=Specified runtime image directory {0}\: {1} does not exists
 message.runtime-image-dir-does-not-exist.advice=Confirm that the value for {0} exists
+message.debug-working-directory=Kept working directory for debug\: {0}
 
 error.cannot-create-output-dir=Output directory {0} cannot be created.
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
@@ -172,3 +173,4 @@
 ERR_NoJreInstallerName=Jre Installers require a name parameter.
 ERR_InvalidCharacterInArgument=Error: Invalid character found in {0} argument
 ERR_LicenseFileNotExit=Error: Specified license file does not exist.
+ERR_BuildRootInvalid=Error: build-root ({0}) must be empty directory.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -449,25 +449,6 @@
         } catch (IOException ex) {
             ex.printStackTrace();
             return null;
-        } finally {
-            try {
-                if (imageDir != null &&
-                        PREDEFINED_APP_IMAGE.fetchFrom(p) == null &&
-                        (PREDEFINED_RUNTIME_IMAGE.fetchFrom(p) == null ||
-                        !Arguments.CREATE_JRE_INSTALLER.fetchFrom(p)) &&
-                        !Log.isDebug() &&
-                        !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(imageDir);
-                } else if (imageDir != null) {
-                    Log.verbose(MessageFormat.format(
-                            I18N.getString("message.debug-working-directory"),
-                            imageDir.getAbsolutePath()));
-                }
-            } catch (IOException ex) {
-                // noinspection ReturnInsideFinallyBlock
-                Log.debug(ex.getMessage());
-                return null;
-            }
         }
     }
 
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Mon Jan 07 16:39:30 2019 -0500
@@ -549,40 +549,6 @@
         } catch (IOException ex) {
             Log.verbose(ex);
             return null;
-        } finally {
-            try {
-                if (imageDir != null &&
-                        PREDEFINED_APP_IMAGE.fetchFrom(p) == null &&
-                        (PREDEFINED_RUNTIME_IMAGE.fetchFrom(p) == null ||
-                        !Arguments.CREATE_JRE_INSTALLER.fetchFrom(p)) &&
-                        !Log.isDebug() &&
-                        !Log.isVerbose()) {
-                    IOUtils.deleteRecursive(imageDir);
-                } else if (imageDir != null) {
-                    Log.verbose(MessageFormat.format(
-                            I18N.getString("message.debug-working-directory"),
-                            imageDir.getAbsolutePath()));
-                }
-
-                cleanupConfigFiles(p);
-            } catch (IOException ex) {
-                // noinspection ReturnInsideFinallyBlock
-                Log.debug(ex.getMessage());
-                return null;
-            }
-        }
-    }
-
-    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        if (getConfig_ProjectFile(params) != null) {
-            getConfig_ProjectFile(params).delete();
-        }
-        if (getConfig_Script(params) != null) {
-            getConfig_Script(params).delete();
         }
     }
 
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java	Mon Jan 07 16:39:30 2019 -0500
@@ -38,6 +38,7 @@
 import java.io.FileWriter;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.PosixFilePermission;
 import java.text.MessageFormat;
 import java.util.HashMap;
@@ -231,15 +232,6 @@
         return CONFIG_ROOT.fetchFrom(params);
     }
 
-    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (Log.isDebug() || Log.isVerbose()) {
-            return;
-        }
-
-        getConfig_AppIcon(params).delete();
-        getConfig_ExecutableProperties(params).delete();
-    }
-
     @Override
     public Path getAppDir() {
         return appDir;
@@ -263,30 +255,26 @@
                     I18N.getString("error.cannot-write-to-output-dir"),
                     rootFile.getAbsolutePath()));
         }
-        try {
-            // create the .exe launchers
-            createLauncherForEntryPoint(params);
+        // create the .exe launchers
+        createLauncherForEntryPoint(params);
 
-            // copy the jars
-            copyApplication(params);
-
-            // copy in the needed libraries
-            try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
-                Files.copy(is_lib, root.resolve(LIBRARY_NAME));
-            }
+        // copy the jars
+        copyApplication(params);
 
-            copyMSVCDLLs();
+        // copy in the needed libraries
+        try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
+            Files.copy(is_lib, root.resolve(LIBRARY_NAME));
+        }
+
+        copyMSVCDLLs();
 
-            // create the secondary launchers, if any
-            List<Map<String, ? super Object>> entryPoints =
-                    StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params);
-            for (Map<String, ? super Object> entryPoint : entryPoints) {
-                Map<String, ? super Object> tmp = new HashMap<>(originalParams);
-                tmp.putAll(entryPoint);
-                createLauncherForEntryPoint(tmp);
-            }
-        } finally {
-            cleanupConfigFiles(params);
+        // create the secondary launchers, if any
+        List<Map<String, ? super Object>> entryPoints =
+                StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params);
+        for (Map<String, ? super Object> entryPoint : entryPoints) {
+        Map<String, ? super Object> tmp = new HashMap<>(originalParams);
+            tmp.putAll(entryPoint);
+            createLauncherForEntryPoint(tmp);
         }
     }
 
@@ -393,7 +381,9 @@
                 icon,
                 VERBOSE.fetchFrom(params),
                 RESOURCE_DIR.fetchFrom(params));
-        Files.copy(in, iconTarget.toPath());
+
+        Files.copy(in, iconTarget.toPath(),
+                StandardCopyOption.REPLACE_EXISTING);
 
         writeCfgFile(p, root.resolve(
                 getLauncherCfgName(p)).toFile(), "$APPDIR\\runtime");
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -121,7 +121,6 @@
 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}".
 message.tool-wrong-version=Detected [{0}] version {1} but version {2} is required.
-message.debug-working-directory=Kept working directory for debug\: {0}
 message.outputting-to-location=Generating EXE for installer to\: {0}
 message.output-location=Installer (.exe) saved to\: {0}
 message.tool-version=\  Detected [{0}] version [{1}]
@@ -130,7 +129,6 @@
 message.iscc-file-string=\  InnoSetup compiler set to {0}
 message.creating-association-with-null-extension=Creating association with null extension.
 message.wrong-tool-version=Detected [{0}] version {1} but version {2} is required.
-message.use-wix36-features=WiX 3.6 detected. Enabling advanced cleanup action.
 message.version-string-too-many-components=Version sting may have up to 3 components - major.minor.build .
 message.truncating.id=Truncating Application ID to 126 chars for Inno Setup.
 message.use-wix36-features=WiX 3.6 detected. Enabling advanced cleanup action.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -121,7 +121,6 @@
 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}".
 message.tool-wrong-version=Detected [{0}] version {1} but version {2} is required.
-message.debug-working-directory=Kept working directory for debug\: {0}
 message.outputting-to-location=Generating EXE for installer to\: {0}
 message.output-location=Installer (.exe) saved to\: {0}
 message.tool-version=\  Detected [{0}] version [{1}]
@@ -130,7 +129,6 @@
 message.iscc-file-string=\  InnoSetup compiler set to {0}
 message.creating-association-with-null-extension=Creating association with null extension.
 message.wrong-tool-version=Detected [{0}] version {1} but version {2} is required.
-message.use-wix36-features=WiX 3.6 detected. Enabling advanced cleanup action.
 message.version-string-too-many-components=Version sting may have up to 3 components - major.minor.build .
 message.truncating.id=Truncating Application ID to 126 chars for Inno Setup.
 message.use-wix36-features=WiX 3.6 detected. Enabling advanced cleanup action.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties	Sun Jan 06 16:58:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties	Mon Jan 07 16:39:30 2019 -0500
@@ -121,7 +121,6 @@
 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}".
 message.tool-wrong-version=Detected [{0}] version {1} but version {2} is required.
-message.debug-working-directory=Kept working directory for debug\: {0}
 message.outputting-to-location=Generating EXE for installer to\: {0}
 message.output-location=Installer (.exe) saved to\: {0}
 message.tool-version=\  Detected [{0}] version [{1}]
@@ -130,7 +129,6 @@
 message.iscc-file-string=\  InnoSetup compiler set to {0}
 message.creating-association-with-null-extension=Creating association with null extension.
 message.wrong-tool-version=Detected [{0}] version {1} but version {2} is required.
-message.use-wix36-features=WiX 3.6 detected. Enabling advanced cleanup action.
 message.version-string-too-many-components=Version sting may have up to 3 components - major.minor.build .
 message.truncating.id=Truncating Application ID to 126 chars for Inno Setup.
 message.use-wix36-features=WiX 3.6 detected. Enabling advanced cleanup action.
--- a/test/jdk/tools/jpackage/createimage/JPackageCreateImageBuildRootTest.java	Sun Jan 06 16:58:28 2019 -0500
+++ b/test/jdk/tools/jpackage/createimage/JPackageCreateImageBuildRootTest.java	Mon Jan 07 16:39:30 2019 -0500
@@ -46,10 +46,9 @@
         "--main-jar", "hello.jar",
         "--class", "Hello",
         "--files", "hello.jar",
-        "--force",
-        "--build-root", "TBD"};
+        "--force" };
 
-    private static final String [] CMD_VERBOSE = {
+    private static final String [] CMD_BUILD_ROOT = {
         "create-image",
         "--input", "input",
         "--output", "output",
@@ -58,12 +57,11 @@
         "--class", "Hello",
         "--files", "hello.jar",
         "--force",
-        "--verbose",
         "--build-root", "TBD"};
 
-    private static void validate(boolean verbose) throws Exception {
+    private static void validate(boolean retain) throws Exception {
         File br = new File(buildRoot);
-        if (verbose) {
+        if (retain) {
             if (!br.exists()) {
                 throw new AssertionError(br.getAbsolutePath() + " does not exist");
             }
@@ -81,15 +79,14 @@
             buildRoot = BUILD_ROOT;
         }
 
-        CMD[CMD.length - 1] = buildRoot;
-        CMD_VERBOSE[CMD_VERBOSE.length - 1] = buildRoot;
+        CMD_BUILD_ROOT[CMD_BUILD_ROOT.length - 1] = buildRoot;
     }
 
     private static void testBuildRoot() throws Exception {
         init(false);
         JPackageHelper.executeCLI(true, CMD);
         validate(false);
-        JPackageHelper.executeCLI(true, CMD_VERBOSE);
+        JPackageHelper.executeCLI(true, CMD_BUILD_ROOT);
         validate(true);
     }
 
@@ -97,7 +94,7 @@
         init(true);
         JPackageHelper.executeToolProvider(true, CMD);
         validate(false);
-        JPackageHelper.executeToolProvider(true, CMD_VERBOSE);
+        JPackageHelper.executeToolProvider(true, CMD_BUILD_ROOT);
         validate(true);
     }