< prev index next >

test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java

Print this page
*** 1,7 ***
--- 1,8 ---
  /*
   * Copyright (c) 2024, Red Hat, Inc.
+  * Copyright (c) 2025, 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.

*** 29,10 ***
--- 30,14 ---
  import java.nio.file.attribute.BasicFileAttributes;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.List;
+ import java.util.Random;
+ import java.util.Set;
+ import java.util.function.Predicate;
+ import java.util.stream.Collectors;
  
  import tests.Helper;
  import tests.JImageGenerator;
  
  

*** 45,13 ***
   * @enablePreview
   * @modules java.base/jdk.internal.jimage
   *          jdk.jlink/jdk.tools.jlink.internal
   *          jdk.jlink/jdk.tools.jlink.plugin
   *          jdk.jlink/jdk.tools.jimage
   * @build tests.* jdk.test.lib.process.OutputAnalyzer
   *        jdk.test.lib.process.ProcessTools
!  * @run main/othervm/timeout=1200 -Xmx1g PackagedModulesVsRuntimeImageLinkTest
   */
  public class PackagedModulesVsRuntimeImageLinkTest extends AbstractLinkableRuntimeTest {
  
      public static void main(String[] args) throws Exception {
          PackagedModulesVsRuntimeImageLinkTest test = new PackagedModulesVsRuntimeImageLinkTest();
--- 50,14 ---
   * @enablePreview
   * @modules java.base/jdk.internal.jimage
   *          jdk.jlink/jdk.tools.jlink.internal
   *          jdk.jlink/jdk.tools.jlink.plugin
   *          jdk.jlink/jdk.tools.jimage
+  *          jdk.jlink
   * @build tests.* jdk.test.lib.process.OutputAnalyzer
   *        jdk.test.lib.process.ProcessTools
!  * @run main/othervm/timeout=1200 -ea -esa -DDISABLE_PREVIEW_PATCHING=false -Xmx1g PackagedModulesVsRuntimeImageLinkTest
   */
  public class PackagedModulesVsRuntimeImageLinkTest extends AbstractLinkableRuntimeTest {
  
      public static void main(String[] args) throws Exception {
          PackagedModulesVsRuntimeImageLinkTest test = new PackagedModulesVsRuntimeImageLinkTest();

*** 68,11 ***
                  .validatingModule("java.se");
          if (isLinkableRuntime) {
              builder.setLinkableRuntime();
          }
          Path javaSEruntimeLink = createJavaImageRuntimeLink(builder.build());
- 
          // create a java.se using packaged modules (jmod-full)
          Path javaSEJmodFull = JImageGenerator.getJLinkTask()
                  .output(helper.createNewImageDir("java-se-jmodfull"))
                  .addMods("java.se").call().assertSuccess();
  
--- 74,10 ---

*** 118,13 ***
          // and offset differences in container bytes)
          Path jimageJmodLess = javaSEJmodLess.resolve(Path.of("lib")).resolve(Path.of("modules"));
          Path jimageJmodFull = javaSEJmodFull.resolve(Path.of("lib")).resolve(Path.of("modules"));
          List<String> jimageContentJmodLess = JImageHelper.listContents(jimageJmodLess);
          List<String> jimageContentJmodFull = JImageHelper.listContents(jimageJmodFull);
!         if (jimageContentJmodLess.size() != jimageContentJmodFull.size()) {
!             throw new AssertionError(String.format("Size of jimage content differs for jmod-less (%d) v. jmod-full (%d)", jimageContentJmodLess.size(), jimageContentJmodFull.size()));
-         }
          for (int i = 0; i < jimageContentJmodFull.size(); i++) {
              if (!jimageContentJmodFull.get(i).equals(jimageContentJmodLess.get(i))) {
                  throw new AssertionError(String.format("Jimage content differs at index %d: jmod-full was: '%s' jmod-less was: '%s'",
                                                         i,
                                                         jimageContentJmodFull.get(i),
--- 123,12 ---
          // and offset differences in container bytes)
          Path jimageJmodLess = javaSEJmodLess.resolve(Path.of("lib")).resolve(Path.of("modules"));
          Path jimageJmodFull = javaSEJmodFull.resolve(Path.of("lib")).resolve(Path.of("modules"));
          List<String> jimageContentJmodLess = JImageHelper.listContents(jimageJmodLess);
          List<String> jimageContentJmodFull = JImageHelper.listContents(jimageJmodFull);
!         assertSameContent("jmod-less", jimageContentJmodLess, "jmod-full", jimageContentJmodFull);
!         // Both lists are same size, with same names, so enumerate either.
          for (int i = 0; i < jimageContentJmodFull.size(); i++) {
              if (!jimageContentJmodFull.get(i).equals(jimageContentJmodLess.get(i))) {
                  throw new AssertionError(String.format("Jimage content differs at index %d: jmod-full was: '%s' jmod-less was: '%s'",
                                                         i,
                                                         jimageContentJmodFull.get(i),

*** 143,12 ***
                  throw new AssertionError("Content bytes mismatch for " + loc);
              }
          }
      }
  
      private static boolean isTreeInfoResource(String path) {
!         return path.startsWith("/packages") || path.startsWith("/modules");
      }
  
      private static void handleFileMismatch(Path a, Path b) {
          throw new AssertionError("Files mismatch: " + a + " vs. " + b);
      }
--- 147,41 ---
                  throw new AssertionError("Content bytes mismatch for " + loc);
              }
          }
      }
  
+     // Helper to assert the content of two jimage files are the same and provide
+     // useful debug information otherwise.
+     private static void assertSameContent(
+             String lhsLabel, List<String> lhsNames, String rhsLabel, List<String> rhsNames) {
+ 
+         List<String> lhsOnly =
+                 lhsNames.stream().filter(Predicate.not(Set.copyOf(rhsNames)::contains)).toList();
+         List<String> rhsOnly =
+                 rhsNames.stream().filter(Predicate.not(Set.copyOf(lhsNames)::contains)).toList();
+         if (!lhsOnly.isEmpty() || !rhsOnly.isEmpty()) {
+             String message = String.format(
+                     "jimage content differs for %s (%d) v. %s (%d)",
+                     lhsLabel, lhsNames.size(), rhsLabel, rhsNames.size());
+             if (!lhsOnly.isEmpty()) {
+                 message += "\nOnly in " + lhsLabel + ":\n\t" + String.join("\n\t", lhsOnly);
+             }
+             if (!rhsOnly.isEmpty()) {
+                 message += "\nOnly in " + rhsLabel + ":\n\t" + String.join("\n\t", rhsOnly);
+             }
+             throw new AssertionError(message);
+         }
+     }
+ 
      private static boolean isTreeInfoResource(String path) {
!         return pathStartsWith(path, "/packages") || pathStartsWith(path, "/modules");
+     }
+ 
+     // Handle both "<prefix>" and "<prefix>/...".
+     private static boolean pathStartsWith(String path, String prefix) {
+         int plen = prefix.length();
+         return path.startsWith(prefix) && (path.length() == plen || path.charAt(plen) == '/');
      }
  
      private static void handleFileMismatch(Path a, Path b) {
          throw new AssertionError("Files mismatch: " + a + " vs. " + b);
      }
< prev index next >