From 12da6a53b0285338eb90777f34e429d2e536d3cf Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Thu, 4 Dec 2025 19:08:17 +0100 Subject: [PATCH 1/3] 8373097: Save command should create missing parent directories --- .../jdk/internal/jshell/tool/JShellTool.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index 795321253fdf0..0781ea0fb632c 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -3362,7 +3362,19 @@ private boolean cmdSave(String rawargs) { // error occurred, already reported return false; } - try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename), + // Create missing parent directories before writing to target file + Path target; + try { + target = toPathResolvingUserHome(filename).normalize(); + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); // calls Path::toAbsolutePath + } + } catch (Exception e) { + errormsg("jshell.err.file.exception", "/save", filename, e); + return false; + } + try (BufferedWriter writer = Files.newBufferedWriter(target, Charset.defaultCharset(), CREATE, TRUNCATE_EXISTING, WRITE)) { if (at.hasOption("-history")) { From 55b2eedc136a8b24d09f4f1659ed43be56a109c7 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Thu, 4 Dec 2025 20:38:09 +0100 Subject: [PATCH 2/3] Add file with parent directories to `/save` test --- test/langtools/jdk/jshell/ToolBasicTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/langtools/jdk/jshell/ToolBasicTest.java b/test/langtools/jdk/jshell/ToolBasicTest.java index 5015d1f64b12a..7fba0a9cd4452 100644 --- a/test/langtools/jdk/jshell/ToolBasicTest.java +++ b/test/langtools/jdk/jshell/ToolBasicTest.java @@ -585,6 +585,7 @@ public void testSave() throws IOException { Compiler compiler = new Compiler(); Path path = compiler.getPath("testSave.repl"); { + Path pathWithDirectories = compiler.getPath("what/ever/testSave.repl"); List list = Arrays.asList( "int a;", "class A { public String toString() { return \"A\"; } }" @@ -593,9 +594,11 @@ public void testSave() throws IOException { (a) -> assertVariable(a, "int", "a"), (a) -> assertCommand(a, "()", null, null, null, "", ""), (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"), - (a) -> assertCommand(a, "/save " + path.toString(), "") + (a) -> assertCommand(a, "/save " + path.toString(), ""), + (a) -> assertCommand(a, "/save " + pathWithDirectories.toString(), "") ); assertEquals(list, Files.readAllLines(path)); + assertEquals(list, Files.readAllLines(pathWithDirectories)); } { List output = new ArrayList<>(); From 668701df16a651c77d2789d3ed2841a136337235 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Mon, 8 Dec 2025 08:02:04 +0100 Subject: [PATCH 3/3] Clean up [skip-ci] --- .../share/classes/jdk/internal/jshell/tool/JShellTool.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index 0781ea0fb632c..9a030f7e46b98 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -3365,10 +3365,10 @@ private boolean cmdSave(String rawargs) { // Create missing parent directories before writing to target file Path target; try { - target = toPathResolvingUserHome(filename).normalize(); + target = toPathResolvingUserHome(filename); Path parent = target.getParent(); if (parent != null) { - Files.createDirectories(parent); // calls Path::toAbsolutePath + Files.createDirectories(parent); } } catch (Exception e) { errormsg("jshell.err.file.exception", "/save", filename, e);