< prev index next > test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java
Print this page
/*
* 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.
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;
* @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();
* @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();
.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();
// 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),
// 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),
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);
}
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 >