8214495: Change behavior of --license-file JDK-8200758-branch
authorherrick
Tue, 18 Dec 2018 19:31:20 -0500
branchJDK-8200758-branch
changeset 57080 bd4ce7f9ea2c
parent 57079 c53a2eca0f57
child 57091 06bc4bd64599
8214495: Change behavior of --license-file Submitten-by: almatvee Reviewed-by: herrick. 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/MacDmgBundler.java
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties
src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.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/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
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java	Tue Dec 18 19:31:20 2018 -0500
@@ -177,20 +177,9 @@
             String.class,
             params -> {
                 try {
-                    List<String> licenseFiles = LICENSE_FILE.fetchFrom(params);
-
-                    //need to copy license file to the root of linux-app.image
-                    if (licenseFiles.size() > 0) {
-                        String licFileStr = licenseFiles.get(0);
-
-                        for (RelativeFileSet rfs :
-                                APP_RESOURCES_LIST.fetchFrom(params)) {
-                            if (rfs.contains(licFileStr)) {
-                                return new String(Files.readAllBytes((
-                                        new File(rfs.getBaseDirectory(),
-                                        licFileStr)).toPath()));
-                            }
-                        }
+                    String licenseFile = LICENSE_FILE.fetchFrom(params);
+                    if (licenseFile != null) {
+                        return Files.readString(new File(licenseFile).toPath());
                     }
                 } catch (Exception e) {
                     if (Log.isDebug()) {
@@ -283,24 +272,9 @@
             }
 
 
-            // validate license file, if used, exists in the proper place
-            if (p.containsKey(LICENSE_FILE.getID())) {
-                List<RelativeFileSet> appResourcesList =
-                        APP_RESOURCES_LIST.fetchFrom(p);
-                for (String license : LICENSE_FILE.fetchFrom(p)) {
-                    boolean found = false;
-                    for (RelativeFileSet appResources : appResourcesList) {
-                        found = found || appResources.contains(license);
-                    }
-                    if (!found) {
-                        throw new ConfigException(
-                                I18N.getString("error.license-missing"),
-                                MessageFormat.format(I18N.getString(
-                                        "error.license-missing.advice"),
-                                        license));
-                    }
-                }
-            } else {
+            // Show warning is license file is missing
+            String licenseFile = LICENSE_FILE.fetchFrom(p);
+            if (licenseFile == null) {
                 Log.verbose(I18N.getString("message.debs-like-licenses"));
             }
 
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java	Tue Dec 18 19:31:20 2018 -0500
@@ -204,25 +204,6 @@
             // we are not interested in return code, only possible exception
             APP_BUNDLER.fetchFrom(p).validate(p);
 
-            // validate license file, if used, exists in the proper place
-            if (p.containsKey(LICENSE_FILE.getID())) {
-                List<RelativeFileSet> appResourcesList =
-                        APP_RESOURCES_LIST.fetchFrom(p);
-                for (String license : LICENSE_FILE.fetchFrom(p)) {
-                    boolean found = false;
-                    for (RelativeFileSet appResources : appResourcesList) {
-                        found = found || appResources.contains(license);
-                    }
-                    if (!found) {
-                        throw new ConfigException(
-                                I18N.getString("error.license-missing"),
-                                MessageFormat.format(
-                                I18N.getString("error.license-missing.advice"),
-                                license));
-                    }
-                }
-            }
-
             // validate presense of required tools
             if (!testTool(TOOL_RPMBUILD, TOOL_RPMBUILD_MIN_VERSION)){
                 throw new ConfigException(
@@ -335,37 +316,28 @@
         }
     }
 
-    /*
-     * set permissions with a string like "rwxr-xr-x"
-     *
-     * This cannot be directly backport to 22u which is built with 1.6
-     */
-    private void setPermissions(File file, String permissions) {
-        Set<PosixFilePermission> filePermissions =
-                PosixFilePermissions.fromString(permissions);
-        try {
-            if (file.exists()) {
-                Files.setPosixFilePermissions(file.toPath(), filePermissions);
-            }
-        } catch (IOException ex) {
-            Logger.getLogger(LinuxDebBundler.class.getName()).log(
-                    Level.SEVERE, null, ex);
-        }
-    }
+    private String getLicenseFileString(Map<String, ? super Object> params)
+            throws IOException {
+        StringBuilder sb = new StringBuilder();
 
-    private String getLicenseFileString(Map<String, ? super Object> params) {
-        StringBuilder sb = new StringBuilder();
-        for (String f: LICENSE_FILE.fetchFrom(params)) {
-            if (sb.length() != 0) {
-                sb.append("\n");
-            }
-            sb.append("%doc ");
+        String licenseStr = LICENSE_FILE.fetchFrom(params);
+        if (licenseStr != null) {
+            File licenseFile = new File(licenseStr);
+            File rootDir =
+                    LinuxAppBundler.getRootDir(RPM_IMAGE_DIR.fetchFrom(params),
+                            params);
+            File target = new File(rootDir + File.separator + "app"
+                    + File.separator + licenseFile.getName());
+            Files.copy(licenseFile.toPath(), target.toPath());
+
+            sb.append("%license ");
             sb.append(LINUX_INSTALL_DIR.fetchFrom(params));
             sb.append("/");
             sb.append(APP_FS_NAME.fetchFrom(params));
             sb.append("/app/");
-            sb.append(f);
+            sb.append(licenseFile.getName());
         }
+
         return sb.toString();
     }
 
@@ -644,7 +616,7 @@
     }
 
     private Map<String, String> createReplacementData(
-            Map<String, ? super Object> params) {
+            Map<String, ? super Object> params) throws IOException {
         Map<String, String> data = new HashMap<>();
 
         data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -84,8 +84,6 @@
 error.parameters-null.advice=Pass in a non-null parameters map.
 error.tool-not-found=Can not find {0}.
 error.tool-not-found.advice=Please install required packages.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative to the basedir "{1}".
 error.launcher-name-too-long=The bundle name "{0}" is too long for a daemon.
 error.launcher-name-too-long.advice=Set a bundler argument "{0}" to a bundle name that is shorter than 16 characters.
 error.cannot-create-output-dir=Output directory {0} cannot be created.
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -84,8 +84,6 @@
 error.parameters-null.advice=Pass in a non-null parameters map.
 error.tool-not-found=Can not find {0}.
 error.tool-not-found.advice=Please install required packages.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative to the basedir "{1}".
 error.launcher-name-too-long=The bundle name "{0}" is too long for a daemon.
 error.launcher-name-too-long.advice=Set a bundler argument "{0}" to a bundle name that is shorter than 16 characters.
 error.cannot-create-output-dir=Output directory {0} cannot be created.
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -84,8 +84,6 @@
 error.parameters-null.advice=Pass in a non-null parameters map.
 error.tool-not-found=Can not find {0}.
 error.tool-not-found.advice=Please install required packages.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative to the basedir "{1}".
 error.launcher-name-too-long=The bundle name "{0}" is too long for a daemon.
 error.launcher-name-too-long.advice=Set a bundler argument "{0}" to a bundle name that is shorter than 16 characters.
 error.cannot-create-output-dir=Output directory {0} cannot be created.
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java	Tue Dec 18 19:31:20 2018 -0500
@@ -191,28 +191,12 @@
 
     private void prepareLicense(Map<String, ? super Object> params) {
         try {
-            File licFile = null;
-
-            List<String> licFiles = LICENSE_FILE.fetchFrom(params);
-            if (licFiles.isEmpty()) {
-                return;
-            }
-            String licFileStr = licFiles.get(0);
-
-            for (RelativeFileSet rfs : APP_RESOURCES_LIST.fetchFrom(params)) {
-                if (rfs.contains(licFileStr)) {
-                    licFile = new File(rfs.getBaseDirectory(), licFileStr);
-                    break;
-                }
-            }
-
-            if (licFile == null) {
-                // this is NPE protection,
-                // validate should have already caught it's absence
-                Log.error("Licence file is null");
+            String licFileStr = LICENSE_FILE.fetchFrom(params);
+            if (licFileStr == null) {
                 return;
             }
 
+            File licFile = new File(licFileStr);
             byte[] licenseContentOriginal = Files.readAllBytes(licFile.toPath());
             String licenseInBase64 =
                     Base64.getEncoder().encodeToString(licenseContentOriginal);
@@ -535,24 +519,6 @@
             //we are not interested in return code, only possible exception
             validateAppImageAndBundeler(params);
 
-            // validate license file, if used, exists in the proper place
-            if (params.containsKey(LICENSE_FILE.getID())) {
-                List<RelativeFileSet> appResourcesList =
-                    APP_RESOURCES_LIST.fetchFrom(params);
-                for (String license : LICENSE_FILE.fetchFrom(params)) {
-                    boolean found = false;
-                    for (RelativeFileSet appResources : appResourcesList) {
-                        found = found || appResources.contains(license);
-                    }
-                    if (!found) {
-                        throw new ConfigException(
-                                I18N.getString("error.license-missing"),
-                                MessageFormat.format(I18N.getString(
-                                "error.license-missing.advice"), license));
-                    }
-                }
-            }
-
             return true;
         } catch (RuntimeException re) {
             if (re.getCause() instanceof ConfigException) {
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java	Tue Dec 18 19:31:20 2018 -0500
@@ -327,30 +327,13 @@
                 + " scaling=\"none\""
                 + "/>");
 
-        if (!LICENSE_FILE.fetchFrom(params).isEmpty()) {
-            File licFile = null;
-
-            List<String> licFiles = LICENSE_FILE.fetchFrom(params);
-            if (licFiles.isEmpty()) {
-                return;
-            }
-            String licFileStr = licFiles.get(0);
-
-            for (RelativeFileSet rfs : APP_RESOURCES_LIST.fetchFrom(params)) {
-                if (rfs.contains(licFileStr)) {
-                    licFile = new File(rfs.getBaseDirectory(), licFileStr);
-                    break;
-                }
-            }
-
-            // this is NPE protection, validate should have caught it's absence
-            // so we don't complain or throw an error
-            if (licFile != null) {
-                out.println("<license"
-                        + " file=\"" + licFile.getAbsolutePath() + "\""
-                        + " mime-type=\"text/rtf\""
-                        + "/>");
-            }
+        String licFileStr = LICENSE_FILE.fetchFrom(params);
+        if (licFileStr != null) {
+            File licFile = new File(licFileStr);
+            out.println("<license"
+                    + " file=\"" + licFile.getAbsolutePath() + "\""
+                    + " mime-type=\"text/rtf\""
+                    + "/>");
         }
 
         /*
@@ -359,7 +342,6 @@
          */
 
         String appId = getAppIdentifier(params);
-        String daemonId = getDaemonIdentifier(params);
 
         out.println("<pkg-ref id=\"" + appId + "\"/>");
 
@@ -538,25 +520,6 @@
             // we are not interested in return code, only possible exception
             validateAppImageAndBundeler(params);
 
-            // validate license file, if used, exists in the proper place
-            if (params.containsKey(LICENSE_FILE.getID())) {
-                List<RelativeFileSet> appResourcesList =
-                        APP_RESOURCES_LIST.fetchFrom(params);
-                for (String license : LICENSE_FILE.fetchFrom(params)) {
-                    boolean found = false;
-                    for (RelativeFileSet appResources : appResourcesList) {
-                        found = found || appResources.contains(license);
-                    }
-                    if (!found) {
-                        throw new ConfigException(
-                                I18N.getString("error.license-missing"),
-                                MessageFormat.format(
-                                I18N.getString("error.license-missing.advice"),
-                                license));
-                    }
-                }
-            }
-
             // reject explicitly set sign to true and no valid signature key
             if (Optional.ofNullable(MacAppImageBuilder.
                     SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -111,8 +111,6 @@
 error.certificate.expired=Error: Certificate expired {0}.
 error.dmg-does-not-do-daemons=DMG bundler doesn't support services.
 error.dmg-does-not-do-daemons.advice=Make sure that the service hint is set to false.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative file reference.
 
 resource.bundle-config-file=Bundle config file
 resource.app-info-plist=Application Info.plist
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -111,8 +111,6 @@
 error.certificate.expired=Error: Certificate expired {0}.
 error.dmg-does-not-do-daemons=DMG bundler doesn't support services.
 error.dmg-does-not-do-daemons.advice=Make sure that the service hint is set to false.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative file reference.
 
 resource.bundle-config-file=Bundle config file
 resource.app-info-plist=Application Info.plist
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -111,8 +111,6 @@
 error.certificate.expired=Error: Certificate expired {0}.
 error.dmg-does-not-do-daemons=DMG bundler doesn't support services.
 error.dmg-does-not-do-daemons.advice=Make sure that the service hint is set to false.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative file reference.
 
 resource.bundle-config-file=Bundle config file
 resource.app-info-plist=Application Info.plist
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java	Tue Dec 18 19:31:20 2018 -0500
@@ -91,13 +91,9 @@
     // String - License type. Needed on Linux (rpm)
     public static final String PARAM_LICENSE_TYPE       = "licenseType";
 
-    // List<String> - File(s) with license. Format is OS/bundler specific
+    // String - File with license. Format is OS/bundler specific
     public static final String PARAM_LICENSE_FILE       = "licenseFile";
 
-    // boolean - service/daemon install.  null means "default"
-    public static final String PARAM_SERVICE_HINT       = "serviceHint";
-
-
     // String Main application class.
     // Not used directly but used to derive default values
     public static final String PARAM_APPLICATION_CLASS  = "applicationClass";
@@ -233,20 +229,6 @@
         putUnlessNull(PARAM_DESCRIPTION, s);
     }
 
-    //path is relative to the application root
-    public void addLicenseFile(String path) {
-        List<String> licenseFiles = fetchParam(LICENSE_FILE);
-        if (licenseFiles == null || licenseFiles.isEmpty()) {
-            licenseFiles = new ArrayList<>();
-            params.put(PARAM_LICENSE_FILE, licenseFiles);
-        }
-        licenseFiles.add(path);
-    }
-
-    public void setServiceHint(Boolean b) {
-        putUnlessNull(PARAM_SERVICE_HINT, b);
-    }
-
     public void setInstalldirChooser(Boolean b) {
         putUnlessNull(PARAM_INSTALLDIR_CHOOSER, b);
     }
@@ -285,10 +267,6 @@
         return fetchParam(VERBOSE);
     }
 
-    public List<String> getLicenseFile() {
-        return fetchParam(LICENSE_FILE);
-    }
-
     public List<String> getJvmargs() {
         return JVM_OPTIONS.fetchFrom(params);
     }
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java	Tue Dec 18 19:31:20 2018 -0500
@@ -27,6 +27,7 @@
 
 import java.io.File;
 import java.nio.file.Files;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -110,10 +111,6 @@
         this.systemWide = systemWide;
     }
 
-    void setServiceHint(Boolean serviceHint) {
-        this.serviceHint = serviceHint;
-    }
-
     void setInstalldirChooser(Boolean installdirChooser) {
         this.installdirChooser = installdirChooser;
     }
@@ -404,6 +401,16 @@
                 throw new PackagerException("ERR_AppImageInvalid", appImage);
             }
         }
+
+        // Validate license file if set
+        String license = (String)bundlerArguments.get(
+                Arguments.CLIOptions.LICENSE_FILE.getId());
+        if (license != null) {
+            File licenseFile = new File(license);
+            if (!licenseFile.exists()) {
+                throw new PackagerException("ERR_LicenseFileNotExit");
+            }
+        }
     }
 
     boolean validateForBundle() {
@@ -498,7 +505,6 @@
         bundleParams.setBundleFormat(targetFormat);
         bundleParams.setVendor(vendor);
         bundleParams.setEmail(email);
-        bundleParams.setServiceHint(serviceHint);
         bundleParams.setInstalldirChooser(installdirChooser);
         bundleParams.setSingleton(singleton);
         bundleParams.setCopyright(copyright);
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java	Tue Dec 18 19:31:20 2018 -0500
@@ -313,14 +313,14 @@
             );
 
     @SuppressWarnings("unchecked")
-    static final StandardBundlerParam<List<String>> LICENSE_FILE =
+    public static final StandardBundlerParam<String> LICENSE_FILE =
             new StandardBundlerParam<>(
                     I18N.getString("param.license-file.name"),
                     I18N.getString("param.license-file.description"),
                     Arguments.CLIOptions.LICENSE_FILE.getId(),
-                    (Class<List<String>>)(Object)List.class,
-                    params -> Collections.<String>emptyList(),
-                    (s, p) -> Arrays.asList(s.split(","))
+                    String.class,
+                    params -> null,
+                    (s, p) -> s
             );
 
     static final StandardBundlerParam<File> BUILD_ROOT =
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -137,8 +137,9 @@
 \          Absolute path of the installation directory of the application\n\
 \          This option is ignored on Windows, use --win-dir-chooser to\n\
 \          provide user the ability to choose the installation directory.\n\
-\  --license-file <file name>\n\
-\          The license file, relative to the input directory\n\
+\  --license-file <file path>\n\
+\          Path to the license file\n\
+\          (absolute path or relative to the current directory)\n\
 \  --copyright <copyright string>\n\
 \          Copyright for the application\n\
 \  --description <description string>\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -137,8 +137,9 @@
 \          Absolute path of the installation directory of the application\n\
 \          This option is ignored on Windows, use --win-dir-chooser to\n\
 \          provide user the ability to choose the installation directory.\n\
-\  --license-file <file name>\n\
-\          The license file, relative to the input directory\n\
+\  --license-file <file path>\n\
+\          Path to the license file\n\
+\          (absolute path or relative to the current directory)\n\
 \  --copyright <copyright string>\n\
 \          Copyright for the application\n\
 \  --description <description string>\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -137,8 +137,9 @@
 \          Absolute path of the installation directory of the application\n\
 \          This option is ignored on Windows, use --win-dir-chooser to\n\
 \          provide user the ability to choose the installation directory.\n\
-\  --license-file <file name>\n\
-\          The license file, relative to the input directory\n\
+\  --license-file <file path>\n\
+\          Path to the license file\n\
+\          (absolute path or relative to the current directory)\n\
 \  --copyright <copyright string>\n\
 \          Copyright for the application\n\
 \  --description <description string>\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -173,3 +173,4 @@
 ERR_NoUniqueName=Secondary Launchers require a unique name parameter.
 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.
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -173,3 +173,4 @@
 ERR_NoUniqueName=Secondary Launchers require a unique name parameter.
 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.
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -173,3 +173,4 @@
 ERR_NoUniqueName=Secondary Launchers require a unique name parameter.
 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.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Tue Dec 18 19:31:20 2018 -0500
@@ -338,25 +338,6 @@
                 }
             }
 
-            // validate license file, if used, exists in the proper place
-            if (p.containsKey(LICENSE_FILE.getID())) {
-                List<RelativeFileSet> appResourcesList =
-                        APP_RESOURCES_LIST.fetchFrom(p);
-                for (String license : LICENSE_FILE.fetchFrom(p)) {
-                    boolean found = false;
-                    for (RelativeFileSet appResources : appResourcesList) {
-                        found = found || appResources.contains(license);
-                    }
-                    if (!found) {
-                        throw new ConfigException(
-                            MessageFormat.format(getString(
-                               "error.license-missing"), license),
-                            MessageFormat.format(getString(
-                               "error.license-missing.advice"), license));
-                    }
-                }
-            }
-
             return true;
         } catch (RuntimeException re) {
             if (re.getCause() instanceof ConfigException) {
@@ -389,22 +370,13 @@
 
         p.put(WIN_APP_IMAGE.getID(), appDir);
 
-        List<String> licenseFiles = LICENSE_FILE.fetchFrom(p);
-        if (licenseFiles != null) {
-            // need to copy license file to the root of win.app.image
-            outerLoop:
-            for (RelativeFileSet rfs : APP_RESOURCES_LIST.fetchFrom(p)) {
-                for (String s : licenseFiles) {
-                    if (rfs.contains(s)) {
-                        File lfile = new File(rfs.getBaseDirectory(), s);
-                        File destFile =
-                            new File(appDir.getParentFile(), lfile.getName());
-                        IOUtils.copyFile(lfile, destFile);
-                        ensureByMutationFileIsRTF(destFile);
-                        break outerLoop;
-                    }
-                }
-            }
+        String licenseFile = LICENSE_FILE.fetchFrom(p);
+        if (licenseFile != null) {
+            // need to copy license file to the working directory and convert to rtf if needed
+            File lfile = new File(licenseFile);
+            File destFile = new File(CONFIG_ROOT.fetchFrom(p), lfile.getName());
+            IOUtils.copyFile(lfile, destFile);
+            ensureByMutationFileIsRTF(destFile);
         }
 
         // copy file association icons
@@ -525,12 +497,19 @@
     }
 
     private String getLicenseFile(Map<String, ? super Object> p) {
-        List<String> licenseFiles = LICENSE_FILE.fetchFrom(p);
-        if (licenseFiles == null || licenseFiles.isEmpty()) {
-            return "";
-        } else {
-            return licenseFiles.get(0);
+        String licenseFile = LICENSE_FILE.fetchFrom(p);
+        if (licenseFile != null) {
+            File lfile = new File(licenseFile);
+            File destFile = new File(CONFIG_ROOT.fetchFrom(p), lfile.getName());
+            String filePath = destFile.getAbsolutePath();
+            if (filePath.contains(" ")) {
+                return "\"" + filePath + "\"";
+            } else {
+                return filePath;
+            }
         }
+
+        return null;
     }
 
     void validateValueAndPut(Map<String, String> data, String key,
@@ -545,6 +524,10 @@
     }
 
     private String innosetupEscape(String value) {
+        if (value == null) {
+            return "";
+        }
+
         if (value.contains("\"") || !value.trim().equals(value)) {
             value = "\"" + value.replace("\"", "\"\"") + "\"";
         }
@@ -677,7 +660,7 @@
                                 .append("\"; ValueType: string;"
                                 + " ValueName: \"\"; ValueData: \"")
                                 .append(entryName)
-                                .append("\"; Flags: uninsdeletevalue\r\n");
+                                .append("\"; Flags: uninsdeletevalue uninsdeletekeyifempty\r\n");
                     } else {
                         registryEntries.append(
                                 "Root: HKCU; Subkey: \"Software\\Classes\\.")
@@ -685,7 +668,7 @@
                                 .append("\"; ValueType: string;"
                                 + " ValueName: \"\"; ValueData: \"")
                                 .append(entryName)
-                                .append("\"; Flags: uninsdeletevalue\r\n");
+                                .append("\"; Flags: uninsdeletevalue uninsdeletekeyifempty\r\n");
                     }
                 }
             }
@@ -709,7 +692,7 @@
                             .append("\"; ValueType: string; ValueName: " +
                                  "\"Extension\"; ValueData: \".")
                             .append(ext)
-                            .append("\"; Flags: uninsdeletevalue\r\n");
+                            .append("\"; Flags: uninsdeletevalue uninsdeletekeyifempty\r\n");
                     } else {
                         registryEntries.append(
                                 "Root: HKCU; Subkey: \"Software\\" +
@@ -718,7 +701,7 @@
                                 .append("\"; ValueType: string; " +
                                 "ValueName: \"Extension\"; ValueData: \".")
                                 .append(ext)
-                                .append("\"; Flags: uninsdeletevalue\r\n");
+                                .append("\"; Flags: uninsdeletevalue uninsdeletekeyifempty\r\n");
                     }
                 }
             }
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Tue Dec 18 19:31:20 2018 -0500
@@ -384,25 +384,6 @@
                 }
             }
 
-            // validate license file, if used, exists in the proper place
-            if (p.containsKey(LICENSE_FILE.getID())) {
-                List<RelativeFileSet> appResourcesList =
-                        APP_RESOURCES_LIST.fetchFrom(p);
-                for (String license : LICENSE_FILE.fetchFrom(p)) {
-                    boolean found = false;
-                    for (RelativeFileSet appResources : appResourcesList) {
-                        found = found || appResources.contains(license);
-                    }
-                    if (!found) {
-                        throw new ConfigException(
-                            MessageFormat.format(I18N.getString(
-                               "error.license-missing"), license),
-                            MessageFormat.format(I18N.getString(
-                               "error.license-missing.advice"), license));
-                    }
-                }
-            }
-
             return true;
         } catch (RuntimeException re) {
             if (re.getCause() instanceof ConfigException) {
@@ -482,21 +463,13 @@
 
         p.put(WIN_APP_IMAGE.getID(), appDir);
 
-        List<String> licenseFiles = LICENSE_FILE.fetchFrom(p);
-        if (licenseFiles != null) {
-            // need to copy license file to the root of win.app.image
-            outerLoop:
-            for (RelativeFileSet rfs : APP_RESOURCES_LIST.fetchFrom(p)) {
-                for (String s : licenseFiles) {
-                    if (rfs.contains(s)) {
-                        File lfile = new File(rfs.getBaseDirectory(), s);
-                        File destFile = new File(appDir, lfile.getName());
-                        IOUtils.copyFile(lfile, destFile);
-                        ensureByMutationFileIsRTF(destFile);
-                        break outerLoop;
-                    }
-                }
-            }
+        String licenseFile = LICENSE_FILE.fetchFrom(p);
+        if (licenseFile != null) {
+            // need to copy license file to the working directory and convert to rtf if needed
+            File lfile = new File(licenseFile);
+            File destFile = new File(CONFIG_ROOT.fetchFrom(p), lfile.getName());
+            IOUtils.copyFile(lfile, destFile);
+            ensureByMutationFileIsRTF(destFile);
         }
 
         // copy file association icons
@@ -1111,13 +1084,20 @@
                 APP_NAME.fetchFrom(params) + ".wxs");
     }
 
-    private String getLicenseFile(Map<String, ? super Object> params) {
-        List<String> licenseFiles = LICENSE_FILE.fetchFrom(params);
-        if (licenseFiles == null || licenseFiles.isEmpty()) {
-            return null;
-        } else {
-            return licenseFiles.get(0);
+    private String getLicenseFile(Map<String, ? super Object> p) {
+        String licenseFile = LICENSE_FILE.fetchFrom(p);
+        if (licenseFile != null) {
+            File lfile = new File(licenseFile);
+            File destFile = new File(CONFIG_ROOT.fetchFrom(p), lfile.getName());
+            String filePath = destFile.getAbsolutePath();
+            if (filePath.contains(" ")) {
+                return "\"" + filePath + "\"";
+            } else {
+                return filePath;
+            }
         }
+
+        return null;
     }
 
     private boolean prepareWiXConfig(
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -99,8 +99,6 @@
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
 error.iscc-not-found=Can not find Inno Setup Compiler (iscc.exe).
 error.iscc-not-found.advice=Download Inno Setup 5 or later from http\://www.jrsoftware.org and add it to the PATH.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative file reference.
 error.copyright-is-too-long=The copyright string is too long for InnoSetup.
 error.copyright-is-too-long.advice=Provide a copyright string shorter than 100 characters.
 error.too-many-content-types-for-file-association=More than one MIME types was specified for File Association number {0}.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -99,8 +99,6 @@
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
 error.iscc-not-found=Can not find Inno Setup Compiler (iscc.exe).
 error.iscc-not-found.advice=Download Inno Setup 5 or later from http\://www.jrsoftware.org and add it to the PATH.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative file reference.
 error.copyright-is-too-long=The copyright string is too long for InnoSetup.
 error.copyright-is-too-long.advice=Provide a copyright string shorter than 100 characters.
 error.too-many-content-types-for-file-association=More than one MIME types was specified for File Association number {0}.
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties	Tue Dec 18 18:23:16 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
@@ -99,8 +99,6 @@
 error.cannot-write-to-output-dir=Output directory {0} is not writable.
 error.iscc-not-found=Can not find Inno Setup Compiler (iscc.exe).
 error.iscc-not-found.advice=Download Inno Setup 5 or later from http\://www.jrsoftware.org and add it to the PATH.
-error.license-missing=Specified license file is missing.
-error.license-missing.advice=Make sure that "{0}" references a file in the app resources, and that it is relative file reference.
 error.copyright-is-too-long=The copyright string is too long for InnoSetup.
 error.copyright-is-too-long.advice=Provide a copyright string shorter than 100 characters.
 error.too-many-content-types-for-file-association=More than one MIME types was specified for File Association number {0}.