diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java index 4ac1418d480..c422c8a78f8 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java @@ -310,6 +310,19 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder { // generate java runtime info.plist writeRuntimeInfoPlist( runtimeDir.resolve("Contents/Info.plist").toFile(), params); + + // copy library + Path runtimeMacOSDir = Files.createDirectories( + runtimeDir.resolve("Contents/MacOS")); + + final Path jliName = Path.of("libjli.dylib"); + try (Stream walk = Files.walk(runtimeRoot.resolve("lib"))) { + final Path jli = walk + .filter(file -> file.getFileName().equals(jliName)) + .findFirst() + .get(); + Files.copy(jli, runtimeMacOSDir.resolve(jliName)); + } } private void sign(Map params) throws IOException { diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java index a424f6a73bd..8787e345168 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java @@ -336,10 +336,6 @@ public class MacDmgBundler extends MacBaseInstallerBundler { File mountedRoot = new File(imagesRoot.getAbsolutePath(), APP_NAME.fetchFrom(params)); try { - Files.deleteIfExists(AppImageFile.getPathInAppImage( - mountedRoot.toPath().resolve(APP_NAME.fetchFrom(params) - + ".app"))); - // background image File bgdir = new File(mountedRoot, BACKGROUND_IMAGE_FOLDER); bgdir.mkdirs(); diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java index 891b9434473..894d0ab817d 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java @@ -407,8 +407,6 @@ public class MacPkgBundler extends MacBaseInstallerBundler { root, "--install-location", getInstallDir(params), - "--filter", - AppImageFile.getPathInAppImage(Path.of("")).toString(), "--analyze", cpl.getAbsolutePath()); @@ -424,8 +422,6 @@ public class MacPkgBundler extends MacBaseInstallerBundler { root, "--install-location", getInstallDir(params), - "--filter", - AppImageFile.getPathInAppImage(Path.of("")).toString(), "--component-plist", cpl.getAbsolutePath(), "--scripts", diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java index 248405b07d8..b4feff36f8e 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java +++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java @@ -95,7 +95,10 @@ public class AppImageFile { * @param appImageDir - path to application image */ public static Path getPathInAppImage(Path appImageDir) { - return appImageDir.resolve(FILENAME); + return ApplicationLayout.platformAppImage() + .resolveAt(appImageDir) + .appDirectory() + .resolve(FILENAME); } /** diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java index dfaf7502a03..6375d32ad54 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java +++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java @@ -251,6 +251,7 @@ public class IOUtils { public static void createXml(Path dstFile, XmlConsumer xmlConsumer) throws IOException { XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance(); + Files.createDirectories(dstFile.getParent()); try (Writer w = Files.newBufferedWriter(dstFile)) { // Wrap with pretty print proxy XMLStreamWriter xml = (XMLStreamWriter) Proxy.newProxyInstance( diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 9c95e336697..58407fd8279 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -38,6 +38,7 @@ import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.incubator.jpackage.internal.AppImageFile; import jdk.incubator.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingFunction; @@ -235,9 +236,7 @@ public final class JPackageCommand extends CommandArguments { Files.createDirectories(fakeRuntimeDir); - if (TKit.isWindows() || TKit.isLinux()) { - // Needed to make WindowsAppBundler happy as it copies MSVC dlls - // from `bin` directory. + if (TKit.isLinux()) { // Need to make the code in rpm spec happy as it assumes there is // always something in application image. fakeRuntimeDir.resolve("bin").toFile().mkdir(); @@ -246,7 +245,7 @@ public final class JPackageCommand extends CommandArguments { if (TKit.isOSX()) { // Make MacAppImageBuilder happy createBulkFile.accept(fakeRuntimeDir.resolve(Path.of( - "Contents/Home/lib/jli/libjli.dylib"))); + "lib/jli/libjli.dylib"))); } // Mak sure fake runtime takes some disk space. @@ -680,6 +679,44 @@ public final class JPackageCommand extends CommandArguments { public JPackageCommand assertImageCreated() { verifyIsOfType(PackageType.IMAGE); + assertAppLayout(); + return this; + } + + JPackageCommand assertAppLayout() { + if (isPackageUnpacked() || isImagePackageType()) { + final Path rootDir = isPackageUnpacked() ? pathToUnpackedPackageFile( + appInstallationDirectory()) : outputBundle(); + final Path appImageFileName = AppImageFile.getPathInAppImage( + Path.of("")).getFileName(); + try (Stream walk = ThrowingSupplier.toSupplier( + () -> Files.walk(rootDir)).get()) { + List appImageFiles = walk + .filter(path -> path.getFileName().equals(appImageFileName)) + .map(Path::toString) + .collect(Collectors.toList()); + if (isImagePackageType() || TKit.isOSX()) { + List expected = List.of( + AppImageFile.getPathInAppImage(rootDir).toString()); + TKit.assertStringListEquals(expected, appImageFiles, + String.format( + "Check there is only one file with [%s] name in the package", + appImageFileName)); + } else { + TKit.assertStringListEquals(List.of(), appImageFiles, + String.format( + "Check there are no files with [%s] name in the package", + appImageFileName)); + } + } + } else if (TKit.isOSX()) { + TKit.assertFileExists(AppImageFile.getPathInAppImage( + appInstallationDirectory())); + } else { + TKit.assertPathExists(AppImageFile.getPathInAppImage( + appInstallationDirectory()), false); + } + TKit.assertDirectoryExists(appRuntimeDirectory()); if (!isRuntime()) { @@ -687,6 +724,11 @@ public final class JPackageCommand extends CommandArguments { TKit.assertFileExists(appLauncherCfgPath(null)); } + if (TKit.isOSX()) { + TKit.assertFileExists(appRuntimeDirectory().resolve( + "Contents/MacOS/libjli.dylib")); + } + return this; } @@ -785,14 +827,6 @@ public final class JPackageCommand extends CommandArguments { }).collect(Collectors.joining(" ")); } - public static Path relativePathInRuntime(JavaTool tool) { - Path path = tool.relativePathInJavaHome(); - if (TKit.isOSX()) { - path = Path.of("Contents/Home").resolve(path); - } - return path; - } - public static Stream filterOutput(Stream jpackageOutput) { // Skip "WARNING: Using incubator ..." first line of output return jpackageOutput.skip(1); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index 28e1c6d178a..a88b6401c68 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -553,30 +553,14 @@ public final class PackageTest extends RunnablePackageTest { } TKit.trace(String.format(formatString, cmd.getPrintableCommandLine())); - TKit.assertDirectoryExists(cmd.appRuntimeDirectory()); if (!cmd.isRuntime()) { - TKit.assertExecutableFileExists(cmd.appLauncherPath()); - if (PackageType.WINDOWS.contains(cmd.packageType()) && !cmd.isPackageUnpacked( "Not verifying desktop integration")) { new WindowsHelper.DesktopIntegrationVerifier(cmd); } } - - if (cmd.isPackageUnpacked()) { - final Path appImageFile = AppImageFile.getPathInAppImage( - Path.of("")); - try (Stream walk = ThrowingSupplier.toSupplier( - () -> Files.walk(cmd.unpackedPackageDirectory())).get()) { - walk.filter(path -> path.getFileName().equals(appImageFile)) - .findFirst() - .ifPresent(path -> TKit.assertPathExists(path, false)); - } - } else { - TKit.assertPathExists(AppImageFile.getPathInAppImage( - cmd.appInstallationDirectory()), false); - } + cmd.assertAppLayout(); installVerifiers.forEach(v -> v.accept(cmd)); } diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java index 871d5abb281..5eae5608f99 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java @@ -335,6 +335,15 @@ public final class BasicTest { "--no-header-files", "--no-man-pages"); + TKit.trace("jlink output BEGIN"); + try (Stream paths = Files.walk(runtimeDir)) { + paths.filter(Files::isRegularFile) + .map(runtimeDir::relativize) + .map(Path::toString) + .forEach(TKit::trace); + } + TKit.trace("jlink output END"); + if (moduleName != null) { jlink.addArguments("--add-modules", moduleName, "--module-path", Path.of(cmd.getArgumentValue("--module-path")).resolve(