--- old/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java 2019-07-03 08:54:19.619482000 -0400 +++ new/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java 2019-07-03 08:54:17.511441300 -0400 @@ -57,7 +57,6 @@ private final Path root; private final Path appDir; private final Path appModsDir; - private final String relativeModsDir; private final Path runtimeDir; private final Path binDir; private final Path mdir; @@ -89,7 +88,6 @@ this.root = imageOutDir.resolve(APP_NAME.fetchFrom(config)); this.appDir = root.resolve("app"); this.appModsDir = appDir.resolve("mods"); - this.relativeModsDir = "app/mods"; this.runtimeDir = root.resolve("runtime"); this.binDir = root.resolve("bin"); this.mdir = runtimeDir.resolve("lib"); @@ -109,7 +107,6 @@ this.root = imageOutDir.resolve(appName); this.appDir = null; this.appModsDir = null; - this.relativeModsDir = null; this.runtimeDir = null; this.binDir = null; this.mdir = null; @@ -153,11 +150,6 @@ } @Override - public String getRelativeModsDir() { - return relativeModsDir; - } - - @Override public void prepareApplicationFiles() throws IOException { Map originalParams = new HashMap<>(params); @@ -206,8 +198,7 @@ executableFile.toFile().setExecutable(true, false); executableFile.toFile().setWritable(true, true); - writeCfgFile(params, root.resolve(getLauncherCfgName(params)).toFile(), - "$APPDIR/runtime"); + writeCfgFile(params, root.resolve(getLauncherCfgName(params)).toFile()); } private void copyIcon() throws IOException { --- old/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java 2019-07-03 08:54:31.278307900 -0400 +++ new/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java 2019-07-03 08:54:28.808460000 -0400 @@ -76,7 +76,6 @@ private final Path contentsDir; private final Path javaDir; private final Path javaModsDir; - private final String relativeModsDir; private final Path resourcesDir; private final Path macOSDir; private final Path runtimeDir; @@ -176,7 +175,6 @@ this.contentsDir = root.resolve("Contents"); this.javaDir = contentsDir.resolve("Java"); this.javaModsDir = javaDir.resolve("mods"); - this.relativeModsDir = "Java/mods"; this.resourcesDir = contentsDir.resolve("Resources"); this.macOSDir = contentsDir.resolve("MacOS"); this.runtimeDir = contentsDir.resolve("runtime"); @@ -199,7 +197,6 @@ this.contentsDir = root.resolve("Contents"); this.javaDir = null; this.javaModsDir = null; - this.relativeModsDir = null; this.resourcesDir = null; this.macOSDir = null; this.runtimeDir = this.root; @@ -278,11 +275,6 @@ } @Override - public String getRelativeModsDir() { - return relativeModsDir; - } - - @Override public void prepareApplicationFiles() throws IOException { Map originalParams = new HashMap<>(params); // Generate PkgInfo @@ -303,7 +295,7 @@ executable.toFile().setExecutable(true, false); // generate main app launcher config file File cfg = new File(root.toFile(), getLauncherCfgName(params)); - writeCfgFile(params, cfg, "$APPDIR/runtime"); + writeCfgFile(params, cfg); // create additional app launcher(s) and config file(s) List> entryPoints = @@ -321,7 +313,7 @@ // add config file for add launcher cfg = new File(root.toFile(), getLauncherCfgName(tmp)); - writeCfgFile(tmp, cfg, "$APPDIR/runtime"); + writeCfgFile(tmp, cfg); } // Copy class path entries to Java folder @@ -489,7 +481,7 @@ COPYRIGHT.fetchFrom(params) != null ? COPYRIGHT.fetchFrom(params) : "Unknown"); data.put("DEPLOY_LAUNCHER_NAME", getLauncherName(params)); - data.put("DEPLOY_JAVA_RUNTIME_NAME", "$APPDIR/runtime"); + data.put("DEPLOY_JAVA_RUNTIME_NAME", getCfgRuntimeDir()); data.put("DEPLOY_BUNDLE_SHORT_VERSION", VERSION.fetchFrom(params) != null ? VERSION.fetchFrom(params) : "1.0.0"); @@ -539,14 +531,8 @@ data.put("DEPLOY_LAUNCHER_CLASS", MAIN_CLASS.fetchFrom(params)); - StringBuilder macroedPath = new StringBuilder(); - for (String s : CLASSPATH.fetchFrom(params).split("[ ;:]+")) { - macroedPath.append(s); - macroedPath.append(":"); - } - macroedPath.deleteCharAt(macroedPath.length() - 1); - - data.put("DEPLOY_APP_CLASSPATH", macroedPath.toString()); + data.put("DEPLOY_APP_CLASSPATH", + getCfgClassPath(CLASSPATH.fetchFrom(params))); StringBuilder bundleDocumentTypes = new StringBuilder(); StringBuilder exportedTypes = new StringBuilder(); --- old/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java 2019-07-03 08:54:42.901932800 -0400 +++ new/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java 2019-07-03 08:54:40.356083600 -0400 @@ -68,7 +68,6 @@ public abstract void prepareJreFiles() throws IOException; public abstract Path getAppDir(); public abstract Path getAppModsDir(); - public abstract String getRelativeModsDir(); public Path getRoot() { return this.root; @@ -173,7 +172,7 @@ } public void writeCfgFile(Map params, - File cfgFileName, String runtimeLocation) throws IOException { + File cfgFileName) throws IOException { cfgFileName.delete(); File mainJar = JLinkBundlerHelper.getMainJar(params); ModFile.ModType mainJarType = ModFile.ModType.Unknown; @@ -189,9 +188,10 @@ out.println("[Application]"); out.println("app.name=" + APP_NAME.fetchFrom(params)); out.println("app.version=" + VERSION.fetchFrom(params)); - out.println("app.runtime=" + runtimeLocation); + out.println("app.runtime=" + getCfgRuntimeDir()); out.println("app.identifier=" + IDENTIFIER.fetchFrom(params)); - out.println("app.classpath=" + CLASSPATH.fetchFrom(params)); + out.println("app.classpath=" + + getCfgClassPath(CLASSPATH.fetchFrom(params))); // The main app is required to be a jar, modular or unnamed. if (mainModule != null && @@ -204,12 +204,12 @@ // legacy way and the main class string must be // of the format com/foo/Main if (mainJar != null) { - out.println("app.mainjar=" + out.println("app.mainjar=" + getCfgAppDir() + mainJar.toPath().getFileName().toString()); } if (mainClass != null) { out.println("app.mainclass=" - + mainClass.replaceAll("\\.", "/")); + + mainClass.replace("\\", "/")); } } @@ -223,7 +223,7 @@ if (modsDir != null && modsDir.toFile().exists()) { out.println("--module-path"); - out.println("$APPDIR/" + getRelativeModsDir()); + out.println(getCfgAppDir().replace("\\","/") + "mods"); } out.println(); @@ -241,4 +241,29 @@ } } + String getCfgAppDir() { + return "$APPDIR" + File.separator + + getAppDir().getFileName() + File.separator; + } + + String getCfgRuntimeDir() { + return "$APPDIR" + File.separator + "runtime"; + } + + String getCfgClassPath(String classpath) { + String cfgAppDir = getCfgAppDir(); + + StringBuilder sb = new StringBuilder(); + for (String path : classpath.split("[:;]")) { + if (path.length() > 0) { + sb.append(cfgAppDir); + sb.append(path); + sb.append(File.pathSeparator); + } + } + if (sb.length() > 0) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } } --- old/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java 2019-07-03 08:54:53.886945500 -0400 +++ new/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java 2019-07-03 08:54:51.855906200 -0400 @@ -461,7 +461,7 @@ validateArguments(); - addResources(deployParams, input); + addResources(deployParams, input, mainJarPath); List> launchersAsMap = new ArrayList<>(); @@ -647,7 +647,7 @@ } private void addResources(DeployParams deployParams, - String inputdir) throws PackagerException { + String inputdir, String mainJar) throws PackagerException { if (inputdir == null || inputdir.isEmpty()) { return; @@ -672,7 +672,7 @@ } fileNames.forEach(file -> deployParams.addResource(baseDir, file)); - deployParams.setClasspath(); + deployParams.setClasspath(mainJar); } static CLIOptions toCLIOption(String arg) { --- old/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java 2019-07-03 08:55:04.093943400 -0400 +++ new/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java 2019-07-03 08:55:02.219907200 -0400 @@ -112,12 +112,20 @@ baseDir, new LinkedHashSet<>(expandFileset(file)))); } - void setClasspath() { - String classpath = ""; + void setClasspath(String mainJarPath) { + String classpath; + // we want main jar first on the classpath + if (mainJarPath != null) { + classpath = mainJarPath + File.pathSeparator; + } else { + classpath = ""; + } for (RelativeFileSet resource : resources) { for (String file : resource.getIncludedFiles()) { if (file.endsWith(".jar")) { - classpath += file + File.pathSeparator; + if (!file.equals(mainJarPath)) { + classpath += file + File.pathSeparator; + } } } } --- old/src/jdk.jpackage/share/native/libapplauncher/Package.cpp 2019-07-03 08:55:14.156538200 -0400 +++ new/src/jdk.jpackage/share/native/libapplauncher/Package.cpp 2019-07-03 08:55:12.232700800 -0400 @@ -78,9 +78,7 @@ // Main JAR. config->GetValue(keys[CONFIG_SECTION_APPLICATION], keys[CONFIG_MAINJAR_KEY], FBootFields->FMainJar); - FBootFields->FMainJar = - FilePath::IncludeTrailingSeparator(GetPackageAppDirectory()) - + FilePath::FixPathForPlatform(FBootFields->FMainJar); + FBootFields->FMainJar = FilePath::FixPathForPlatform(FBootFields->FMainJar); // Main Module. config->GetValue(keys[CONFIG_SECTION_APPLICATION], --- old/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java 2019-07-03 08:55:24.342935300 -0400 +++ new/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java 2019-07-03 08:55:22.451298600 -0400 @@ -74,7 +74,6 @@ private final Path root; private final Path appDir; private final Path appModsDir; - private final String relativeModsDir; private final Path runtimeDir; private final Path mdir; private final Path binDir; @@ -125,7 +124,6 @@ this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params)); this.appDir = root.resolve("app"); this.appModsDir = appDir.resolve("mods"); - this.relativeModsDir = "app/mods"; this.runtimeDir = root.resolve("runtime"); this.mdir = runtimeDir.resolve("lib"); this.binDir = root.resolve("bin"); @@ -143,7 +141,6 @@ this.root = imageOutDir.resolve(jreName); this.appDir = null; this.appModsDir = null; - this.relativeModsDir = null; this.runtimeDir = root; this.mdir = runtimeDir.resolve("lib"); this.binDir = null; @@ -200,11 +197,6 @@ } @Override - public String getRelativeModsDir() { - return relativeModsDir; - } - - @Override public void prepareApplicationFiles() throws IOException { Map originalParams = new HashMap<>(params); @@ -322,7 +314,7 @@ StandardCopyOption.REPLACE_EXISTING); writeCfgFile(params, root.resolve( - getLauncherCfgName(params)).toFile(), "$APPDIR\\runtime"); + getLauncherCfgName(params)).toFile()); prepareExecutableProperties(params);