test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java
branchJDK-8200758-branch
changeset 58696 61c44899b4eb
parent 58695 64adf683bc7b
child 58762 0fe62353385b
--- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java	Fri Oct 18 11:00:57 2019 -0400
+++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java	Fri Oct 18 14:14:37 2019 -0400
@@ -53,7 +53,6 @@
  * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
  *  --jpt-run=jdk.jpackage.tests.MainClassTest
  *  --jpt-space-subst=_
- *  --jpt-exclude=modular=y;_main-class=n;_jar-main-class=b;_jlink=y
  */
 
 public final class MainClassTest {
@@ -64,7 +63,7 @@
         }
 
         Script modular(boolean v) {
-            appDesc.setModuleName(v ? null : "com.other");
+            appDesc.setModuleName(v ? "com.other" : null);
             return this;
         }
 
@@ -138,9 +137,12 @@
                 script.appDesc.packageName(), "ThereIsNoSuchClass").filter(
                 Objects::nonNull).collect(Collectors.joining("."));
 
-        cmd = JPackageCommand.helloAppImage(script.appDesc);
+        cmd = JPackageCommand
+                .helloAppImage(script.appDesc)
+                .ignoreDefaultRuntime(true);
         if (!script.withJLink) {
-            cmd.setFakeRuntime();
+            cmd.addArguments("--runtime-image", Path.of(System.getProperty(
+                    "java.home")));
         }
 
         final String moduleName = script.appDesc.moduleName();
@@ -173,13 +175,6 @@
             for (var modular : List.of(true, false)) {
                 for (var mainClass : Script.MainClassType.values()) {
                     for (var jarMainClass : Script.MainClassType.values()) {
-                        if (!withJLink && (jarMainClass == SetWrong || mainClass
-                                == SetWrong)) {
-                            // Without runtime can't run app to verify it will fail, so
-                            // there is no point in such testing.
-                            continue;
-                        }
-
                         Script script = new Script()
                             .modular(modular)
                             .withJLink(withJLink)
@@ -190,10 +185,10 @@
                                 || withMainClass.contains(mainClass)) {
                         } else if (modular) {
                             script.expectedErrorMessage(
-                                    "A main class was not specified nor was one found in the jar");
+                                    "Error: Main application class is missing");
                         } else {
                             script.expectedErrorMessage(
-                                    "Error: Main application class is missing");
+                                    "A main class was not specified nor was one found in the jar");
                         }
 
                         scripts.add(new Script[]{script});
@@ -250,13 +245,13 @@
         }
     }
 
-    private void initJarWithWrongMainClass() {
+    private void initJarWithWrongMainClass() throws IOException {
         // Call JPackageCommand.executePrerequisiteActions() to build app's jar.
         // executePrerequisiteActions() is called by JPackageCommand instance
         // only once.
         cmd.executePrerequisiteActions();
 
-        Path jarFile;
+        final Path jarFile;
         if (script.appDesc.moduleName() != null) {
             jarFile = Path.of(cmd.getArgumentValue("--module-path"),
                     script.appDesc.jarFileName());
@@ -264,37 +259,58 @@
             jarFile = cmd.inputDir().resolve(cmd.getArgumentValue("--main-jar"));
         }
 
-        // Create jar file with the main class attribute in manifest set to
-        // non-existing class.
+        // Create new jar file filtering out main class from the old jar file.
         TKit.withTempDirectory("repack-jar", workDir -> {
-            Path manifestFile = workDir.resolve("META-INF/MANIFEST.MF");
-            try (var jar = new JarFile(jarFile.toFile())) {
-                jar.stream()
-                .filter(Predicate.not(JarEntry::isDirectory))
-                .sequential().forEachOrdered(ThrowingConsumer.toConsumer(
-                    jarEntry -> {
-                        try (var in = jar.getInputStream(jarEntry)) {
-                            Path fileName = workDir.resolve(jarEntry.getName());
-                            Files.createDirectories(fileName.getParent());
-                            Files.copy(in, fileName);
-                        }
-                    }));
-            }
+            // Extract app's class from the old jar.
+            explodeJar(jarFile, workDir,
+                    jarEntry -> Path.of(jarEntry.getName()).equals(
+                            script.appDesc.classFilePath()));
+
+            // Create app's jar file with different main class.
+            var badAppDesc = JavaAppDesc.parse(script.appDesc.toString()).setClassName(
+                    nonExistingMainClass);
+            JPackageCommand.helloAppImage(badAppDesc).executePrerequisiteActions();
+
+            // Extract new jar but skip app's class.
+            explodeJar(jarFile, workDir,
+                    jarEntry -> !Path.of(jarEntry.getName()).equals(
+                            badAppDesc.classFilePath()));
+
+            // At this point we should have:
+            // 1. Manifest from the new jar referencing non-existing class
+            //  as the main class.
+            // 2. Module descriptor referencing non-existing class as the main
+            //  class in case of modular app.
+            // 3. App's class from the old jar. We need it to let jlink find some
+            //  classes in the package declared in module descriptor
+            //  in case of modular app.
 
             Files.delete(jarFile);
-
-            // Adjust manifest.
-            TKit.createTextFile(manifestFile, Files.readAllLines(
-                    manifestFile).stream().map(line -> line.replace(
-                    script.appDesc.className(), nonExistingMainClass)));
-
             new Executor().setToolProvider(JavaTool.JAR)
-            .addArguments("-c", "-M", "-f", jarFile.toString())
+            .addArguments("-v", "-c", "-M", "-f", jarFile.toString())
             .addArguments("-C", workDir.toString(), ".")
+            .dumpOutput()
             .execute().assertExitCodeIsZero();
         });
     }
 
+    private static void explodeJar(Path jarFile, Path workDir,
+            Predicate<JarEntry> filter) throws IOException {
+        try (var jar = new JarFile(jarFile.toFile())) {
+            jar.stream()
+            .filter(Predicate.not(JarEntry::isDirectory))
+            .filter(filter)
+            .sequential().forEachOrdered(ThrowingConsumer.toConsumer(
+                jarEntry -> {
+                    try (var in = jar.getInputStream(jarEntry)) {
+                        Path fileName = workDir.resolve(jarEntry.getName());
+                        Files.createDirectories(fileName.getParent());
+                        Files.copy(in, fileName);
+                    }
+                }));
+        }
+    }
+
     private final JPackageCommand cmd;
     private final Script script;
     private final String nonExistingMainClass;