ADDITIONAL SYSTEM INFORMATION :
Tested on OpenJDK20 Windows and Linux, and OpenJDK14 - similar results for all
A DESCRIPTION OF THE PROBLEM :
When calling Files.createDirectories(path) for a relative path, the result returned is sometimes absolute version of the created path, but on other occasions the same original relative path is returned. Midway through Files.createDirectories(path) there is a line "dir = dir.toAbsolutePath()" but there is "return dir;" before and after that conversion - therefore giving inconsistent return value to caller. This inconsistent behaviour is undocumented. I would expect all calls to Files.createDirectories(path) to return the same value for all calls with same input path. Always toAbsolutePath, or always the original path, never a mix of the two outcomes.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See test case, this repeats the call to create a temporary directory with relative path Path.of(".temp/temp.abc/temp.def")
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
ACTUAL -
On the first call the path returned has been converted to absolute path, but in 2nd+ calls the path returned is relative path equal to the input path.
Windows:
Files.createDirectories(.temp\temp.abc\temp.def) => C:\Temp\.temp\temp.abc\temp.def
Files.createDirectories(.temp\temp.abc\temp.def) => .temp\temp.abc\temp.def
Files.createDirectories(.temp\temp.abc\temp.def) => .temp\temp.abc\temp.def
Linux:
Files.createDirectories(.temp/temp.abc/temp.def) => /tmp/.temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
---------- BEGIN SOURCE ----------
class FilesCreateDirectories {
public static void main(String ... args) throws IOException {
Path temp = Path.of(".temp/temp.abc/temp.def");
Files.deleteIfExists(temp);
Files.deleteIfExists(temp.getParent());
Path a = Files.createDirectories(temp);
Path b = Files.createDirectories(temp);
Path c = Files.createDirectories(temp);
System.out.format("Files.createDirectories(%s) => %s%n", temp, a);
System.out.format("Files.createDirectories(%s) => %s%n", temp, b);
System.out.format("Files.createDirectories(%s) => %s%n", temp, c);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Never assign the returned path from Files.createDirectories(temp) to another variable, and just use the parameter passed for subsequent calls.
FREQUENCY : always
Tested on OpenJDK20 Windows and Linux, and OpenJDK14 - similar results for all
A DESCRIPTION OF THE PROBLEM :
When calling Files.createDirectories(path) for a relative path, the result returned is sometimes absolute version of the created path, but on other occasions the same original relative path is returned. Midway through Files.createDirectories(path) there is a line "dir = dir.toAbsolutePath()" but there is "return dir;" before and after that conversion - therefore giving inconsistent return value to caller. This inconsistent behaviour is undocumented. I would expect all calls to Files.createDirectories(path) to return the same value for all calls with same input path. Always toAbsolutePath, or always the original path, never a mix of the two outcomes.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See test case, this repeats the call to create a temporary directory with relative path Path.of(".temp/temp.abc/temp.def")
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
ACTUAL -
On the first call the path returned has been converted to absolute path, but in 2nd+ calls the path returned is relative path equal to the input path.
Windows:
Files.createDirectories(.temp\temp.abc\temp.def) => C:\Temp\.temp\temp.abc\temp.def
Files.createDirectories(.temp\temp.abc\temp.def) => .temp\temp.abc\temp.def
Files.createDirectories(.temp\temp.abc\temp.def) => .temp\temp.abc\temp.def
Linux:
Files.createDirectories(.temp/temp.abc/temp.def) => /tmp/.temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
Files.createDirectories(.temp/temp.abc/temp.def) => .temp/temp.abc/temp.def
---------- BEGIN SOURCE ----------
class FilesCreateDirectories {
public static void main(String ... args) throws IOException {
Path temp = Path.of(".temp/temp.abc/temp.def");
Files.deleteIfExists(temp);
Files.deleteIfExists(temp.getParent());
Path a = Files.createDirectories(temp);
Path b = Files.createDirectories(temp);
Path c = Files.createDirectories(temp);
System.out.format("Files.createDirectories(%s) => %s%n", temp, a);
System.out.format("Files.createDirectories(%s) => %s%n", temp, b);
System.out.format("Files.createDirectories(%s) => %s%n", temp, c);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Never assign the returned path from Files.createDirectories(temp) to another variable, and just use the parameter passed for subsequent calls.
FREQUENCY : always