8246792: Mac signing tests failed (unsealed contents present in the bundle root)

Reviewed-by: herrick, almatvee
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 4ac1418..c422c8a 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 @@
         // 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<Path> 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<String, ? super Object> 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 a424f6a..8787e34 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 @@
         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 891b943..894d0ab 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 @@
                     root,
                     "--install-location",
                     getInstallDir(params),
-                    "--filter",
-                    AppImageFile.getPathInAppImage(Path.of("")).toString(),
                     "--analyze",
                     cpl.getAbsolutePath());
 
@@ -424,8 +422,6 @@
                     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 248405b..b4feff3 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 @@
      * @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 dfaf750..6375d32 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 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 9c95e33..58407fd 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.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 @@
 
             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 @@
             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 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<Path> walk = ThrowingSupplier.toSupplier(
+                    () -> Files.walk(rootDir)).get()) {
+                List<String> appImageFiles = walk
+                        .filter(path -> path.getFileName().equals(appImageFileName))
+                        .map(Path::toString)
+                        .collect(Collectors.toList());
+                if (isImagePackageType() || TKit.isOSX()) {
+                    List<String> 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 @@
             TKit.assertFileExists(appLauncherCfgPath(null));
         }
 
+        if (TKit.isOSX()) {
+            TKit.assertFileExists(appRuntimeDirectory().resolve(
+                    "Contents/MacOS/libjli.dylib"));
+        }
+
         return this;
     }
 
@@ -785,14 +827,6 @@
         }).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<String> filterOutput(Stream<String> 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 28e1c6d..a88b640 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 @@
             }
             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<Path> 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 871d5ab..5eae560 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 @@
                 "--no-header-files",
                 "--no-man-pages");
 
+        TKit.trace("jlink output BEGIN");
+        try (Stream<Path> 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(