From 5b780501f2a1acabd1a840abf1c7f7f148efcf51 Mon Sep 17 00:00:00 2001 From: David Beaumont Date: Wed, 17 Dec 2025 10:10:48 +0100 Subject: [PATCH 1/4] Allow callers to decide if delgate file manager should be closed --- .../tools/ForwardingJavaFileManager.java | 27 +++++++++++++-- .../filer/TestOriginatingElements.java | 2 +- test/langtools/tools/lib/toolbox/ToolBox.java | 34 +++---------------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java index 1cff1c35770..545665c08ea 100644 --- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java @@ -52,11 +52,32 @@ public class ForwardingJavaFileManager implements Jav protected final M fileManager; /** - * Creates a new instance of {@code ForwardingJavaFileManager}. + * Whether the delegate is owned by this instance and should be closed when + * this instance is closed. + */ + private final boolean shouldClose; + + /** + * Creates a new instance of {@code ForwardingJavaFileManager} which takes + * ownership of the given delegate, and will close it when this instance is + * closed. + * * @param fileManager delegate to this file manager */ protected ForwardingJavaFileManager(M fileManager) { + this(fileManager, true); + } + + /** + * Creates a new instance of {@code ForwardingJavaFileManager}. + * + * @param fileManager delegate to this file manager + * @param shouldClose whether the delegate should be closed when this + * instance is closed. + */ + protected ForwardingJavaFileManager(M fileManager, boolean shouldClose) { this.fileManager = Objects.requireNonNull(fileManager); + this.shouldClose = shouldClose; } /** @@ -247,7 +268,9 @@ public void flush() throws IOException { @Override public void close() throws IOException { - fileManager.close(); + if (shouldClose) { + fileManager.close(); + } } /** diff --git a/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java b/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java index a936c0bb554..60ae4fdc4ab 100644 --- a/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java +++ b/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java @@ -174,7 +174,7 @@ private String getInfo(FileObject fo) { }; try { String generatedData; - try (MemoryFileManager mfm = new MemoryFileManager(sjfm)) { + try (MemoryFileManager mfm = new MemoryFileManager(sjfm, /* shouldClose */ false)) { compiler.getTask(null, mfm, null, null, null, List.of(new ToolBox.JavaSource("package test; public class Generated2 {}"))) .call(); diff --git a/test/langtools/tools/lib/toolbox/ToolBox.java b/test/langtools/tools/lib/toolbox/ToolBox.java index ee217ab2c0c..ae08cca7891 100644 --- a/test/langtools/tools/lib/toolbox/ToolBox.java +++ b/test/langtools/tools/lib/toolbox/ToolBox.java @@ -851,22 +851,16 @@ private interface Content { */ private final Map> files; - /** - * Constructs a memory file manager which stores output files in memory, - * and delegates to a default file manager for input files. - */ - public MemoryFileManager() { - this(ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)); - } - /** * Constructs a memory file manager which stores output files in memory, * and delegates to a specified file manager for input files. * * @param fileManager the file manager to be used for input files + * @param shouldClose whether the delegate file manager should be closed + * when this instance is closed */ - public MemoryFileManager(JavaFileManager fileManager) { - super(fileManager); + public MemoryFileManager(JavaFileManager fileManager, boolean shouldClose) { + super(fileManager, shouldClose); files = new HashMap<>(); } @@ -879,19 +873,6 @@ public JavaFileObject getJavaFileForOutput(Location location, return new MemoryFileObject(location, name, kind); } - /** - * Returns the set of names of files that have been written to a given - * location. - * - * @param location the location - * @return the set of file names - */ - public Set getFileNames(Location location) { - Map filesForLocation = files.get(location); - return (filesForLocation == null) - ? Collections.emptySet() : filesForLocation.keySet(); - } - /** * Returns the content written to a file in a given location, * or null if no such file has been written. @@ -911,13 +892,8 @@ public byte[] getFileBytes(Location location, String name) { * * @param location the location * @param name the name of the file - * @return the content as a string + * @return the content */ - public String getFileString(Location location, String name) { - Content content = getFile(location, name); - return (content == null) ? null : content.getString(); - } - private Content getFile(Location location, String name) { Map filesForLocation = files.get(location); return (filesForLocation == null) ? null : filesForLocation.get(name); From d49af5d7047fcfcf15180fb15698d8bd0e2c601b Mon Sep 17 00:00:00 2001 From: David Beaumont Date: Wed, 17 Dec 2025 10:46:10 +0100 Subject: [PATCH 2/4] tidy and restore eagerly removed not-actually-dead code --- .../classfiles/InnerClasses/T8068517.java | 21 +++++++------- .../filer/TestOriginatingElements.java | 1 - test/langtools/tools/lib/toolbox/ToolBox.java | 28 ++++++++++++++++++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/test/langtools/tools/javac/classfiles/InnerClasses/T8068517.java b/test/langtools/tools/javac/classfiles/InnerClasses/T8068517.java index edb760757f6..52f43856220 100644 --- a/test/langtools/tools/javac/classfiles/InnerClasses/T8068517.java +++ b/test/langtools/tools/javac/classfiles/InnerClasses/T8068517.java @@ -107,17 +107,18 @@ void run() throws Exception { void runTest(String aJava, String bJava) throws Exception { try (JavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { ToolBox tb = new ToolBox(); - ToolBox.MemoryFileManager memoryFM1 = new ToolBox.MemoryFileManager(fm); - new JavacTask(tb).fileManager(memoryFM1) - .sources(aJava, bJava) - .run(); - ToolBox.MemoryFileManager memoryFM2 = new ToolBox.MemoryFileManager(fm); - new JavacTask(tb).fileManager(memoryFM2) - .sources(bJava, aJava) - .run(); + try (var memoryFM1 = new ToolBox.MemoryFileManager(fm, false); + var memoryFM2 = new ToolBox.MemoryFileManager(fm, false)) { + new JavacTask(tb).fileManager(memoryFM1) + .sources(aJava, bJava) + .run(); + new JavacTask(tb).fileManager(memoryFM2) + .sources(bJava, aJava) + .run(); - Assert.check(Arrays.equals(memoryFM1.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"), - memoryFM2.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"))); + Assert.check(Arrays.equals(memoryFM1.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"), + memoryFM2.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"))); + } } } } diff --git a/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java b/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java index 60ae4fdc4ab..82602bd464f 100644 --- a/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java +++ b/test/langtools/tools/javac/processing/filer/TestOriginatingElements.java @@ -67,7 +67,6 @@ import javax.tools.StandardLocation; import toolbox.JavacTask; import toolbox.TestRunner; -import toolbox.TestRunner.Test; import toolbox.ToolBox; import toolbox.ToolBox.MemoryFileManager; diff --git a/test/langtools/tools/lib/toolbox/ToolBox.java b/test/langtools/tools/lib/toolbox/ToolBox.java index ae08cca7891..473f10bb10e 100644 --- a/test/langtools/tools/lib/toolbox/ToolBox.java +++ b/test/langtools/tools/lib/toolbox/ToolBox.java @@ -851,6 +851,14 @@ private interface Content { */ private final Map> files; + /** + * Constructs a memory file manager which stores output files in memory, + * and delegates to a default file manager for input files. + */ + public MemoryFileManager() { + this(ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null), true); + } + /** * Constructs a memory file manager which stores output files in memory, * and delegates to a specified file manager for input files. @@ -873,6 +881,19 @@ public JavaFileObject getJavaFileForOutput(Location location, return new MemoryFileObject(location, name, kind); } + /** + * Returns the set of names of files that have been written to a given + * location. + * + * @param location the location + * @return the set of file names + */ + public Set getFileNames(Location location) { + Map filesForLocation = files.get(location); + return (filesForLocation == null) + ? Collections.emptySet() : filesForLocation.keySet(); + } + /** * Returns the content written to a file in a given location, * or null if no such file has been written. @@ -892,8 +913,13 @@ public byte[] getFileBytes(Location location, String name) { * * @param location the location * @param name the name of the file - * @return the content + * @return the content as a string */ + public String getFileString(Location location, String name) { + Content content = getFile(location, name); + return (content == null) ? null : content.getString(); + } + private Content getFile(Location location, String name) { Map filesForLocation = files.get(location); return (filesForLocation == null) ? null : filesForLocation.get(name); From d41fac6bcc1a439cd22f343b50a19cc97b2ef15b Mon Sep 17 00:00:00 2001 From: David Beaumont Date: Wed, 17 Dec 2025 10:49:20 +0100 Subject: [PATCH 3/4] undo reformatting --- test/langtools/tools/lib/toolbox/ToolBox.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/langtools/tools/lib/toolbox/ToolBox.java b/test/langtools/tools/lib/toolbox/ToolBox.java index 473f10bb10e..c30dac5d2c5 100644 --- a/test/langtools/tools/lib/toolbox/ToolBox.java +++ b/test/langtools/tools/lib/toolbox/ToolBox.java @@ -891,7 +891,7 @@ public JavaFileObject getJavaFileForOutput(Location location, public Set getFileNames(Location location) { Map filesForLocation = files.get(location); return (filesForLocation == null) - ? Collections.emptySet() : filesForLocation.keySet(); + ? Collections.emptySet() : filesForLocation.keySet(); } /** From 1b29ac47a23bf11d9a1d6b334dd6e3841f7d5e4a Mon Sep 17 00:00:00 2001 From: David Beaumont Date: Wed, 17 Dec 2025 12:02:18 +0100 Subject: [PATCH 4/4] add @since for new method --- .../share/classes/javax/tools/ForwardingJavaFileManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java index 545665c08ea..a323025ab58 100644 --- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java @@ -74,6 +74,8 @@ protected ForwardingJavaFileManager(M fileManager) { * @param fileManager delegate to this file manager * @param shouldClose whether the delegate should be closed when this * instance is closed. + * + * @since 26 */ protected ForwardingJavaFileManager(M fileManager, boolean shouldClose) { this.fileManager = Objects.requireNonNull(fileManager);