diff --git a/test/jdk/tools/jlink/JLinkReproducible2Test.java b/test/jdk/tools/jlink/JLinkReproducible2Test.java index 4723bd0eb8f..56593147bfc 100644 --- a/test/jdk/tools/jlink/JLinkReproducible2Test.java +++ b/test/jdk/tools/jlink/JLinkReproducible2Test.java @@ -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"); diff --git a/test/jdk/tools/jlink/JLinkReproducible3Test.java b/test/jdk/tools/jlink/JLinkReproducible3Test.java index 6d37cff4ee4..841fe1fcbb4 100644 --- a/test/jdk/tools/jlink/JLinkReproducible3Test.java +++ b/test/jdk/tools/jlink/JLinkReproducible3Test.java @@ -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); diff --git a/test/jdk/tools/jlink/JLinkTest.java b/test/jdk/tools/jlink/JLinkTest.java index 1d84caaa147..721870b3b9b 100644 --- a/test/jdk/tools/jlink/JLinkTest.java +++ b/test/jdk/tools/jlink/JLinkTest.java @@ -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); } } diff --git a/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java b/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java index ac40cda036c..1ee00d12218 100644 --- a/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java +++ b/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java @@ -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 options, List 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() { - @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); } } diff --git a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java index 998444b9a77..06e2c7b52f0 100644 --- a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java @@ -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(); diff --git a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java index 5551d54a1ea..da0df46e73b 100644 --- a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java @@ -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 requiredRes, List shouldNotExistRes, List 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 expectedLocations, diff --git a/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java b/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java index 3647e0fb27b..07dd1d514be 100644 --- a/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java +++ b/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java @@ -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, Map> 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 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() { - @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); } } diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java index b7c9a59bd65..6d7e4df7fab 100644 --- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java +++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java @@ -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(); diff --git a/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java b/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java index 1df4455bc7d..9414508769b 100644 --- a/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java +++ b/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java @@ -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"))) {