8231277 : Adjust Linux application image layout
Submitted-by: asemenyuk
Reviewed-by: herrick, almatvee
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java Tue Sep 24 13:43:58 2019 -0400
@@ -48,12 +48,7 @@
private static final String LIBRARY_NAME = "libapplauncher.so";
final static String DEFAULT_ICON = "java32.png";
- private final Path root;
- private final Path appDir;
- private final Path appModsDir;
- private final Path runtimeDir;
- private final Path binDir;
- private final Path mdir;
+ private final ApplicationLayout appLayout;
public static final BundlerParamInfo<File> ICON_PNG =
new StandardBundlerParam<>(
@@ -70,35 +65,17 @@
},
(s, p) -> new File(s));
+ private static ApplicationLayout createAppLayout(Map<String, Object> params,
+ Path imageOutDir) {
+ return ApplicationLayout.linuxApp().resolveAt(
+ imageOutDir.resolve(APP_NAME.fetchFrom(params)));
+ }
+
public LinuxAppImageBuilder(Map<String, Object> params, Path imageOutDir)
throws IOException {
- super(params,
- imageOutDir.resolve(APP_NAME.fetchFrom(params) + "/runtime"));
-
- Objects.requireNonNull(imageOutDir);
+ super(params, createAppLayout(params, imageOutDir).runtimeDirectory());
- this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params));
- this.appDir = root.resolve("app");
- this.appModsDir = appDir.resolve("mods");
- this.runtimeDir = root.resolve("runtime");
- this.binDir = root.resolve("bin");
- this.mdir = runtimeDir.resolve("lib");
- Files.createDirectories(appDir);
- Files.createDirectories(runtimeDir);
- }
-
- public LinuxAppImageBuilder(String appName, Path imageOutDir)
- throws IOException {
- super(null, imageOutDir.resolve(appName));
-
- Objects.requireNonNull(imageOutDir);
-
- this.root = imageOutDir.resolve(appName);
- this.appDir = null;
- this.appModsDir = null;
- this.runtimeDir = null;
- this.binDir = null;
- this.mdir = null;
+ appLayout = createAppLayout(params, imageOutDir);
}
private void writeEntry(InputStream in, Path dstFile) throws IOException {
@@ -110,19 +87,31 @@
return APP_NAME.fetchFrom(params);
}
- public static String getLauncherCfgName(
- Map<String, ? super Object> params) {
- return "app" + File.separator + APP_NAME.fetchFrom(params) + ".cfg";
+ private Path getLauncherCfgPath(Map<String, ? super Object> params) {
+ return appLayout.appDirectory().resolve(
+ APP_NAME.fetchFrom(params) + ".cfg");
}
@Override
public Path getAppDir() {
- return appDir;
+ return appLayout.appDirectory();
}
@Override
public Path getAppModsDir() {
- return appModsDir;
+ return appLayout.appModsDirectory();
+ }
+
+ @Override
+ protected String getCfgAppDir() {
+ return Path.of("$APPDIR").resolve(
+ ApplicationLayout.linuxApp().appDirectory()).toString() + File.separator;
+ }
+
+ @Override
+ protected String getCfgRuntimeDir() {
+ return Path.of("$APPDIR").resolve(
+ ApplicationLayout.linuxApp().runtimeDirectory()).toString();
}
@Override
@@ -130,19 +119,20 @@
throws IOException {
Map<String, ? super Object> originalParams = new HashMap<>(params);
- try {
- IOUtils.writableOutputDir(root);
- IOUtils.writableOutputDir(binDir);
- } catch (PackagerException pe) {
- throw new RuntimeException(pe);
- }
+ appLayout.roots().stream().forEach(dir -> {
+ try {
+ IOUtils.writableOutputDir(dir);
+ } catch (PackagerException pe) {
+ throw new RuntimeException(pe);
+ }
+ });
// create the primary launcher
createLauncherForEntryPoint(params);
// Copy library to the launcher folder
try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
- writeEntry(is_lib, binDir.resolve(LIBRARY_NAME));
+ writeEntry(is_lib, appLayout.dllDirectory().resolve(LIBRARY_NAME));
}
// create the additional launchers, if any
@@ -166,8 +156,8 @@
private void createLauncherForEntryPoint(
Map<String, ? super Object> params) throws IOException {
- // Copy executable to Linux folder
- Path executableFile = binDir.resolve(getLauncherName(params));
+ // Copy executable to launchers folder
+ Path executableFile = appLayout.launchersDirectory().resolve(getLauncherName(params));
try (InputStream is_launcher =
getResourceAsStream("jpackageapplauncher")) {
writeEntry(is_launcher, executableFile);
@@ -176,14 +166,15 @@
executableFile.toFile().setExecutable(true, false);
executableFile.toFile().setWritable(true, true);
- writeCfgFile(params, root.resolve(getLauncherCfgName(params)).toFile());
+ writeCfgFile(params, getLauncherCfgPath(params).toFile());
}
private void copyIcon(Map<String, ? super Object> params)
throws IOException {
File icon = ICON_PNG.fetchFrom(params);
- File iconTarget = binDir.resolve(APP_NAME.fetchFrom(params) + ".png").toFile();
+ File iconTarget = appLayout.destktopIntegrationDirectory().resolve(
+ APP_NAME.fetchFrom(params) + ".png").toFile();
InputStream in = locateResource(
iconTarget.getName(),
@@ -205,7 +196,7 @@
}
File srcdir = appResources.getBaseDirectory();
for (String fname : appResources.getIncludedFiles()) {
- copyEntry(appDir, srcdir, fname);
+ copyEntry(appLayout.appDirectory(), srcdir, fname);
}
}
}
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java Tue Sep 24 13:43:58 2019 -0400
@@ -254,7 +254,7 @@
if (StandardBundlerParam.isRuntimeInstaller(params)) {
return ApplicationLayout.javaRuntime();
}
- return ApplicationLayout.unixApp();
+ return ApplicationLayout.linuxApp();
}
private static void validateFileAssociations(
--- a/src/jdk.jpackage/linux/native/jpackageapplauncher/launcher.cpp Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/linux/native/jpackageapplauncher/launcher.cpp Tue Sep 24 13:43:58 2019 -0400
@@ -57,7 +57,7 @@
{
std::string programPath = GetProgramPath();
std::string libraryName = dirname((char*)programPath.c_str());
- libraryName += "/libapplauncher.so";
+ libraryName += "/../lib/libapplauncher.so";
library = dlopen(libraryName.c_str(), RTLD_LAZY);
if (library == NULL) {
--- a/src/jdk.jpackage/linux/native/libapplauncher/LinuxPlatform.cpp Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/linux/native/libapplauncher/LinuxPlatform.cpp Tue Sep 24 13:43:58 2019 -0400
@@ -66,7 +66,7 @@
TString LinuxPlatform::GetPackageAppDirectory() {
return FilePath::IncludeTrailingSeparator(
- GetPackageRootDirectory()) + _T("app");
+ GetPackageRootDirectory()) + _T("lib/app");
}
TString LinuxPlatform::GetAppName() {
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java Tue Sep 24 13:43:58 2019 -0400
@@ -183,25 +183,6 @@
Files.createDirectories(runtimeDir);
}
- public MacAppImageBuilder(Map<String, Object> params, String jreName,
- Path imageOutDir) throws IOException {
- super(null, imageOutDir.resolve(jreName + "/Contents/Home"));
-
- Objects.requireNonNull(imageOutDir);
-
- this.root = imageOutDir.resolve(jreName );
- this.contentsDir = root.resolve("Contents");
- this.javaDir = null;
- this.javaModsDir = null;
- this.resourcesDir = null;
- this.macOSDir = null;
- this.runtimeDir = this.root;
- this.runtimeRoot = runtimeDir.resolve("Contents/Home");
- this.mdir = runtimeRoot.resolve("lib");
-
- Files.createDirectories(runtimeDir);
- }
-
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Files.createDirectories(dstFile.getParent());
Files.copy(in, dstFile);
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java Tue Sep 24 13:43:58 2019 -0400
@@ -71,7 +71,7 @@
public abstract Path getAppDir();
public abstract Path getAppModsDir();
- public Path getRoot() {
+ public Path getRuntimeRoot() {
return this.root;
}
@@ -175,6 +175,7 @@
public void writeCfgFile(Map<String, ? super Object> params,
File cfgFileName) throws IOException {
+ cfgFileName.getParentFile().mkdirs();
cfgFileName.delete();
File mainJar = JLinkBundlerHelper.getMainJar(params);
ModFile.ModType mainJarType = ModFile.ModType.Unknown;
@@ -247,12 +248,12 @@
return runtimeImageTop;
}
- String getCfgAppDir() {
+ protected String getCfgAppDir() {
return "$APPDIR" + File.separator
+ getAppDir().getFileName() + File.separator;
}
- String getCfgRuntimeDir() {
+ protected String getCfgRuntimeDir() {
return "$APPDIR" + File.separator + "runtime";
}
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java Tue Sep 24 13:43:58 2019 -0400
@@ -33,7 +33,7 @@
*/
final class ApplicationLayout implements PathGroup.Facade<ApplicationLayout> {
enum PathRole {
- RUNTIME, APP, LAUNCHERS_DIR, DESKTOP
+ RUNTIME, APP, LAUNCHERS, DESKTOP, APP_MODS, DLLS
}
ApplicationLayout(Map<Object, Path> paths) {
@@ -58,7 +58,14 @@
* Path to launchers directory.
*/
Path launchersDirectory() {
- return pathGroup().getPath(PathRole.LAUNCHERS_DIR);
+ return pathGroup().getPath(PathRole.LAUNCHERS);
+ }
+
+ /**
+ * Path to directory with dynamic libraries.
+ */
+ Path dllDirectory() {
+ return pathGroup().getPath(PathRole.DLLS);
}
/**
@@ -76,24 +83,33 @@
}
/**
+ * Path to application mods directory.
+ */
+ Path appModsDirectory() {
+ return pathGroup().getPath(PathRole.APP_MODS);
+ }
+
+ /**
* Path to directory with application's desktop integration files.
*/
Path destktopIntegrationDirectory() {
return pathGroup().getPath(PathRole.DESKTOP);
}
- static ApplicationLayout unixApp() {
+ static ApplicationLayout linuxApp() {
return new ApplicationLayout(Map.of(
- PathRole.LAUNCHERS_DIR, Path.of("bin"),
- PathRole.APP, Path.of("app"),
- PathRole.RUNTIME, Path.of("runtime"),
- PathRole.DESKTOP, Path.of("bin")
+ PathRole.LAUNCHERS, Path.of("bin"),
+ PathRole.APP, Path.of("lib/app"),
+ PathRole.RUNTIME, Path.of("lib/runtime"),
+ PathRole.DESKTOP, Path.of("lib"),
+ PathRole.DLLS, Path.of("lib"),
+ PathRole.APP_MODS, Path.of("lib/app/mods")
));
}
static ApplicationLayout windowsApp() {
return new ApplicationLayout(Map.of(
- PathRole.LAUNCHERS_DIR, Path.of(""),
+ PathRole.LAUNCHERS, Path.of(""),
PathRole.APP, Path.of("app"),
PathRole.RUNTIME, Path.of("runtime"),
PathRole.DESKTOP, Path.of("")
@@ -105,7 +121,7 @@
return windowsApp();
}
- return unixApp();
+ return linuxApp();
}
static ApplicationLayout javaRuntime() {
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java Tue Sep 24 13:43:58 2019 -0400
@@ -150,7 +150,7 @@
StandardBundlerParam.ADD_MODULES.fetchFrom(params);
Set<String> limitModules =
StandardBundlerParam.LIMIT_MODULES.fetchFrom(params);
- Path outputDir = imageBuilder.getRoot();
+ Path outputDir = imageBuilder.getRuntimeRoot();
File mainJar = getMainJar(params);
ModFile.ModType mainJarType = ModFile.ModType.Unknown;
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java Tue Sep 24 13:43:58 2019 -0400
@@ -24,16 +24,18 @@
*/
package jdk.jpackage.internal;
+import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.BiFunction;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
@@ -52,8 +54,8 @@
/**
* All configured entries.
*/
- Collection<Path> paths() {
- return entries.values();
+ List<Path> paths() {
+ return entries.values().stream().collect(Collectors.toList());
}
/**
@@ -61,14 +63,19 @@
*/
List<Path> roots() {
// Sort by the number of path components in ascending order.
- List<Path> sorted = paths().stream().sorted(
- (a, b) -> a.getNameCount() - b.getNameCount()).collect(
+ List<Map.Entry<Path, Path>> sorted = normalizedPaths().stream().sorted(
+ (a, b) -> a.getKey().getNameCount() - b.getKey().getNameCount()).collect(
Collectors.toList());
- return paths().stream().filter(
+ // Returns `true` if `a` is a parent of `b`
+ BiFunction<Map.Entry<Path, Path>, Map.Entry<Path, Path>, Boolean> isParentOrSelf = (a, b) -> {
+ return a == b || b.getKey().startsWith(a.getKey());
+ };
+
+ return sorted.stream().filter(
v -> v == sorted.stream().sequential().filter(
- v2 -> v == v2 || v2.endsWith(v)).findFirst().get()).collect(
- Collectors.toList());
+ v2 -> isParentOrSelf.apply(v2, v)).findFirst().get()).map(
+ v -> v.getValue()).collect(Collectors.toList());
}
long sizeInBytes() throws IOException {
@@ -132,49 +139,64 @@
private static void copy(boolean move, List<Map.Entry<Path, Path>> entries)
throws IOException {
- // Reorder entries. Entries with source entries with the least amount of
- // descending entries found between source entries should go first.
- entries.sort((e1, e2) -> e1.getKey().getNameCount() - e2.getKey().getNameCount());
+ // destination -> source file mapping
+ Map<Path, Path> actions = new HashMap<>();
+ for (var action: entries) {
+ Path src = action.getKey();
+ Path dst = action.getValue();
+ if (src.toFile().isDirectory()) {
+ Files.walk(src).forEach(path -> actions.put(dst.resolve(
+ src.relativize(path)).toAbsolutePath().normalize(), path));
+ } else {
+ actions.put(dst.toAbsolutePath().normalize(), src);
+ }
+ }
- for (var entry : entries.stream().sequential().filter(e -> {
- return e == entries.stream().sequential().filter(e2 -> isDuplicate(e2, e)).findFirst().get();
- }).collect(Collectors.toList())) {
- Path src = entry.getKey();
- Path dst = entry.getValue();
+ for (var action : actions.entrySet()) {
+ Path dst = action.getKey();
+ Path src = action.getValue();
- if (src.equals(dst)) {
+ if (src.equals(dst) || !src.toFile().exists()) {
continue;
}
- Files.createDirectories(dst.getParent());
- if (move) {
- Files.move(src, dst);
- } else if (src.toFile().isDirectory()) {
- IOUtils.copyRecursive(src, dst);
+ if (src.toFile().isDirectory()) {
+ Files.createDirectories(dst);
} else {
- IOUtils.copyFile(src.toFile(), dst.toFile());
+ Files.createDirectories(dst.getParent());
+ if (move) {
+ Files.move(src, dst);
+ } else {
+ Files.copy(src, dst);
+ }
+ }
+ }
+
+ if (move) {
+ // Delete source dirs.
+ for (var entry: entries) {
+ File srcFile = entry.getKey().toFile();
+ if (srcFile.isDirectory()) {
+ IOUtils.deleteRecursive(srcFile);
+ }
}
}
}
- private static boolean isDuplicate(Map.Entry<Path, Path> a,
- Map.Entry<Path, Path> b) {
- if (a == b || a.equals(b)) {
- return true;
+ private static Map.Entry<Path, Path> normalizedPath(Path v) {
+ final Path normalized;
+ if (!v.isAbsolute()) {
+ normalized = Path.of("./").resolve(v.normalize());
+ } else {
+ normalized = v.normalize();
}
- if (b.getKey().getNameCount() < a.getKey().getNameCount()) {
- return isDuplicate(b, a);
- }
+ return Map.entry(normalized, v);
+ }
- if (!a.getKey().endsWith(b.getKey())) {
- return false;
- }
-
- Path relativeSrcPath = a.getKey().relativize(b.getKey());
- Path relativeDstPath = a.getValue().relativize(b.getValue());
-
- return relativeSrcPath.equals(relativeDstPath);
+ private List<Map.Entry<Path, Path>> normalizedPaths() {
+ return entries.values().stream().map(PathGroup::normalizedPath).collect(
+ Collectors.toList());
}
private final Map<Object, Path> entries;
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java Tue Sep 24 13:43:58 2019 -0400
@@ -526,7 +526,7 @@
File image = appBuilder.getRuntimeImageDir(topImage);
// copy whole runtime, need to skip jmods and src.zip
final List<String> excludes = Arrays.asList("jmods", "src.zip");
- IOUtils.copyRecursive(image.toPath(), appBuilder.getRoot(), excludes);
+ IOUtils.copyRecursive(image.toPath(), appBuilder.getRuntimeRoot(), excludes);
// if module-path given - copy modules to appDir/mods
List<Path> modulePath =
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java Tue Sep 24 13:41:16 2019 -0400
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java Tue Sep 24 13:43:58 2019 -0400
@@ -127,21 +127,6 @@
Files.createDirectories(runtimeDir);
}
- public WindowsAppImageBuilder(String jreName, Path imageOutDir)
- throws IOException {
- super(null, imageOutDir.resolve(jreName));
-
- Objects.requireNonNull(imageOutDir);
-
- this.root = imageOutDir.resolve(jreName);
- this.appDir = null;
- this.appModsDir = null;
- this.runtimeDir = root;
- this.mdir = runtimeDir.resolve("lib");
- this.binDir = null;
- Files.createDirectories(runtimeDir);
- }
-
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Files.createDirectories(dstFile.getParent());
Files.copy(in, dstFile);
--- a/test/jdk/tools/jpackage/helpers/JPackageInstallerHelper.java Tue Sep 24 13:41:16 2019 -0400
+++ b/test/jdk/tools/jpackage/helpers/JPackageInstallerHelper.java Tue Sep 24 13:43:58 2019 -0400
@@ -144,100 +144,4 @@
}
}
}
-
- public static void validateStartMenu(String menuGroup, String menu, boolean exist)
- throws Exception {
- String startMenuLink = JPackagePath.getWinStartMenu() +
- File.separator + menuGroup + File.separator +
- menu + ".lnk";
-
- File link = new File(startMenuLink);
- if (exist) {
- if (!link.exists()) {
- throw new AssertionError("Cannot find " + link.getAbsolutePath());
- }
- } else {
- if (link.exists()) {
- throw new AssertionError("Error: " + link.getAbsolutePath() + " exist");
- }
- }
- }
-
- public static void validateDesktopShortcut(String name, boolean exist)
- throws Exception {
- String shortcutLink = JPackagePath.getWinPublicDesktop() +
- File.separator + name + ".lnk";
-
- File link = new File(shortcutLink);
- if (exist) {
- if (!link.exists()) {
- throw new AssertionError("Cannot find " + link.getAbsolutePath());
- }
- } else {
- if (link.exists()) {
- throw new AssertionError("Error: " + link.getAbsolutePath() + " exist");
- }
- }
- }
-
- public static void validateUserLocalStartMenu(String menuGroup, String menu, boolean exist)
- throws Exception {
- String startMenuLink = JPackagePath.getWinUserLocalStartMenu() +
- File.separator + menuGroup + File.separator +
- menu + ".lnk";
-
- File link = new File(startMenuLink);
- if (exist) {
- if (!link.exists()) {
- throw new AssertionError("Cannot find " + link.getAbsolutePath());
- }
- } else {
- if (link.exists()) {
- throw new AssertionError("Error: " + link.getAbsolutePath() + " exist");
- }
- }
- }
-
- public static void validateWinRegistry(String key, String [] values, boolean retValZero)
- throws Exception {
- File outFile = new File("regOutput.txt");
- if (outFile.exists()) {
- outFile.delete();
- }
-
- int retVal = JPackageHelper.execute(outFile, "reg.exe", "query", key);
- if (retValZero) {
- if (retVal != 0) {
- System.out.println("validateWinRegistry() key=" + key);
- if (outFile.exists()) {
- System.err.println(Files.readString(outFile.toPath()));
- }
- throw new AssertionError(
- "Reg.exe application exited with error: " + retVal);
- }
- } else {
- if (retVal == 0) {
- System.out.println("validateWinRegistry() key=" + key);
- if (outFile.exists()) {
- System.err.println(Files.readString(outFile.toPath()));
- }
- throw new AssertionError(
- "Reg.exe application exited without error: " + retVal);
- } else {
- return; // Done
- }
- }
-
- if (!outFile.exists()) {
- throw new AssertionError(outFile.getAbsolutePath() + " was not created");
- }
-
- String output = Files.readString(outFile.toPath());
- for (String value : values) {
- if (!output.contains(value)) {
- System.err.println(output);
- throw new AssertionError("Cannot find in registry: " + value);
- }
- }
- }
}
--- a/test/jdk/tools/jpackage/helpers/JPackagePath.java Tue Sep 24 13:41:16 2019 -0400
+++ b/test/jdk/tools/jpackage/helpers/JPackagePath.java Tue Sep 24 13:43:58 2019 -0400
@@ -30,18 +30,6 @@
*/
public class JPackagePath {
- // Path to Windows "Program Files" folder
- // Probably better to figure this out programattically
- private static final String WIN_PROGRAM_FILES = "C:\\Program Files";
-
- // Path to Windows Start menu items
- private static final String WIN_START_MENU =
- "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs";
-
- // Path to Windows public desktop location
- private static final String WIN_PUBLIC_DESKTOP =
- "C:\\Users\\Public\\Desktop";
-
// Return path to test src adjusted to location of caller
public static String getTestSrcRoot() {
return JPackageHelper.TEST_SRC_ROOT;
@@ -58,16 +46,7 @@
}
public static String getApp(String name) {
- if (JPackageHelper.isWindows()) {
- return Path.of("output", name, name + ".exe").toString();
- } else if (JPackageHelper.isOSX()) {
- return Path.of("output", name + ".app",
- "Contents", "MacOS", name).toString();
- } else if (JPackageHelper.isLinux()) {
- return Path.of("output", name, "bin", name).toString();
- } else {
- throw new AssertionError("Cannot detect platform");
- }
+ return getAppSL(name, name);
}
// Returns path to generate test application icon
@@ -82,7 +61,7 @@
return Path.of("output", name + ".app",
"Contents", "Resources", name + ".icns").toString();
} else if (JPackageHelper.isLinux()) {
- return Path.of("output", name, "bin", name + ".png").toString();
+ return Path.of("output", name, "lib", name + ".png").toString();
} else {
throw new AssertionError("Cannot detect platform");
}
@@ -118,7 +97,7 @@
return Path.of("output", name + ".app",
"Contents", "Java", name + ".cfg").toString();
} else if (JPackageHelper.isLinux()) {
- return Path.of("output", name, "app", name + ".cfg").toString();
+ return Path.of("output", name, "lib", "app", name + ".cfg").toString();
} else {
throw new AssertionError("Cannot detect platform");
}
@@ -131,17 +110,9 @@
public static String getRuntimeJava(String name) {
if (JPackageHelper.isWindows()) {
- return Path.of("output", name,
- "runtime", "bin", "java.exe").toString();
- } else if (JPackageHelper.isOSX()) {
- return Path.of("output", name + ".app", "Contents",
- "runtime", "Contents", "Home", "bin", "java").toString();
- } else if (JPackageHelper.isLinux()) {
- return Path.of("output", name,
- "runtime", "bin", "java").toString();
- } else {
- throw new AssertionError("Cannot detect platform");
+ return Path.of(getRuntimeBin(name), "java.exe").toString();
}
+ return Path.of(getRuntimeBin(name), "java").toString();
}
// Returns output file name generate by test application
@@ -162,45 +133,12 @@
"Contents", "runtime",
"Contents", "Home", "bin").toString();
} else if (JPackageHelper.isLinux()) {
- return Path.of("output", name, "runtime", "bin").toString();
+ return Path.of("output", name, "lib", "runtime", "bin").toString();
} else {
throw new AssertionError("Cannot detect platform");
}
}
- public static String getWinProgramFiles() {
- return WIN_PROGRAM_FILES;
- }
-
- public static String getWinUserLocal() {
- return Path.of(System.getProperty("user.home"),
- "AppData", "Local").toString();
- }
-
- public static String getWinStartMenu() {
- return WIN_START_MENU;
- }
-
- public static String getWinPublicDesktop() {
- return WIN_PUBLIC_DESKTOP;
- }
-
- public static String getWinUserLocalStartMenu() {
- return Path.of(System.getProperty("user.home"), "AppData", "Roaming",
- "Microsoft", "Windows", "Start Menu", "Programs").toString();
- }
-
- public static String getWinInstalledApp(String testName) {
- return Path.of(getWinProgramFiles(), testName,
- testName + ".exe").toString();
- }
-
- public static String getWinInstalledApp(String installDir,
- String testName) {
- return Path.of(getWinProgramFiles(), installDir,
- testName + ".exe").toString();
- }
-
public static String getOSXInstalledApp(String testName) {
return File.separator + "Applications"
+ File.separator + testName + ".app"
@@ -209,10 +147,6 @@
+ File.separator + testName;
}
- public static String getLinuxInstalledApp(String testName) {
- return Path.of("/opt", testName, "bin", testName).toString();
- }
-
public static String getOSXInstalledApp(String subDir, String testName) {
return File.separator + "Applications"
+ File.separator + subDir
@@ -222,41 +156,6 @@
+ File.separator + testName;
}
- public static String getLinuxInstalledApp(String subDir, String testName) {
- return Path.of("/opt", subDir, testName, "bin", testName).toString();
- }
-
- public static String getWinInstallFolder(String testName) {
- return getWinProgramFiles()
- + File.separator + testName;
- }
-
- public static String getLinuxInstallFolder(String testName) {
- return File.separator + "opt"
- + File.separator + testName;
- }
-
- public static String getLinuxInstallFolder(String subDir, String testName) {
- if (testName == null) {
- return File.separator + "opt"
- + File.separator + subDir;
- } else {
- return File.separator + "opt"
- + File.separator + subDir
- + File.separator + testName;
- }
- }
-
- public static String getWinUserLocalInstalledApp(String testName) {
- return getWinUserLocal()
- + File.separator + testName
- + File.separator + testName + ".exe";
- }
-
- public static String getWinUserLocalInstallFolder(String testName) {
- return getWinUserLocal() + File.separator + testName;
- }
-
// Returs path to test license file
public static String getLicenseFilePath() {
String path = JPackagePath.getTestSrcRoot()
@@ -265,11 +164,4 @@
return path;
}
-
- // Returns path to app folder of installed application
- public static String getWinInstalledAppFolder(String testName) {
- return getWinProgramFiles()
- + File.separator + testName
- + File.separator + "app";
- }
}
--- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java Tue Sep 24 13:41:16 2019 -0400
+++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java Tue Sep 24 13:43:58 2019 -0400
@@ -307,7 +307,7 @@
if (PackageType.IMAGE == packageType()) {
return null;
}
- return appInstallationDirectory().resolve("runtime");
+ return appInstallationDirectory().resolve(appRuntimePath(packageType()));
}
/**
@@ -388,8 +388,6 @@
/**
* Returns path to runtime directory relative to image directory.
*
- * Function will always return "runtime".
- *
* @throws IllegalArgumentException if command is configured for platform
* packaging
*/
@@ -399,6 +397,13 @@
throw new IllegalArgumentException("Unexpected package type");
}
+ return appRuntimePath(type);
+ }
+
+ private static Path appRuntimePath(PackageType type) {
+ if (PackageType.LINUX.contains(type)) {
+ return Path.of("lib/runtime");
+ }
return Path.of("runtime");
}
@@ -414,17 +419,18 @@
private static boolean isFakeRuntime(Path runtimeDir, String msg) {
final List<Path> criticalRuntimeFiles;
if (Test.isWindows()) {
- criticalRuntimeFiles = List.of(Path.of("server\\jvm.dll"));
+ criticalRuntimeFiles = List.of(Path.of("bin\\server\\jvm.dll"));
} else if (Test.isLinux()) {
- criticalRuntimeFiles = List.of(Path.of("server/libjvm.so"));
+ criticalRuntimeFiles = List.of(Path.of("lib/server/libjvm.so"));
} else if (Test.isOSX()) {
- criticalRuntimeFiles = List.of(Path.of("server/libjvm.dylib"));
+ criticalRuntimeFiles = List.of(Path.of("lib/server/libjvm.dylib"));
} else {
throw new IllegalArgumentException("Unknwon platform");
}
- if (criticalRuntimeFiles.stream().filter(v -> v.toFile().exists())
- .findFirst().orElse(null) == null) {
+ if (criticalRuntimeFiles.stream().filter(
+ v -> runtimeDir.resolve(v).toFile().exists()).findFirst().orElse(
+ null) == null) {
// Fake runtime
Test.trace(String.format(
"%s because application runtime directory [%s] is incomplete",
--- a/test/jdk/tools/jpackage/jdk/jpackage/internal/DeployParamsTest.java Tue Sep 24 13:41:16 2019 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2018, 2019, 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.
- *
- * 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.
- */
-
-import jdk.jpackage.internal.Arguments;
-import jdk.jpackage.internal.DeployParams;
-import jdk.jpackage.internal.PackagerException;
-import java.io.File;
-
-/*
- * @test
- * @bug 8211285
- * @summary DeployParamsTest
- * @modules jdk.jpackage
- * @modules jdk.jpackage/jdk.jpackage.internal
- * @run main/othervm -Xmx512m DeployParamsTest
- */
-public class DeployParamsTest {
-
- private static File testRoot = null;
-
- private static void setUp() {
- testRoot = new File("deployParamsTest");
- System.out.println("DeployParamsTest: " + testRoot.getAbsolutePath());
- testRoot.mkdir();
- }
-
- private static void tearDown() {
- if (testRoot != null) {
- testRoot.delete();
- }
- }
-
- private static void testValidateAppName1() throws Exception {
- DeployParams params = getParamsAppName();
-
- setAppName(params, "Test");
- params.validate();
-
- setAppName(params, "Test Name");
- params.validate();
-
- setAppName(params, "Test - Name !!!");
- params.validate();
- }
-
- private static void testValidateAppName2() throws Exception {
- DeployParams params = getParamsAppName();
-
- setAppName(params, "Test\nName");
- appName2TestHelper(params);
-
- setAppName(params, "Test\rName");
- appName2TestHelper(params);
-
- setAppName(params, "TestName\\");
- appName2TestHelper(params);
-
- setAppName(params, "Test \" Name");
- appName2TestHelper(params);
- }
-
- private static void appName2TestHelper(DeployParams params) throws Exception {
- try {
- params.validate();
- } catch (PackagerException pe) {
- if (!pe.getMessage().startsWith("Error: Invalid Application name")) {
- throw new Exception("Unexpected PackagerException received: " + pe);
- }
-
- return; // Done
- }
-
- throw new Exception("Expecting PackagerException");
- }
-
- // Returns deploy params initialized to pass all validation, except for
- // app name
- private static DeployParams getParamsAppName() {
- DeployParams params = new DeployParams();
-
- params.setOutput(testRoot);
- params.addResource(testRoot, new File(testRoot, "test.jar"));
- params.addBundleArgument(Arguments.CLIOptions.APPCLASS.getId(), "TestClass");
- params.addBundleArgument(Arguments.CLIOptions.MAIN_JAR.getId(), "test.jar");
- params.addBundleArgument(Arguments.CLIOptions.INPUT.getId(), "input");
-
- return params;
- }
-
- private static void setAppName(DeployParams params, String appName) {
- params.addBundleArgument(Arguments.CLIOptions.NAME.getId(), appName);
- }
-
- public static void main(String[] args) throws Exception {
- setUp();
-
- try {
- testValidateAppName1();
- testValidateAppName2();
- } finally {
- tearDown();
- }
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java Tue Sep 24 13:43:58 2019 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019, 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;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+import static org.junit.Assert.*;
+
+
+public class ApplicationLayoutTest {
+
+ @Rule
+ public final TemporaryFolder tempFolder = new TemporaryFolder();
+
+ private void fillLinuxAppImage() throws IOException {
+ appImage = tempFolder.newFolder("Foo").toPath();
+
+ Path base = appImage.getFileName();
+
+ tempFolder.newFolder(base.toString(), "bin");
+ tempFolder.newFolder(base.toString(), "lib", "app", "mods");
+ tempFolder.newFolder(base.toString(), "lib", "runtime", "bin");
+ tempFolder.newFile(base.resolve("bin/Foo").toString());
+ tempFolder.newFile(base.resolve("lib/app/Foo.cfg").toString());
+ tempFolder.newFile(base.resolve("lib/app/hello.jar").toString());
+ tempFolder.newFile(base.resolve("lib/Foo.png").toString());
+ tempFolder.newFile(base.resolve("lib/libapplauncher.so").toString());
+ tempFolder.newFile(base.resolve("lib/runtime/bin/java").toString());
+ }
+
+ @Test
+ public void testLinux() throws IOException {
+ fillLinuxAppImage();
+ testApplicationLayout(ApplicationLayout.linuxApp());
+ }
+
+ private void testApplicationLayout(ApplicationLayout layout) throws IOException {
+ ApplicationLayout srcLayout = layout.resolveAt(appImage);
+ assertApplicationLayout(srcLayout);
+
+ ApplicationLayout dstLayout = layout.resolveAt(
+ appImage.getParent().resolve(
+ "Copy" + appImage.getFileName().toString()));
+ srcLayout.move(dstLayout);
+ Files.deleteIfExists(appImage);
+ assertApplicationLayout(dstLayout);
+
+ dstLayout.copy(srcLayout);
+ assertApplicationLayout(srcLayout);
+ assertApplicationLayout(dstLayout);
+ }
+
+ private void assertApplicationLayout(ApplicationLayout layout) throws IOException {
+ assertTrue(Files.isRegularFile(layout.appDirectory().resolve("Foo.cfg")));
+ assertTrue(Files.isRegularFile(layout.appDirectory().resolve("hello.jar")));
+ assertTrue(Files.isDirectory(layout.appModsDirectory()));
+ assertTrue(Files.isRegularFile(layout.launchersDirectory().resolve("Foo")));
+ assertTrue(Files.isRegularFile(layout.destktopIntegrationDirectory().resolve("Foo.png")));
+ assertTrue(Files.isRegularFile(layout.dllDirectory().resolve("libapplauncher.so")));
+ assertTrue(Files.isRegularFile(layout.runtimeDirectory().resolve("bin/java")));
+ }
+
+ private Path appImage;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DeployParamsTest.java Tue Sep 24 13:43:58 2019 -0400
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2018, 2019, 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.
+ *
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Rule;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Test for JDK-8211285
+ */
+public class DeployParamsTest {
+
+ @Rule
+ public final TemporaryFolder tempFolder = new TemporaryFolder();
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() throws IOException {
+ testRoot = tempFolder.newFolder();
+ }
+
+ @Test
+ public void testValidAppName() throws PackagerException {
+ initParamsAppName();
+
+ setAppNameAndValidate("Test");
+
+ setAppNameAndValidate("Test Name");
+
+ setAppNameAndValidate("Test - Name !!!");
+ }
+
+ @Test
+ public void testInvalidAppName() throws PackagerException {
+ initForInvalidAppNamePackagerException();
+ initParamsAppName();
+ setAppNameAndValidate("Test\nName");
+ }
+
+ @Test
+ public void testInvalidAppName2() throws PackagerException {
+ initForInvalidAppNamePackagerException();
+ initParamsAppName();
+ setAppNameAndValidate("Test\rName");
+ }
+
+ @Test
+ public void testInvalidAppName3() throws PackagerException {
+ initForInvalidAppNamePackagerException();
+ initParamsAppName();
+ setAppNameAndValidate("TestName\\");
+ }
+
+ @Test
+ public void testInvalidAppName4() throws PackagerException {
+ initForInvalidAppNamePackagerException();
+ initParamsAppName();
+ setAppNameAndValidate("Test \" Name");
+ }
+
+ private void initForInvalidAppNamePackagerException() {
+ thrown.expect(PackagerException.class);
+
+ String msg = "Error: Invalid Application name";
+
+ // Unfortunately org.hamcrest.core.StringStartsWith is not available
+ // with older junit, DIY
+
+ // thrown.expectMessage(startsWith("Error: Invalid Application name"));
+ thrown.expectMessage(new BaseMatcher() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object o) {
+ if (o instanceof String) {
+ return ((String) o).startsWith(msg);
+ }
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description d) {
+ d.appendText(msg);
+ }
+ });
+ }
+
+ // Returns deploy params initialized to pass all validation, except for
+ // app name
+ private void initParamsAppName() {
+ params = new DeployParams();
+
+ params.setOutput(testRoot);
+ params.addResource(testRoot, new File(testRoot, "test.jar"));
+ params.addBundleArgument(Arguments.CLIOptions.APPCLASS.getId(),
+ "TestClass");
+ params.addBundleArgument(Arguments.CLIOptions.MAIN_JAR.getId(),
+ "test.jar");
+ params.addBundleArgument(Arguments.CLIOptions.INPUT.getId(), "input");
+ }
+
+ private void setAppNameAndValidate(String appName) throws PackagerException {
+ params.addBundleArgument(Arguments.CLIOptions.NAME.getId(), appName);
+ params.validate();
+ }
+
+ private File testRoot = null;
+ private DeployParams params;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PathGroupTest.java Tue Sep 24 13:43:58 2019 -0400
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019, 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;
+
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+
+public class PathGroupTest {
+ public PathGroupTest() {
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNullId() {
+ new PathGroup(Map.of()).getPath(null);
+ }
+
+ @Test
+ public void testEmptyPathGroup() {
+ PathGroup pg = new PathGroup(Map.of());
+
+ assertNull(pg.getPath("foo"));
+
+ assertEquals(0, pg.paths().size());
+ assertEquals(0, pg.roots().size());
+ }
+
+ @Test
+ public void testRootsSinglePath() {
+ final PathGroup pg = new PathGroup(Map.of("main", PATH_FOO));
+
+ List<Path> paths = pg.paths();
+ assertEquals(1, paths.size());
+ assertEquals(PATH_FOO, paths.iterator().next());
+
+ List<Path> roots = pg.roots();
+ assertEquals(1, roots.size());
+ assertEquals(PATH_FOO, roots.iterator().next());
+ }
+
+ @Test
+ public void testDuplicatedRoots() {
+ final PathGroup pg = new PathGroup(Map.of("main", PATH_FOO, "another",
+ PATH_FOO, "root", PATH_EMPTY));
+
+ List<Path> paths = pg.paths();
+ Collections.sort(paths);
+
+ assertEquals(3, paths.size());
+ assertEquals(PATH_EMPTY, paths.get(0));
+ assertEquals(PATH_FOO, paths.get(1));
+ assertEquals(PATH_FOO, paths.get(2));
+
+ List<Path> roots = pg.roots();
+ assertEquals(1, roots.size());
+ assertEquals(PATH_EMPTY, roots.get(0));
+ }
+
+ @Test
+ public void testRoots() {
+ final PathGroup pg = new PathGroup(Map.of(1, Path.of("foo"), 2, Path.of(
+ "foo", "bar"), 3, Path.of("foo", "bar", "buz")));
+
+ List<Path> paths = pg.paths();
+ assertEquals(3, paths.size());
+ assertTrue(paths.contains(Path.of("foo")));
+ assertTrue(paths.contains(Path.of("foo", "bar")));
+ assertTrue(paths.contains(Path.of("foo", "bar", "buz")));
+
+ List<Path> roots = pg.roots();
+ assertEquals(1, roots.size());
+ assertEquals(Path.of("foo"), roots.get(0));
+ }
+
+ @Test
+ public void testResolveAt() {
+ final PathGroup pg = new PathGroup(Map.of(0, PATH_FOO, 1, PATH_BAR, 2,
+ PATH_EMPTY));
+
+ final Path aPath = Path.of("a");
+
+ final PathGroup pg2 = pg.resolveAt(aPath);
+ assertThat(pg, not(equalTo(pg2)));
+
+ List<Path> paths = pg.paths();
+ assertEquals(3, paths.size());
+ assertTrue(paths.contains(PATH_EMPTY));
+ assertTrue(paths.contains(PATH_FOO));
+ assertTrue(paths.contains(PATH_BAR));
+ assertEquals(PATH_EMPTY, pg.roots().get(0));
+
+ paths = pg2.paths();
+ assertEquals(3, paths.size());
+ assertTrue(paths.contains(aPath.resolve(PATH_EMPTY)));
+ assertTrue(paths.contains(aPath.resolve(PATH_FOO)));
+ assertTrue(paths.contains(aPath.resolve(PATH_BAR)));
+ assertEquals(aPath, pg2.roots().get(0));
+ }
+
+ private final static Path PATH_FOO = Path.of("foo");
+ private final static Path PATH_BAR = Path.of("bar");
+ private final static Path PATH_EMPTY = Path.of("");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/junit/junit.java Tue Sep 24 13:43:58 2019 -0400
@@ -0,0 +1,9 @@
+/*
+ * @test
+ * @summary jpackage unit tests
+ * @library ${jtreg.home}/lib/junit.jar
+ * @run shell run_junit.sh
+ * jdk.jpackage.internal.PathGroupTest
+ * jdk.jpackage.internal.DeployParamsTest
+ * jdk.jpackage.internal.ApplicationLayoutTest
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/junit/run_junit.sh Tue Sep 24 13:43:58 2019 -0400
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+set -x
+
+set -e
+if [ -z "$BASH" ]; then
+ # The script relies on Bash arrays, rerun in Bash.
+ /bin/bash $0 $@
+ exit
+fi
+
+classes=( "$@" )
+sources=()
+for c in "${classes[@]}"; do
+ sources+=( "${TESTSRC}/$(echo $c | sed -e 's|\.|/|g').java" )
+done
+
+common_args=(\
+ --patch-module jdk.jpackage="${TESTSRC}${PS}${TESTCLASSES}" \
+ --add-reads jdk.jpackage=ALL-UNNAMED \
+ --add-exports jdk.jpackage/jdk.jpackage.internal=ALL-UNNAMED \
+ -classpath "${TESTCLASSPATH}" \
+)
+
+# Compile classes for junit
+"${COMPILEJAVA}/bin/javac" ${TESTTOOLVMOPTS} ${TESTJAVACOPTS} \
+ "${common_args[@]}" -d "${TESTCLASSES}" "${sources[@]}"
+
+# Run junit
+"${TESTJAVA}/bin/java" ${TESTVMOPTS} ${TESTJAVAOPTS} \
+ "${common_args[@]}" org.junit.runner.JUnitCore "$@"
--- a/test/jdk/tools/jpackage/linux/BundleNameTest.java Tue Sep 24 13:41:16 2019 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2019, 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.
- *
- * 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.
- */
-
-import jdk.jpackage.test.Test;
-import jdk.jpackage.test.PackageTest;
-import jdk.jpackage.test.PackageType;
-
-
-/**
- * Test --linux-package-name parameter. Output of the test should be
- * quickbrownfox2_1.0-1_amd64.deb or quickbrownfox2-1.0-1.amd64.rpm package
- * bundle. The output package should provide the same functionality as the
- * default package.
- *
- * deb:
- * Package property of the package should be set to quickbrownfox2.
- *
- * rpm:
- * Name property of the package should be set to quickbrownfox2.
- */
-
-
-/*
- * @test
- * @summary jpackage with --linux-package-name
- * @library ../helpers
- * @requires (os.family == "linux")
- * @modules jdk.jpackage/jdk.jpackage.internal
- * @run main/othervm/timeout=360 -Xmx512m BundleNameTest
- */
-public class BundleNameTest {
-
- public static void main(String[] args) {
- final String PACKAGE_NAME = "quickbrownfox2";
-
- Test.run(args, () -> {
- new PackageTest()
- .forTypes(PackageType.LINUX)
- .configureHelloApp()
- .addInitializer(cmd -> {
- cmd.addArguments("--linux-package-name", PACKAGE_NAME);
- })
- .forTypes(PackageType.LINUX_DEB)
- .addBundlePropertyVerifier("Package", PACKAGE_NAME)
- .forTypes(PackageType.LINUX_RPM)
- .addBundlePropertyVerifier("Name", PACKAGE_NAME)
- .run();
- });
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java Tue Sep 24 13:43:58 2019 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ * 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.
+ */
+
+import jdk.jpackage.test.Test;
+import jdk.jpackage.test.PackageTest;
+import jdk.jpackage.test.PackageType;
+
+
+/**
+ * Test --linux-package-name parameter. Output of the test should be
+ * quickbrownfox2_1.0-1_amd64.deb or quickbrownfox2-1.0-1.amd64.rpm package
+ * bundle. The output package should provide the same functionality as the
+ * default package.
+ *
+ * deb:
+ * Package property of the package should be set to quickbrownfox2.
+ *
+ * rpm:
+ * Name property of the package should be set to quickbrownfox2.
+ */
+
+
+/*
+ * @test
+ * @summary jpackage with --linux-package-name
+ * @library ../helpers
+ * @requires (os.family == "linux")
+ * @modules jdk.jpackage/jdk.jpackage.internal
+ * @run main/othervm/timeout=360 -Xmx512m LinuxBundleNameTest
+ */
+public class LinuxBundleNameTest {
+
+ public static void main(String[] args) {
+ final String PACKAGE_NAME = "quickbrownfox2";
+
+ Test.run(args, () -> {
+ new PackageTest()
+ .forTypes(PackageType.LINUX)
+ .configureHelloApp()
+ .addInitializer(cmd -> {
+ cmd.addArguments("--linux-package-name", PACKAGE_NAME);
+ })
+ .forTypes(PackageType.LINUX_DEB)
+ .addBundlePropertyVerifier("Package", PACKAGE_NAME)
+ .forTypes(PackageType.LINUX_RPM)
+ .addBundlePropertyVerifier("Name", PACKAGE_NAME)
+ .run();
+ });
+ }
+}