8375623: Excessive disk space usage of jpackage and jlink tests in debug builds after JDK-8373246

Reviewed-by: clanger
This commit is contained in:
Arno Zeller 2026-07-30 07:19:19 +00:00
parent e04f4dd46f
commit a3dff658bb
9 changed files with 174 additions and 97 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2026, 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
@ -26,6 +26,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.spi.ToolProvider;
import jdk.test.lib.util.FileUtils;
/*
* @test
* @summary Make sure that jimages are consistent when created by jlink.
@ -35,6 +37,8 @@ import java.util.spi.ToolProvider;
* jdk.management
* jdk.unsupported
* jdk.charsets
* @library /test/lib
* @build jdk.test.lib.util.FileUtils
* @run main JLinkReproducible2Test
*/
public class JLinkReproducible2Test {
@ -54,6 +58,10 @@ public class JLinkReproducible2Test {
throw new RuntimeException("jlink producing inconsistent result");
}
// Free disk space before creating the next pair of images.
FileUtils.deleteFileTreeWithRetry(image1);
FileUtils.deleteFileTreeWithRetry(image2);
Path image3 = Paths.get("./image3");
Path image4 = Paths.get("./image4");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2026, 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
@ -22,6 +22,7 @@
*/
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.util.FileUtils;
import java.io.File;
import java.io.IOException;
@ -40,6 +41,7 @@ import java.util.Optional;
* jdk.unsupported
* jdk.charsets
* @library /test/lib
* @build jdk.test.lib.util.FileUtils
* @run main JLinkReproducible3Test
*/
public class JLinkReproducible3Test {
@ -48,33 +50,17 @@ public class JLinkReproducible3Test {
Path image1 = Paths.get("./image1");
Path image2 = Paths.get("./image2");
Path copyJdk1Dir = Path.of("./copy-jdk1-tmpdir");
Files.createDirectory(copyJdk1Dir);
Path copyJdk2Dir = Path.of("./copy-jdk2-tmpdir");
Files.createDirectory(copyJdk2Dir);
Path jdkTestDir = Path.of(
Optional.of(
System.getProperty("test.jdk"))
.orElseThrow(() -> new RuntimeException("Couldn't load JDK Test Dir"))
);
copyJDK(jdkTestDir, copyJdk1Dir);
copyJDK(jdkTestDir, copyJdk2Dir);
Path copiedJlink1 = Optional.of(
Paths.get(copyJdk1Dir.toString(), "bin", "jlink"))
.orElseThrow(() -> new RuntimeException("Unable to load copied jlink")
);
Path copiedJlink2 = Optional.of(
Paths.get(copyJdk2Dir.toString(), "bin", "jlink"))
.orElseThrow(() -> new RuntimeException("Unable to load copied jlink")
);
runCopiedJlink(copiedJlink1.toString(), "--add-modules", "java.base,jdk.management,jdk.unsupported,jdk.charsets", "--output", image1.toString());
runCopiedJlink(copiedJlink2.toString(), "--add-modules", "java.base,jdk.management,jdk.unsupported,jdk.charsets", "--output", image2.toString());
// Link each image from its own copy of the JDK placed at a distinct
// location. Copy, link, then delete the copy before creating the next
// one so that at most one JDK copy exists on disk at a time.
linkFromCopy(jdkTestDir, Path.of("./copy-jdk1-tmpdir"), image1);
linkFromCopy(jdkTestDir, Path.of("./copy-jdk2-tmpdir"), image2);
long mismatch = Files.mismatch(image1.resolve("lib").resolve("modules"), image2.resolve("lib").resolve("modules"));
if (mismatch != -1L) {
@ -82,6 +68,20 @@ public class JLinkReproducible3Test {
}
}
private static void linkFromCopy(Path jdkTestDir, Path copyJdkDir, Path image) throws Exception {
Files.createDirectory(copyJdkDir);
copyJDK(jdkTestDir, copyJdkDir);
Path copiedJlink = Paths.get(copyJdkDir.toString(), "bin", "jlink");
runCopiedJlink(copiedJlink.toString(), "--add-modules",
"java.base,jdk.management,jdk.unsupported,jdk.charsets",
"--output", image.toString());
// The copied JDK was only needed to run jlink; free the disk space
// before creating the next copy.
FileUtils.deleteFileTreeWithRetry(copyJdkDir);
}
private static void runCopiedJlink(String... args) throws Exception {
var process = new ProcessBuilder(args);
var res = ProcessTools.executeProcess(process);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2026, 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
@ -36,6 +36,7 @@ import java.util.stream.Stream;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.plugin.Plugin;
import jdk.test.lib.util.FileUtils;
import tests.Helper;
import tests.JImageGenerator;
@ -45,13 +46,14 @@ import tests.JImageGenerator;
* @bug 8189777 8194922 8206962 8240349 8163382 8165735 8166810 8173717 8321139
* @author Jean-Francois Denise
* @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g)
* @library ../lib
* @library ../lib /test/lib
* @modules java.base/jdk.internal.jimage
* jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink.plugin
* jdk.jlink/jdk.tools.jimage
* jdk.compiler
* @build tests.*
* @build jdk.test.lib.util.FileUtils
* @run main/othervm/timeout=480 -Xmx1g JLinkTest
*/
public class JLinkTest {
@ -110,10 +112,12 @@ public class JLinkTest {
// No --module-path specified. $JAVA_HOME/jmods should be assumed.
// The following should succeed as it uses only system modules.
String imageDir = "bug818977-no-modulepath";
Path image = helper.createNewImageDir(imageDir);
JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir(imageDir))
.output(image)
.addMods("jdk.jshell")
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(image);
}
{
@ -121,11 +125,13 @@ public class JLinkTest {
// $JAVA_HOME/jmods should be added automatically.
// The following should succeed as it uses only system modules.
String imageDir = "bug8189777-invalid-modulepath";
Path image = helper.createNewImageDir(imageDir);
JImageGenerator.getJLinkTask()
.modulePath("does_not_exist_path")
.output(helper.createNewImageDir(imageDir))
.output(image)
.addMods("jdk.jshell")
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(image);
}
{
@ -139,11 +145,13 @@ public class JLinkTest {
{
String moduleName = "bug8134651";
Path image1 = helper.createNewImageDir(moduleName);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
.output(helper.createNewImageDir(moduleName))
.output(image1)
.addMods("leaf1")
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(image1);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
.addMods("leaf1")
@ -155,11 +163,13 @@ public class JLinkTest {
.addMods("leaf1")
.call().assertFailure("Error: no value given for --module-path");
// do not include standard module path - should be added automatically
Path image2 = helper.createNewImageDir(moduleName);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath(false))
.output(helper.createNewImageDir(moduleName))
.output(image2)
.addMods("leaf1")
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(image2);
// no --module-path. default sys mod path is assumed - but that won't contain 'leaf1' module
JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir(moduleName))
@ -170,18 +180,22 @@ public class JLinkTest {
{
String moduleName = "m"; // 8163382
Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
Path imageM = helper.createNewImageDir(moduleName);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
.output(helper.createNewImageDir(moduleName))
.output(imageM)
.addMods("m")
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(imageM);
moduleName = "mod";
jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
Path imageMod = helper.createNewImageDir(moduleName);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
.output(helper.createNewImageDir(moduleName))
.output(imageMod)
.addMods("m")
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(imageMod);
}
{
@ -196,13 +210,15 @@ public class JLinkTest {
// second --module-path does not have that module
.call().assertFailure("Error: Module m_8165735 not found");
Path imageRepeatedPath = helper.createNewImageDir(moduleName);
JImageGenerator.getJLinkTask()
.modulePath(".") // first --module-path overridden later
.repeatedModulePath(helper.defaultModulePath())
.output(helper.createNewImageDir(moduleName))
.output(imageRepeatedPath)
.addMods(moduleName)
// second --module-path has that module
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(imageRepeatedPath);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
@ -212,13 +228,15 @@ public class JLinkTest {
.addMods(moduleName)
.call().assertFailure("Error: Module m_8165735dependency not found, required by m_8165735");
Path imageRepeatedLimit = helper.createNewImageDir(moduleName);
JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
.output(helper.createNewImageDir(moduleName))
.output(imageRepeatedLimit)
.limitMods("java.base")
.repeatedLimitMods(moduleName) // second --limit-modules overrides first
.addMods(moduleName)
.call().assertSuccess();
FileUtils.deleteFileTreeWithRetry(imageRepeatedLimit);
}
{
@ -269,6 +287,7 @@ public class JLinkTest {
String[] files = {Helper.getDebugSymbolsExtension()};
Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess();
helper.checkImage(imageDir, moduleName, res, files);
FileUtils.deleteFileTreeWithRetry(imageDir);
}
// filter out + Skip debug + compress with filter + sort resources
@ -282,6 +301,7 @@ public class JLinkTest {
String[] res = {".jcov", "/META-INF/"};
Path imageDir = helper.generateDefaultImage(userOptions2, moduleName).assertSuccess();
helper.checkImage(imageDir, moduleName, res, null);
FileUtils.deleteFileTreeWithRetry(imageDir);
}
// module-info.class should not be excluded
@ -439,5 +459,6 @@ public class JLinkTest {
helper.generateDefaultJModule(moduleName, "composite2");
Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess();
helper.checkImage(imageDir, moduleName, null, null);
FileUtils.deleteFileTreeWithRetry(imageDir);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -28,6 +28,7 @@
* @modules jdk.compiler
* jdk.jlink
* @build jdk.test.lib.compiler.CompilerUtils
* @build jdk.test.lib.util.FileUtils
* @run testng ExcludeJmodSectionPluginTest
*/
@ -35,12 +36,9 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -49,7 +47,10 @@ import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.test.lib.compiler.CompilerUtils;
import jdk.test.lib.util.FileUtils;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -75,6 +76,8 @@ public class ExcludeJmodSectionPluginTest {
static final Path INCLUDE_DIR = Paths.get("include");
static final Path IMAGES_DIR = Paths.get("images");
private Path lastImageDir;
@BeforeTest
private void setup() throws Exception {
// build jmod files
@ -209,12 +212,13 @@ public class ExcludeJmodSectionPluginTest {
private Path createImage(String outputDir, List<String> options,
List<String> expectedFiles) {
lastImageDir = IMAGES_DIR.resolve(outputDir);
System.out.println("jlink " + options.toString());
int rc = JLINK_TOOL.run(System.out, System.out,
options.toArray(new String[0]));
assertTrue(rc == 0);
Path d = IMAGES_DIR.resolve(outputDir);
Path d = lastImageDir;
for (String fn : expectedFiles) {
Path path = d.resolve(fn);
if (Files.notExists(path)) {
@ -224,24 +228,12 @@ public class ExcludeJmodSectionPluginTest {
return d;
}
private void deleteDirectory(Path dir) throws IOException {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException
{
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException
{
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
@AfterMethod
public void cleanup(ITestResult result) throws IOException {
if (result.isSuccess() && lastImageDir != null && Files.exists(lastImageDir)) {
FileUtils.deleteFileTreeWithRetry(lastImageDir);
}
lastImageDir = null;
}
/**
@ -258,7 +250,7 @@ public class ExcludeJmodSectionPluginTest {
Path msrc = SRC_DIR.resolve(name);
if (Files.exists(msrc)) {
deleteDirectory(msrc);
FileUtils.deleteFileTreeWithRetry(msrc);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -34,10 +34,13 @@ import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.testng.ITestResult;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import jdk.test.lib.util.FileUtils;
import jdk.tools.jlink.internal.LinkableRuntimeImage;
import tests.Helper;
import tests.JImageGenerator;
@ -48,7 +51,7 @@ import tests.Result;
/*
* @test
* @bug 8252919 8327499
* @library ../../lib
* @library ../../lib /test/lib
* @summary Test --generate-jli-classes plugin
* @modules java.base/jdk.internal.jimage
* jdk.jlink/jdk.tools.jlink.internal
@ -56,11 +59,13 @@ import tests.Result;
* jdk.jlink/jdk.tools.jmod
* jdk.jlink/jdk.tools.jimage
* @build tests.*
* @build jdk.test.lib.util.FileUtils
* @run testng/othervm GenerateJLIClassesPluginTest
*/
public class GenerateJLIClassesPluginTest {
private static Helper helper;
private static Path lastImageDir;
@BeforeTest
public static void setup() throws Exception {
@ -80,6 +85,14 @@ public class GenerateJLIClassesPluginTest {
}
}
@AfterMethod
public static void cleanup(ITestResult result) throws IOException {
if (result.isSuccess() && lastImageDir != null && Files.exists(lastImageDir)) {
FileUtils.deleteFileTreeWithRetry(lastImageDir);
}
lastImageDir = null;
}
@Test
public static void testSpecies() throws IOException {
// Check that --generate-jli-classes=@file works as intended
@ -88,7 +101,7 @@ public class GenerateJLIClassesPluginTest {
String fileString = "[SPECIES_RESOLVE] java.lang.invoke.BoundMethodHandle$Species_" + species + " (salvaged)\n";
Files.write(baseFile, fileString.getBytes(Charset.defaultCharset()));
Result result = JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir("generate-jli-file"))
.output(lastImageDir = helper.createNewImageDir("generate-jli-file"))
.option("--generate-jli-classes=@" + baseFile.toString())
.addMods("java.base")
.call();
@ -113,7 +126,7 @@ public class GenerateJLIClassesPluginTest {
fileString = "[LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeVirtual L_L (success)\n";
Files.write(failFile, fileString.getBytes(Charset.defaultCharset()));
Result result = JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir("invalid-signature"))
.output(lastImageDir = helper.createNewImageDir("invalid-signature"))
.option("--generate-jli-classes=@" + failFile.toString())
.addMods("java.base")
.call();
@ -125,7 +138,7 @@ public class GenerateJLIClassesPluginTest {
@Test
public static void nonExistentTraceFile() throws IOException {
Result result = JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir("non-existent-tracefile"))
.output(lastImageDir = helper.createNewImageDir("non-existent-tracefile"))
.option("--generate-jli-classes=@NON_EXISTENT_FILE")
.addMods("java.base")
.call();
@ -140,7 +153,7 @@ public class GenerateJLIClassesPluginTest {
Path invokersTrace = Files.createTempFile("invokers", "trace");
Files.writeString(invokersTrace, fileString, Charset.defaultCharset());
Result result = JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir("jli-invokers"))
.output(lastImageDir = helper.createNewImageDir("jli-invokers"))
.option("--generate-jli-classes=@" + invokersTrace.toString())
.addMods("java.base")
.call();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -22,6 +22,7 @@
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
@ -35,11 +36,13 @@ import jdk.tools.jlink.internal.TaskHelper;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
import jdk.tools.jlink.plugin.PluginException;
import jdk.test.lib.Platform;
import jdk.test.lib.util.FileUtils;
import tests.Helper;
import tests.JImageGenerator;
import tests.JImageValidator;
import tests.Result;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@ -67,6 +70,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* jdk.compiler
* @build tests.*
* @build jdk.test.lib.Platform
* @build jdk.test.lib.util.FileUtils
* @build tools.jlink.plugins.GetAvailableLocales
* @run junit/othervm/timeout=720 -Xmx1g IncludeLocalesPluginTest
*/
@ -75,6 +79,8 @@ public class IncludeLocalesPluginTest {
private static final String MODULE_NAME = "IncludeLocalesTest";
private static Helper helper;
private Path lastImageDir;
private boolean testPassed;
// Test data should include:
// - --include-locales command line option
@ -422,18 +428,22 @@ public class IncludeLocalesPluginTest {
@MethodSource("testData")
public void launch(String optIncludeLocales, String optAddModules, List<String> requiredRes,
List<String> shouldNotExistRes, List<String> availableLocs, String errorMsg) throws Exception {
testPassed = false;
// create image for each test data
Result result;
lastImageDir = helper.createNewImageDir(MODULE_NAME);
if (optIncludeLocales.isEmpty()) {
System.out.println("Invoking jlink with no --include-locales option");
result = JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir(MODULE_NAME))
.output(lastImageDir)
.option("--strip-debug")
.addMods(optAddModules)
.call();
} else {
System.out.println("Invoking jlink with \"" + optIncludeLocales + "\"");
result = JImageGenerator.getJLinkTask()
.output(helper.createNewImageDir(MODULE_NAME))
.output(lastImageDir)
.option("--strip-debug")
.addMods(optAddModules)
.option(optIncludeLocales)
.call();
@ -452,6 +462,14 @@ public class IncludeLocalesPluginTest {
.getMessage("error.prefix") + " " +errorMsg);
System.out.println("\tExpected failure: " + result.getMessage());
}
testPassed = true;
}
@AfterEach
public void cleanup() throws IOException {
if (testPassed && lastImageDir != null && Files.exists(lastImageDir)) {
FileUtils.deleteFileTreeWithRetry(lastImageDir);
}
}
private static void testLocaleDataEntries(Path image, List<String> expectedLocations,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -29,6 +29,7 @@
* @modules jdk.compiler
* jdk.jlink
* @build jdk.test.lib.compiler.CompilerUtils
* @build jdk.test.lib.util.FileUtils
* @run testng LegalFilePluginTest
*/
@ -38,12 +39,9 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -54,7 +52,10 @@ import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.test.lib.compiler.CompilerUtils;
import jdk.test.lib.util.FileUtils;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -79,6 +80,8 @@ public class LegalFilePluginTest {
static final Path LEGAL_DIR = Paths.get("legal");
static final Path IMAGES_DIR = Paths.get("images");
private Path lastImageDir;
static final Map<List<String>, Map<String,String>> LICENSES = Map.of(
// Key is module name and requires
// Value is a map of filename to the file content
@ -259,32 +262,21 @@ public class LegalFilePluginTest {
}
private Path createImage(String outputDir, List<String> options) {
lastImageDir = IMAGES_DIR.resolve(outputDir);
System.out.println("jlink " + options.stream().collect(Collectors.joining(" ")));
int rc = JLINK_TOOL.run(System.out, System.out,
options.toArray(new String[0]));
assertTrue(rc == 0);
return IMAGES_DIR.resolve(outputDir);
return lastImageDir;
}
private void deleteDirectory(Path dir) throws IOException {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException
{
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException
{
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
@AfterMethod
public void cleanup(ITestResult result) throws IOException {
if (result.isSuccess() && lastImageDir != null && Files.exists(lastImageDir)) {
FileUtils.deleteFileTreeWithRetry(lastImageDir);
}
lastImageDir = null;
}
/**
@ -301,7 +293,7 @@ public class LegalFilePluginTest {
Path msrc = SRC_DIR.resolve(name);
if (Files.exists(msrc)) {
deleteDirectory(msrc);
FileUtils.deleteFileTreeWithRetry(msrc);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -37,6 +37,9 @@ import jdk.test.lib.util.FileUtils;
import static jdk.test.lib.process.ProcessTools.*;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@ -68,6 +71,8 @@ public class UserModuleTest {
// the names of the modules in this test
private static String[] modules = new String[] {"m1", "m2", "m3", "m4", "m5"};
private Path lastPerTestImageDir;
private static boolean hasJmods() {
if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) {
@ -100,6 +105,22 @@ public class UserModuleTest {
createJmods("m1", "m4");
}
@AfterMethod
public void cleanupPerTestImage(ITestResult result) throws IOException {
if (result.isSuccess() && lastPerTestImageDir != null
&& Files.exists(lastPerTestImageDir)) {
FileUtils.deleteFileTreeWithRetry(lastPerTestImageDir);
}
lastPerTestImageDir = null;
}
@AfterTest(alwaysRun = true)
public void cleanupSharedImage() throws IOException {
if (Files.exists(IMAGE)) {
FileUtils.deleteFileTreeWithRetry(IMAGE);
}
}
/*
* Test the image created when linking with a module with
* no Packages attribute
@ -157,7 +178,7 @@ public class UserModuleTest {
public void testDedupSet() throws Throwable {
if (!hasJmods()) return;
Path dir = Paths.get("dedupSetTest");
Path dir = lastPerTestImageDir = Paths.get("dedupSetTest");
createImage(dir, "m1", "m2", "m3", "m4");
Path java = dir.resolve("bin").resolve("java");
assertTrue(executeProcess(java.toString(),
@ -172,7 +193,7 @@ public class UserModuleTest {
public void testRequiresStatic() throws Throwable {
if (!hasJmods()) return;
Path dir = Paths.get("requiresStatic");
Path dir = lastPerTestImageDir = Paths.get("requiresStatic");
createImage(dir, "m5");
Path java = dir.resolve("bin").resolve("java");
assertTrue(executeProcess(java.toString(), "-m", "m5/p5.Main")
@ -194,7 +215,7 @@ public class UserModuleTest {
public void testRequiresStatic2() throws Throwable {
if (!hasJmods()) return;
Path dir = Paths.get("requiresStatic2");
Path dir = lastPerTestImageDir = Paths.get("requiresStatic2");
createImage(dir, "m3", "m5");
Path java = dir.resolve("bin").resolve("java");
@ -242,7 +263,7 @@ public class UserModuleTest {
if (!hasJmods()) return;
// create an image using JMOD files
Path dir = Paths.get("packagesTest");
Path dir = lastPerTestImageDir = Paths.get("packagesTest");
String mp = Paths.get(JAVA_HOME, "jmods").toString() +
File.pathSeparator + JMODS_DIR.toString();
@ -271,7 +292,7 @@ public class UserModuleTest {
if (!hasJmods()) return;
// create an image using JMOD files
Path dir = Paths.get("retainModuleTargetTest");
Path dir = lastPerTestImageDir = Paths.get("retainModuleTargetTest");
String mp = Paths.get(JAVA_HOME, "jmods").toString() +
File.pathSeparator + JMODS_DIR.toString();

View File

@ -1,4 +1,5 @@
/*
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -41,6 +42,7 @@ import java.util.stream.Collectors;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.util.FileUtils;
import jdk.tools.jlink.internal.LinkableRuntimeImage;
import tests.Helper;
import tests.JImageGenerator;
@ -141,7 +143,11 @@ public abstract class AbstractLinkableRuntimeTest {
for (String extra: baseSpec.getExtraOptions()) {
builder.extraJlinkOpt(extra);
}
return jlinkUsingImage(builder.build());
Path finalImage = jlinkUsingImage(builder.build());
// The intermediate run-time link image was only needed as the jlink
// source for producing the final image; free the disk space now.
FileUtils.deleteFileTreeWithRetry(runtimeJlinkImage);
return finalImage;
}
protected Path jlinkUsingImage(JlinkSpec spec) throws Exception {
@ -280,6 +286,12 @@ public abstract class AbstractLinkableRuntimeTest {
// Remove JMODs as needed for the test
copyJDKTreeWithoutSpecificJmods(from, runtimeJlinkImage, excludedJmodFiles);
// In the non-linkable-runtime case 'from' is a temporary
// --generate-linkable-runtime image that has now been copied into
// 'runtimeJlinkImage'; delete it to free the disk space.
if (!baseSpec.isLinkableRuntime()) {
FileUtils.deleteFileTreeWithRetry(from);
}
// Verify the base image is actually without desired packaged modules
if (excludedJmodFiles.isEmpty()) {
if (Files.exists(runtimeJlinkImage.resolve("jmods"))) {