8215515: Add a command line option to override internal resources. JDK-8200758-branch
authorherrick
Fri, 21 Dec 2018 07:40:47 -0500
branchJDK-8200758-branch
changeset 57091 06bc4bd64599
parent 57080 bd4ce7f9ea2c
child 57092 3c5666ad2181
8215515: Add a command line option to override internal resources. Reviewed-by: kcr, almatvee
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppBundler.java
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java
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.java
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/javalogo_white_16.png
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/javalogo_white_48.png
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/MacBaseInstallerBundler.java
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.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.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/StandardBundlerParam.java
src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.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/share/classes/jdk/jpackage/internal/resources/ResourceLocator.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsBundlerParam.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/javalogo_white_16.ico
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/javalogo_white_32.ico
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.LinuxResources;
-
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.LinuxResources;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -182,11 +180,6 @@
     }
 
     @Override
-    public InputStream getResourceAsStream(String name) {
-        return LinuxResources.class.getResourceAsStream(name);
-    }
-
-    @Override
     public void prepareApplicationFiles() throws IOException {
         Map<String, ? super Object> originalParams = new HashMap<>(params);
 
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.LinuxResources;
-
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.*;
@@ -231,11 +229,6 @@
 
     public final static String TOOL_DPKG = "dpkg-deb";
 
-    public LinuxDebBundler() {
-        super();
-        baseResourceLoader = LinuxResources.class;
-    }
-
     public static boolean testTool(String toolName, String minVersion) {
         try {
             ProcessBuilder pb = new ProcessBuilder(
@@ -453,21 +446,19 @@
         if (!Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) {
             // prepare installer icon
             if (icon == null || !icon.exists()) {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         DEFAULT_ICON,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             } else {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         icon,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             }
         }
 
@@ -487,14 +478,13 @@
                         getConfig_DesktopShortcutFile(
                                 rootDir, secondaryLauncher)));
                 String content = preprocessTextResource(
-                        LinuxAppBundler.BUNDLER_PREFIX
-                                + getConfig_DesktopShortcutFile(rootDir,
-                                        secondaryLauncher).getName(),
+                        getConfig_DesktopShortcutFile(rootDir,
+                        secondaryLauncher).getName(),
                         I18N.getString("resource.menu-shortcut-descriptor"),
                         DEFAULT_DESKTOP_FILE_TEMPLATE,
                         secondaryLauncherData,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
                 w.write(content);
                 w.close();
             }
@@ -503,21 +493,19 @@
             iconTarget = getConfig_IconFile(rootDir, secondaryLauncher);
             icon = ICON_PNG.fetchFrom(secondaryLauncher);
             if (icon == null || !icon.exists()) {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         DEFAULT_ICON,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             } else {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         icon,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             }
 
             // postinst copying of desktop icon
@@ -690,14 +678,13 @@
             Writer w = new BufferedWriter(new FileWriter(
                     getConfig_DesktopShortcutFile(rootDir, params)));
             String content = preprocessTextResource(
-                    LinuxAppBundler.BUNDLER_PREFIX
-                            + getConfig_DesktopShortcutFile(
-                                    rootDir, params).getName(),
+                    getConfig_DesktopShortcutFile(
+                    rootDir, params).getName(),
                     I18N.getString("resource.menu-shortcut-descriptor"),
                     DEFAULT_DESKTOP_FILE_TEMPLATE,
                     data,
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
             w.write(content);
             w.close();
         }
@@ -705,39 +692,36 @@
         Writer w = new BufferedWriter(new FileWriter(
                 getConfig_ControlFile(params)));
         String content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_ControlFile(params).getName(),
+                getConfig_ControlFile(params).getName(),
                 I18N.getString("resource.deb-control-file"),
                 DEFAULT_CONTROL_TEMPLATE,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
 
         w = new BufferedWriter(new FileWriter(
                 getConfig_PreinstallFile(params)));
         content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_PreinstallFile(params).getName(),
+                getConfig_PreinstallFile(params).getName(),
                 I18N.getString("resource.deb-preinstall-script"),
                 DEFAULT_PREINSTALL_TEMPLATE,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         setPermissions(getConfig_PreinstallFile(params), "rwxr-xr-x");
 
         w = new BufferedWriter(new FileWriter(getConfig_PrermFile(params)));
         content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_PrermFile(params).getName(),
+                getConfig_PrermFile(params).getName(),
                 I18N.getString("resource.deb-prerm-script"),
                 DEFAULT_PRERM_TEMPLATE,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         setPermissions(getConfig_PrermFile(params), "rwxr-xr-x");
@@ -745,39 +729,36 @@
         w = new BufferedWriter(new FileWriter(
                 getConfig_PostinstallFile(params)));
         content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_PostinstallFile(params).getName(),
+                getConfig_PostinstallFile(params).getName(),
                 I18N.getString("resource.deb-postinstall-script"),
                 DEFAULT_POSTINSTALL_TEMPLATE,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         setPermissions(getConfig_PostinstallFile(params), "rwxr-xr-x");
 
         w = new BufferedWriter(new FileWriter(getConfig_PostrmFile(params)));
         content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_PostrmFile(params).getName(),
+                getConfig_PostrmFile(params).getName(),
                 I18N.getString("resource.deb-postrm-script"),
                 DEFAULT_POSTRM_TEMPLATE,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         setPermissions(getConfig_PostrmFile(params), "rwxr-xr-x");
 
         w = new BufferedWriter(new FileWriter(getConfig_CopyrightFile(params)));
         content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_CopyrightFile(params).getName(),
+                getConfig_CopyrightFile(params).getName(),
                 I18N.getString("resource.deb-copyright-file"),
                 DEFAULT_COPYRIGHT_TEMPLATE,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
 
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.LinuxResources;
-
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.*;
@@ -163,11 +161,6 @@
     public final static String TOOL_RPMBUILD = "rpmbuild";
     public final static double TOOL_RPMBUILD_MIN_VERSION = 4.0d;
 
-    public LinuxRpmBundler() {
-        super();
-        baseResourceLoader = LinuxResources.class;
-    }
-
     public static boolean testTool(String toolName, double minVersion) {
         try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 PrintStream ps = new PrintStream(baos)) {
@@ -352,21 +345,19 @@
         File icon = LinuxAppBundler.ICON_PNG.fetchFrom(params);
         if (!Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) {
             if (icon == null || !icon.exists()) {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         DEFAULT_ICON,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             } else {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         icon,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             }
         }
 
@@ -384,13 +375,12 @@
             Writer w = new BufferedWriter(new FileWriter(
                     getConfig_DesktopShortcutFile(rootDir, secondaryLauncher)));
             String content = preprocessTextResource(
-                    LinuxAppBundler.BUNDLER_PREFIX
-                            + getConfig_DesktopShortcutFile(rootDir,
-                                    secondaryLauncher).getName(),
+                    getConfig_DesktopShortcutFile(rootDir,
+                    secondaryLauncher).getName(),
                     I18N.getString("resource.menu-shortcut-descriptor"),
                     DEFAULT_DESKTOP_FILE_TEMPLATE, secondaryLauncherData,
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
             w.write(content);
             w.close();
 
@@ -398,21 +388,19 @@
             iconTarget = getConfig_IconFile(rootDir, secondaryLauncher);
             icon = LinuxAppBundler.ICON_PNG.fetchFrom(secondaryLauncher);
             if (icon == null || !icon.exists()) {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         DEFAULT_ICON,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             } else {
-                fetchResource(LinuxAppBundler.BUNDLER_PREFIX
-                        + iconTarget.getName(),
+                fetchResource(iconTarget.getName(),
                         I18N.getString("resource.menu-icon"),
                         icon,
                         iconTarget,
                         VERBOSE.fetchFrom(params),
-                        DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                        RESOURCE_DIR.fetchFrom(params));
             }
 
             // post copying of desktop icon
@@ -588,13 +576,11 @@
             Writer w = new BufferedWriter(new FileWriter(
                     getConfig_DesktopShortcutFile(rootDir, params)));
             String content = preprocessTextResource(
-                    LinuxAppBundler.BUNDLER_PREFIX
-                            + getConfig_DesktopShortcutFile(rootDir,
-                                    params).getName(),
+                    getConfig_DesktopShortcutFile(rootDir, params).getName(),
                     I18N.getString("resource.menu-shortcut-descriptor"),
                     DEFAULT_DESKTOP_FILE_TEMPLATE, data,
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
             w.write(content);
             w.close();
         }
@@ -603,12 +589,11 @@
         Writer w = new BufferedWriter(
                 new FileWriter(getConfig_SpecFile(params)));
         String content = preprocessTextResource(
-                LinuxAppBundler.BUNDLER_PREFIX
-                        + getConfig_SpecFile(params).getName(),
+                getConfig_SpecFile(params).getName(),
                 I18N.getString("resource.rpm-spec-file"),
                 DEFAULT_SPEC_TEMPLATE, data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
 
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.java	Tue Dec 18 19:31:20 2018 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jpackage.internal.resources;
-
-public class LinuxResources {
-
-}
Binary file src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/javalogo_white_16.png has changed
Binary file src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/javalogo_white_48.png has changed
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.MacResources;
-
 import java.io.File;
 import java.io.IOException;
 import java.math.BigInteger;
@@ -220,11 +218,6 @@
             },
             (s, p) -> new File(s));
 
-    public MacAppBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
     public static boolean validCFBundleVersion(String v) {
         // CFBundleVersion (String - iOS, OS X) specifies the build version
         // number of the bundle, which identifies an iteration (released or
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.MacResources;
-
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
@@ -327,11 +325,6 @@
     }
 
     @Override
-    public InputStream getResourceAsStream(String name) {
-        return MacResources.class.getResourceAsStream(name);
-    }
-
-    @Override
     public void prepareApplicationFiles() throws IOException {
         Map<String, ? super Object> originalParams = new HashMap<>(params);
         // Generate PkgInfo
@@ -379,12 +372,12 @@
         /*********** Take care of "config" files *******/
         File icon = ICON_ICNS.fetchFrom(params);
         InputStream in = locateResource(
-                "package/macosx/" + APP_NAME.fetchFrom(params) + ".icns",
+                APP_NAME.fetchFrom(params) + ".icns",
                 "icon",
                 DEFAULT_ICNS_ICON.fetchFrom(params),
                 icon,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         Files.copy(in,
                 resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns"));
 
@@ -510,13 +503,12 @@
         data.put("CF_BUNDLE_SHORT_VERSION_STRING", VERSION.fetchFrom(params));
 
         Writer w = new BufferedWriter(new FileWriter(file));
-        w.write(preprocessTextResource(
-                "package/macosx/Runtime-Info.plist",
+        w.write(preprocessTextResource("Runtime-Info.plist",
                 I18N.getString("resource.runtime-info-plist"),
                 TEMPLATE_RUNTIME_INFO_PLIST,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params)));
+                RESOURCE_DIR.fetchFrom(params)));
         w.close();
     }
 
@@ -729,12 +721,12 @@
 
         Writer w = new BufferedWriter(new FileWriter(file));
         w.write(preprocessTextResource(
-                // BUNDLER_PREFIX + getConfig_InfoPlist(params).getName(),
-                "package/Info.plist",
+                // getConfig_InfoPlist(params).getName(),
+                "Info.plist",
                 I18N.getString("resource.app-info-plist"),
                 TEMPLATE_INFO_PLIST_LITE,
                 data, VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params)));
+                RESOURCE_DIR.fetchFrom(params)));
         w.close();
     }
 
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.MacResources;
-
 import java.io.File;
 import java.io.IOException;
 import java.text.MessageFormat;
@@ -127,11 +125,6 @@
             params -> "-MacAppStore",
             (s, p) -> s);
 
-    public MacAppStoreBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
     //@Override
     public File bundle(Map<String, ? super Object> p, File outdir) {
         Log.verbose(MessageFormat.format(I18N.getString(
@@ -274,31 +267,30 @@
                     DEFAULT_ENTITLEMENTS,
                     getConfig_Entitlements(params),
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
         } else {
             fetchResource(getEntitlementsFileName(params),
                     I18N.getString("resource.mac-app-store-entitlements"),
                     entitlements,
                     getConfig_Entitlements(params),
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
         }
         fetchResource(getInheritEntitlementsFileName(params),
                 I18N.getString("resource.mac-app-store-inherit-entitlements"),
                 DEFAULT_INHERIT_ENTITLEMENTS,
                 getConfig_Inherit_Entitlements(params),
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
     }
 
     private String getEntitlementsFileName(Map<String, ? super Object> params) {
-        return BUNDLER_PREFIX + APP_NAME.fetchFrom(params) + ".entitlements";
+        return APP_NAME.fetchFrom(params) + ".entitlements";
     }
 
     private String getInheritEntitlementsFileName(
             Map<String, ? super Object> params) {
-        return BUNDLER_PREFIX + APP_NAME.fetchFrom(params)
-                + "_Inherit.entitlements";
+        return APP_NAME.fetchFrom(params) + "_Inherit.entitlements";
     }
 
 
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.MacResources;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.MacResources;
-
 import java.io.*;
 import java.nio.file.Files;
 import java.text.MessageFormat;
@@ -54,11 +52,6 @@
             params -> "",
             (s, p) -> s);
 
-    public MacDmgBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
     public File bundle(Map<String, ? super Object> params, File outdir) {
         Log.verbose(MessageFormat.format(I18N.getString("message.building-dmg"),
                 APP_NAME.fetchFrom(params)));
@@ -160,11 +153,10 @@
         data.put("DEPLOY_INSTALL_NAME", "Desktop");
 
         Writer w = new BufferedWriter(new FileWriter(dmgSetup));
-        w.write(preprocessTextResource(
-                MacAppBundler.BUNDLER_PREFIX + dmgSetup.getName(),
+        w.write(preprocessTextResource(dmgSetup.getName(),
                 I18N.getString("resource.dmg-setup-script"),
                         DEFAULT_DMG_SETUP_SCRIPT, data, VERBOSE.fetchFrom(p),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(p)));
+                RESOURCE_DIR.fetchFrom(p)));
         w.close();
     }
 
@@ -207,11 +199,10 @@
             Writer w = new BufferedWriter(
                     new FileWriter(getConfig_LicenseFile(params)));
             w.write(preprocessTextResource(
-                    MacAppBundler.BUNDLER_PREFIX
-                    + getConfig_LicenseFile(params).getName(),
+                    getConfig_LicenseFile(params).getName(),
                     I18N.getString("resource.license-setup"),
                     DEFAULT_LICENSE_PLIST, data, VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params)));
+                    RESOURCE_DIR.fetchFrom(params)));
             w.close();
 
         } catch (IOException ex) {
@@ -222,41 +213,38 @@
     private boolean prepareConfigFiles(Map<String, ? super Object> params)
             throws IOException {
         File bgTarget = getConfig_VolumeBackground(params);
-        fetchResource(MacAppBundler.BUNDLER_PREFIX + bgTarget.getName(),
+        fetchResource(bgTarget.getName(),
                 I18N.getString("resource.dmg-background"),
                 DEFAULT_BACKGROUND_IMAGE,
                 bgTarget,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
 
         File iconTarget = getConfig_VolumeIcon(params);
         if (MacAppBundler.ICON_ICNS.fetchFrom(params) == null ||
                 !MacAppBundler.ICON_ICNS.fetchFrom(params).exists()) {
-            fetchResource(
-                    MacAppBundler.BUNDLER_PREFIX + iconTarget.getName(),
+            fetchResource(iconTarget.getName(),
                     I18N.getString("resource.volume-icon"),
                     TEMPLATE_BUNDLE_ICON,
                     iconTarget,
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
         } else {
-            fetchResource(
-                    MacAppBundler.BUNDLER_PREFIX + iconTarget.getName(),
+            fetchResource(iconTarget.getName(),
                     I18N.getString("resource.volume-icon"),
                     MacAppBundler.ICON_ICNS.fetchFrom(params),
                     iconTarget,
                     VERBOSE.fetchFrom(params),
-                    DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                    RESOURCE_DIR.fetchFrom(params));
         }
 
 
-        fetchResource(MacAppBundler.BUNDLER_PREFIX
-                + getConfig_Script(params).getName(),
+        fetchResource(getConfig_Script(params).getName(),
                 I18N.getString("resource.post-install-script"),
                 (String) null,
                 getConfig_Script(params),
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
 
         prepareLicense(params);
 
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.MacResources;
-
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
@@ -141,11 +139,6 @@
             params -> "",
             (s, p) -> s);
 
-    public MacPkgBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
     public File bundle(Map<String, ? super Object> params, File outdir) {
         Log.verbose(MessageFormat.format(I18N.getString("message.building-pkg"),
                 APP_NAME.fetchFrom(params)));
@@ -280,26 +273,26 @@
 
         Writer w = new BufferedWriter(
                 new FileWriter(getScripts_PreinstallFile(params)));
-        String content = preprocessTextResource(MacAppBundler.BUNDLER_PREFIX
-                + getScripts_PreinstallFile(params).getName(),
+        String content = preprocessTextResource(
+                getScripts_PreinstallFile(params).getName(),
                 I18N.getString("resource.pkg-preinstall-script"),
                 TEMPLATE_PREINSTALL_SCRIPT,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         getScripts_PreinstallFile(params).setExecutable(true, false);
 
         w = new BufferedWriter(
                 new FileWriter(getScripts_PostinstallFile(params)));
-        content = preprocessTextResource(MacAppBundler.BUNDLER_PREFIX
-                + getScripts_PostinstallFile(params).getName(),
+        content = preprocessTextResource(
+                getScripts_PostinstallFile(params).getName(),
                 I18N.getString("resource.pkg-postinstall-script"),
                 TEMPLATE_POSTINSTALL_SCRIPT,
                 data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         getScripts_PostinstallFile(params).setExecutable(true, false);
@@ -368,22 +361,21 @@
     private boolean prepareConfigFiles(Map<String, ? super Object> params)
             throws IOException {
         File imageTarget = getConfig_BackgroundImage(params);
-        fetchResource(MacAppBundler.BUNDLER_PREFIX + imageTarget.getName(),
+        fetchResource(imageTarget.getName(),
                 I18N.getString("resource.pkg-background-image"),
                 DEFAULT_BACKGROUND_IMAGE,
                 imageTarget,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
 
         prepareDistributionXMLFile(params);
 
-        fetchResource(MacAppBundler.BUNDLER_PREFIX
-                + getConfig_Script(params).getName(),
+        fetchResource(getConfig_Script(params).getName(),
                 I18N.getString("resource.post-install-script"),
                 (String) null,
                 getConfig_Script(params),
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
 
         return true;
     }
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.java	Tue Dec 18 19:31:20 2018 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jpackage.internal.resources;
-
-// no-op, use as anchor for resource loading
-public class MacResources {
-
-}
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java	Fri Dec 21 07:40:47 2018 -0500
@@ -39,6 +39,8 @@
 import java.util.ResourceBundle;
 import java.util.ArrayList;
 
+import jdk.jpackage.internal.resources.ResourceLocator;
+
 import static jdk.jpackage.internal.StandardBundlerParam.*;
 import static jdk.jpackage.internal.StandardBundlerParam.ARGUMENTS;
 
@@ -47,10 +49,6 @@
     private static final ResourceBundle I18N = ResourceBundle.getBundle(
             "jdk.jpackage.internal.resources.MainResources");
 
-    //do not use file separator -
-    // we use it for classpath lookup and there / are not platform specific
-    public final static String BUNDLER_PREFIX = "package/";
-
     private final Map<String, Object> properties;
     private final Path root;
     protected List<String> excludeFileList = new ArrayList<>();
@@ -62,7 +60,10 @@
         excludeFileList.add(".*\\.diz");
     }
 
-    public abstract InputStream getResourceAsStream(String name);
+    public InputStream getResourceAsStream(String name) {
+        return ResourceLocator.class.getResourceAsStream(name);
+    }
+
     public abstract void prepareApplicationFiles() throws IOException;
     public abstract void prepareJreFiles() throws IOException;
     public abstract Path getAppDir();
@@ -120,7 +121,7 @@
             String msg = null;
             if (customFromClasspath) {
                 msg = MessageFormat.format(I18N.getString(
-                    "message.using-custom-resource-from-classpath"),
+                    "message.using-custom-resource"),
                     category == null ? "" : "[" + category + "] ", publicName);
             } else if (customFromFile) {
                 msg = MessageFormat.format(I18N.getString(
@@ -129,12 +130,16 @@
                     customFile.getAbsoluteFile());
             } else if (is != null) {
                 msg = MessageFormat.format(I18N.getString(
-                    "message.using-default-resource-from-classpath"),
-                    category == null ? "" : "[" + category + "] ", publicName);
+                    "message.using-default-resource"),
+                    defaultName,
+                    category == null ? "" : "[" + category + "] ",
+                    publicName);
             } else {
                 msg = MessageFormat.format(I18N.getString(
-                    "message.using-default-resource"),
-                    category == null ? "" : "[" + category + "] ", publicName);
+                    "message.no-default-resource"),
+                    defaultName == null ? "" : defaultName,
+                    category == null ? "" : "[" + category + "] ",
+                    publicName);
             }
             if (msg != null) {
                 Log.verbose(msg);
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -37,6 +37,8 @@
 import java.util.Map;
 import java.util.ResourceBundle;
 
+import jdk.jpackage.internal.resources.ResourceLocator;
+
 /**
  * AbstractBundler
  *
@@ -59,15 +61,14 @@
                 StandardBundlerParam.BUILD_ROOT.fetchFrom(params), "images"),
             (s, p) -> null);
 
-    // do not use file separator -
-    // we use it for classpath lookup and there / are not platform specific
-    public final static String BUNDLER_PREFIX = "package/";
-
-    protected Class<?> baseResourceLoader = null;
+    public InputStream getResourceAsStream(String name) {
+        return ResourceLocator.class.getResourceAsStream(name);
+    }
 
     protected void fetchResource(String publicName, String category,
             String defaultName, File result, boolean verbose, File publicRoot)
             throws IOException {
+
         InputStream is = streamResource(publicName, category,
                 defaultName, verbose, publicRoot);
         if (is != null) {
@@ -80,7 +81,8 @@
         } else {
             if (verbose) {
                 Log.verbose(MessageFormat.format(I18N.getString(
-                        "message.using-default-resource"),
+                        "message.no-default-resource"),
+                        defaultName == null ? "" : defaultName,
                         category == null ? "" : "[" + category + "] ",
                         publicName));
             }
@@ -90,6 +92,7 @@
     protected void fetchResource(String publicName, String category,
             File defaultFile, File result, boolean verbose, File publicRoot)
             throws IOException {
+
         InputStream is = streamResource(publicName, category,
                 null, verbose, publicRoot);
         if (is != null) {
@@ -122,26 +125,26 @@
                             new FileInputStream(publicResource));
                 }
             } else {
-                is = baseResourceLoader.getClassLoader().getResourceAsStream(
-                        publicName);
+                is = getResourceAsStream(publicName);
             }
             custom = (is != null);
         }
         if (is == null && defaultName != null) {
-            is = baseResourceLoader.getResourceAsStream(defaultName);
+            is = getResourceAsStream(defaultName);
         }
         if (verbose && is != null) {
             String msg = null;
             if (custom) {
                 msg = MessageFormat.format(I18N.getString(
-                        "message.using-custom-resource-from-classpath"),
+                        "message.using-custom-resource"),
                         category == null ?
                         "" : "[" + category + "] ", publicName);
             } else {
                 msg = MessageFormat.format(I18N.getString(
-                        "message.using-default-resource-from-classpath"),
-                        category == null ?
-                        "" : "[" + category + "] ", publicName);
+                        "message.using-default-resource"),
+                        defaultName == null ? "" : defaultName,
+                        category == null ? "" : "[" + category + "] ",
+                        publicName);
             }
             Log.verbose(msg);
         }
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java	Fri Dec 21 07:40:47 2018 -0500
@@ -231,6 +231,11 @@
             setOptionValue("force", true);
         }),
 
+        RESOURCE_DIR("resource-dir",
+                OptionCategories.PROPERTY, () -> {
+            String resourceDir = popArg();
+            setOptionValue("resource-dir", resourceDir);
+        }),
 
         FILES ("files", "f", OptionCategories.PROPERTY, () -> {
               context().files = new ArrayList<>();
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java	Fri Dec 21 07:40:47 2018 -0500
@@ -394,13 +394,13 @@
                             true : Boolean.valueOf(s)
             );
 
-    static final StandardBundlerParam<File> DROP_IN_RESOURCES_ROOT =
+    static final StandardBundlerParam<File> RESOURCE_DIR =
             new StandardBundlerParam<>(
-                    I18N.getString("param.drop-in-resources-root.name"),
-                    I18N.getString("param.drop-in-resources-root.description"),
-                    "dropinResourcesRoot",
+                    I18N.getString("param.resource-dir.name"),
+                    I18N.getString("param.resource-dir.description"),
+                    Arguments.CLIOptions.RESOURCE_DIR.getId(),
                     File.class,
-                    params -> new File("."),
+                    params -> null,
                     (s, p) -> new File(s)
             );
 
@@ -763,11 +763,6 @@
                         MessageFormat.format(I18N.getString(
                         "error.no-main-class-with-main-jar.advice"),
                         MAIN_JAR.fetchFrom(params)));
-            } else if (hasMainJarClassPath) {
-                throw new ConfigException(
-                        I18N.getString("error.no-main-class-with-classpath"),
-                        I18N.getString(
-                        "error.no-main-class-with-classpath.advice"));
             } else {
                 throw new ConfigException(
                         I18N.getString("error.no-main-class"),
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java	Fri Dec 21 07:40:47 2018 -0500
@@ -81,6 +81,7 @@
         add(CLIOptions.CREATE_IMAGE, CLIOptions.ADD_MODULES);
         add(CLIOptions.CREATE_IMAGE, CLIOptions.MODULE_PATH);
         add(CLIOptions.CREATE_IMAGE, CLIOptions.LIMIT_MODULES);
+        add(CLIOptions.CREATE_IMAGE, CLIOptions.RESOURCE_DIR);
 
         if (Platform.getPlatform() == Platform.MAC) {
             add(CLIOptions.CREATE_IMAGE, CLIOptions.MAC_SIGN);
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties	Fri Dec 21 07:40:47 2018 -0500
@@ -150,6 +150,11 @@
 \          Vendor of the application\n\
 \  --force 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\
+\          Icons, template files, and other resources of jpackage can be\n\
+\          over-ridden by adding replacement resources to this directory.\n\
+\          (absolute path or relative to the current directory)\n\
 \n\
 Modular options:\n\
 \  --module -m <module name>\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties	Fri Dec 21 07:40:47 2018 -0500
@@ -150,6 +150,11 @@
 \          Vendor of the application\n\
 \  --force 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\
+\          Icons, template files, and other resources of jpackage can be\n\
+\          over-ridden by adding replacement resources to this directory.\n\
+\          (absolute path or relative to the current directory)\n\
 \n\
 Modular options:\n\
 \  --module -m <module name>\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties	Fri Dec 21 07:40:47 2018 -0500
@@ -150,6 +150,11 @@
 \          Vendor of the application\n\
 \  --force 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\
+\          Icons, template files, and other resources of jpackage can be\n\
+\          over-ridden by adding replacement resources to this directory.\n\
+\          (absolute path or relative to the current directory)\n\
 \n\
 Modular options:\n\
 \  --module -m <module name>\n\
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties	Fri Dec 21 07:40:47 2018 -0500
@@ -93,8 +93,8 @@
 param.verbose.description=Flag to print out more information and saves configuration files for bundlers.
 param.force.name=Force
 param.force.description=Flag to allow removal of existing Build Root contents
-param.drop-in-resources-root.name=Drop-In Resources Root
-param.drop-in-resources-root.description=The directory to look for bundler specific drop in resources.  If not set the classpath will be searched.
+param.resource-dir.name=Resource Dir
+param.resource-dir.description=The directory to look for bundler specific resources.
 param.secondary-launchers.name=Secondary Launchers
 param.secondary-launchers.description=A collection of bundle param info for secondary launchers
 param.file-associations.name=File Associations
@@ -124,10 +124,10 @@
 param.install-dir.name=Installation Directory
 param.install-dir.description=Installation directory of the application.
 
-message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize)
+message.using-default-resource=Using default package resource {0} {1} (add {2} to the resource-dir to customize)
+message.no-default-resource=no default package resource {0} {1} (add {2} to the resource-dir to customize)
 message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1})
-message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1})
-message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize)
+message.using-custom-resource=Using custom package resource {0} (loaded from {1})
 message.creating-app-bundle=Creating app bundle\: {0} in {1}
 message.detected.modules="Automatically adding detected modules: {0}."
 message.modules="Adding modules: {0} to runtime image."
@@ -145,11 +145,9 @@
 error.no-main-module.advice=Make sure to use fx\:module task to create modular application.
 error.srcfiles.contain.modules=Error: Modules are not allowed in srcfiles: {0}.
 error.no-main-class-with-main-jar=An application class was not specified nor was one found in the jar {0}
-error.no-main-class-with-main-jar.advice=Please specify a applicationClass or ensure that the jar {0} specifies one in the manifest.
-error.no-main-class-with-classpath=An application class was not specified nor was one found in the supplied classpath
-error.no-main-class-with-classpath.advice=Please specify a applicationClass or ensure that the classpath has a jar containing one in the manifest.
+error.no-main-class-with-main-jar.advice=Please specify a application class or ensure that the jar {0} specifies one in the manifest.
 error.no-main-class=An application class was not specified nor was one found in the supplied application resources
-error.no-main-class.advice=Please specify a applicationClass or ensure that the appResources has a jar containing one in the manifest.
+error.no-main-class.advice=Please specify a application class or ensure that the appResources has a jar containing one in the manifest.
 error.main-jar-does-not-exist=The configured main jar does not exist {0}
 error.main-jar-does-not-exist.advice=The main jar must be specified relative to the app resources (not an absolute path), and must exist within those resources.
 
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties	Fri Dec 21 07:40:47 2018 -0500
@@ -93,8 +93,8 @@
 param.verbose.description=Flag to print out more information and saves configuration files for bundlers.
 param.force.name=Force
 param.force.description=Flag to allow removal of existing Build Root contents
-param.drop-in-resources-root.name=Drop-In Resources Root
-param.drop-in-resources-root.description=The directory to look for bundler specific drop in resources.  If not set the classpath will be searched.
+param.resource-dir.name=Resource Dir
+param.resource-dir.description=The directory to look for bundler specific resources.
 param.secondary-launchers.name=Secondary Launchers
 param.secondary-launchers.description=A collection of bundle param info for secondary launchers
 param.file-associations.name=File Associations
@@ -124,10 +124,10 @@
 param.install-dir.name=Installation Directory
 param.install-dir.description=Installation directory of the application.
 
-message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize)
+message.using-default-resource=Using default package resource {0} {1} (add {2} to the resource-dir to customize)
+message.no-default-resource=no default package resource {0} {1} (add {2} to the resource-dir to customize)
 message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1})
-message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1})
-message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize)
+message.using-custom-resource=Using custom package resource {0} (loaded from {1})
 message.creating-app-bundle=Creating app bundle\: {0} in {1}
 message.detected.modules="Automatically adding detected modules: {0}."
 message.modules="Adding modules: {0} to runtime image."
@@ -145,11 +145,9 @@
 error.no-main-module.advice=Make sure to use fx\:module task to create modular application.
 error.srcfiles.contain.modules=Error: Modules are not allowed in srcfiles: {0}.
 error.no-main-class-with-main-jar=An application class was not specified nor was one found in the jar {0}
-error.no-main-class-with-main-jar.advice=Please specify a applicationClass or ensure that the jar {0} specifies one in the manifest.
-error.no-main-class-with-classpath=An application class was not specified nor was one found in the supplied classpath
-error.no-main-class-with-classpath.advice=Please specify a applicationClass or ensure that the classpath has a jar containing one in the manifest.
+error.no-main-class-with-main-jar.advice=Please specify a application class or ensure that the jar {0} specifies one in the manifest.
 error.no-main-class=An application class was not specified nor was one found in the supplied application resources
-error.no-main-class.advice=Please specify a applicationClass or ensure that the appResources has a jar containing one in the manifest.
+error.no-main-class.advice=Please specify a application class or ensure that the appResources has a jar containing one in the manifest.
 error.main-jar-does-not-exist=The configured main jar does not exist {0}
 error.main-jar-does-not-exist.advice=The main jar must be specified relative to the app resources (not an absolute path), and must exist within those resources.
 
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties	Fri Dec 21 07:40:47 2018 -0500
@@ -93,8 +93,8 @@
 param.verbose.description=Flag to print out more information and saves configuration files for bundlers.
 param.force.name=Force
 param.force.description=Flag to allow removal of existing Build Root contents
-param.drop-in-resources-root.name=Drop-In Resources Root
-param.drop-in-resources-root.description=The directory to look for bundler specific drop in resources.  If not set the classpath will be searched.
+param.resource-dir.name=Resource Dir
+param.resource-dir.description=The directory to look for bundler specific resources.
 param.secondary-launchers.name=Secondary Launchers
 param.secondary-launchers.description=A collection of bundle param info for secondary launchers
 param.file-associations.name=File Associations
@@ -124,10 +124,10 @@
 param.install-dir.name=Installation Directory
 param.install-dir.description=Installation directory of the application.
 
-message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize)
+message.using-default-resource=Using default package resource {0} {1} (add {2} to the resource-dir to customize)
+message.no-default-resource=no default package resource {0} {1} (add {2} to the resource-dir to customize)
 message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1})
-message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1})
-message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize)
+message.using-custom-resource=Using custom package resource {0} (loaded from {1})
 message.creating-app-bundle=Creating app bundle\: {0} in {1}
 message.detected.modules="Automatically adding detected modules: {0}."
 message.modules="Adding modules: {0} to runtime image."
@@ -145,11 +145,9 @@
 error.no-main-module.advice=Make sure to use fx\:module task to create modular application.
 error.srcfiles.contain.modules=Error: Modules are not allowed in srcfiles: {0}.
 error.no-main-class-with-main-jar=An application class was not specified nor was one found in the jar {0}
-error.no-main-class-with-main-jar.advice=Please specify a applicationClass or ensure that the jar {0} specifies one in the manifest.
-error.no-main-class-with-classpath=An application class was not specified nor was one found in the supplied classpath
-error.no-main-class-with-classpath.advice=Please specify a applicationClass or ensure that the classpath has a jar containing one in the manifest.
+error.no-main-class-with-main-jar.advice=Please specify a application class or ensure that the jar {0} specifies one in the manifest.
 error.no-main-class=An application class was not specified nor was one found in the supplied application resources
-error.no-main-class.advice=Please specify a applicationClass or ensure that the appResources has a jar containing one in the manifest.
+error.no-main-class.advice=Please specify a application class or ensure that the appResources has a jar containing one in the manifest.
 error.main-jar-does-not-exist=The configured main jar does not exist {0}
 error.main-jar-does-not-exist.advice=The main jar must be specified relative to the app resources (not an absolute path), and must exist within those resources.
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/ResourceLocator.java	Fri Dec 21 07:40:47 2018 -0500
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jpackage.internal.resources;
+
+public class ResourceLocator {
+
+}
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.WinResources;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
@@ -62,14 +60,6 @@
             },
             (s, p) -> new File(s));
 
-    public WinAppBundler() {
-        super();
-        baseResourceLoader = WinResources.class;
-    }
-
-    public final static String WIN_BUNDLER_PREFIX =
-            BUNDLER_PREFIX + "windows/";
-
     @Override
     public boolean validate(Map<String, ? super Object> params)
             throws UnsupportedPlatformException, ConfigException {
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.WinResources;
-
 import java.io.*;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
@@ -162,11 +160,6 @@
             },
             null);
 
-    public WinExeBundler() {
-        super();
-        baseResourceLoader = WinResources.class;
-    }
-
     @Override
     public String getName() {
         return getString("exe.bundler.name");
@@ -791,11 +784,10 @@
                 getConfig_ExeProjectFile(p)));
 
         String content = preprocessTextResource(
-                WinAppBundler.WIN_BUNDLER_PREFIX +
                 getConfig_ExeProjectFile(p).getName(),
                 getString("resource.inno-setup-project-file"),
                 iss, data, VERBOSE.fetchFrom(p),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(p));
+                RESOURCE_DIR.fetchFrom(p));
         w.write(content);
         w.close();
         return true;
@@ -820,20 +812,19 @@
 
         // prepare installer icon
         File iconTarget = getConfig_SmallInnoSetupIcon(p);
-        fetchResource(WinAppBundler.WIN_BUNDLER_PREFIX + iconTarget.getName(),
+        fetchResource(iconTarget.getName(),
                 getString("resource.setup-icon"),
                 DEFAULT_INNO_SETUP_ICON,
                 iconTarget,
                 VERBOSE.fetchFrom(p),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(p));
+                RESOURCE_DIR.fetchFrom(p));
 
-        fetchResource(WinAppBundler.WIN_BUNDLER_PREFIX +
-                getConfig_Script(p).getName(),
+        fetchResource(getConfig_Script(p).getName(),
                 getString("resource.post-install-script"),
                 (String) null,
                 getConfig_Script(p),
                 VERBOSE.fetchFrom(p),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(p));
+                RESOURCE_DIR.fetchFrom(p));
         return true;
     }
 
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.WinResources;
-
 import java.io.*;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
@@ -206,12 +204,6 @@
                        "null".equalsIgnoreCase(s))? false : Boolean.valueOf(s)
         );
 
-    public WinMsiBundler() {
-        super();
-        baseResourceLoader = WinResources.class;
-    }
-
-
     @Override
     public String getName() {
         return I18N.getString("msi.bundler.name");
@@ -602,13 +594,12 @@
 
     private boolean prepareBasicProjectConfig(
         Map<String, ? super Object> params) throws IOException {
-        fetchResource(WinAppBundler.WIN_BUNDLER_PREFIX +
-                getConfig_Script(params).getName(),
+        fetchResource(getConfig_Script(params).getName(),
                 I18N.getString("resource.post-install-script"),
                 (String) null,
                 getConfig_Script(params),
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         return true;
     }
 
@@ -708,11 +699,10 @@
                 new FileWriter(getConfig_ProjectFile(params)));
 
         String content = preprocessTextResource(
-                WinAppBundler.WIN_BUNDLER_PREFIX +
                 getConfig_ProjectFile(params).getName(),
                 I18N.getString("resource.wix-config-file"),
                 wxs, data, VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
         return true;
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.WinResources;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileInputStream;
@@ -253,11 +251,6 @@
     }
 
     @Override
-    public InputStream getResourceAsStream(String name) {
-        return WinResources.class.getResourceAsStream(name);
-    }
-
-    @Override
     public void prepareApplicationFiles() throws IOException {
         Map<String, ? super Object> originalParams = new HashMap<>(params);
         File rootFile = root.toFile();
@@ -323,11 +316,9 @@
 
     // TODO: do we still need this?
     private boolean copyMSVCDLLs(String VS_VER) throws IOException {
-        final InputStream REDIST_MSVCR_URL =
-                WinResources.class.getResourceAsStream(
+        final InputStream REDIST_MSVCR_URL = getResourceAsStream(
                 REDIST_MSVCR.replaceAll("VS_VER", VS_VER));
-        final InputStream REDIST_MSVCP_URL =
-                WinResources.class.getResourceAsStream(
+        final InputStream REDIST_MSVCP_URL = getResourceAsStream(
                 REDIST_MSVCP.replaceAll("VS_VER", VS_VER));
 
         if (REDIST_MSVCR_URL != null && REDIST_MSVCP_URL != null) {
@@ -377,12 +368,12 @@
 
         Writer w = new BufferedWriter(
                 new FileWriter(getConfig_ExecutableProperties(params)));
-        String content = preprocessTextResource(BUNDLER_PREFIX
-                + getConfig_ExecutableProperties(params).getName(),
+        String content = preprocessTextResource(
+                getConfig_ExecutableProperties(params).getName(),
                 I18N.getString("resource.executable-properties-template"),
                 EXECUTABLE_PROPERTIES_TEMPLATE, data,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         w.write(content);
         w.close();
     }
@@ -396,12 +387,12 @@
         File iconTarget = getConfig_AppIcon(p);
 
         InputStream in = locateResource(
-               "package/windows/" + APP_NAME.fetchFrom(params) + ".ico",
+                APP_NAME.fetchFrom(params) + ".ico",
                 "icon",
                 TEMPLATE_APP_ICON,
                 icon,
                 VERBOSE.fetchFrom(params),
-                DROP_IN_RESOURCES_ROOT.fetchFrom(params));
+                RESOURCE_DIR.fetchFrom(params));
         Files.copy(in, iconTarget.toPath());
 
         writeCfgFile(p, root.resolve(
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsBundlerParam.java	Tue Dec 18 19:31:20 2018 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsBundlerParam.java	Fri Dec 21 07:40:47 2018 -0500
@@ -25,8 +25,6 @@
 
 package jdk.jpackage.internal;
 
-import jdk.jpackage.internal.resources.WinResources;
-
 import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.function.BiFunction;
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.java	Tue Dec 18 19:31:20 2018 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jpackage.internal.resources;
-
-public class WinResources {
-
-}
Binary file src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/javalogo_white_16.ico has changed
Binary file src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/javalogo_white_32.ico has changed