In Java 9, the WinNTFileSystem
class (FileSystem implementation for windows) changed.
It probably solves a issue which the way the class considers what a absolute path is. I didn't find a bug that exactly specifies this one but some are close to.
File.isAbsolute()
states :
On Microsoft Windows systems, a pathname is absolute if its prefix is
a drive specifier followed by "\", or if its prefix is "\\".
So according to the specification, for the following:
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // not absolute according to the spec
File xx = new File("C:\\", "Workspace");
System.out.println(xx.isAbsolute());
File xxx = new File("\\\\Workspace");
System.out.println(xxx.isAbsolute());
we expect :
false
true
true
But we get :
true
true
true
From Java 9 it produces the expected result.
The problem is that before Java 9 a path without \
is all the same considered as an absolute path :
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // true
While that this should not be the case.
Concretely, the main changes concern the resolve(String parent, String child)
method of the WinNTFileSystem
class.
Before, resolve()
resolved the abstract path by adding a slash between the parent and the child for any child path that doesn't start with a slash.
From Java 9, resolve()
doesn't add a slash any longer between the parent and the child if the parent is a drive.
Here is the change :
boolean isDirectoryRelative =
pn == 2 && isLetter(parent.charAt(0)) && parent.charAt(1) == ':';
if (child.charAt(childStart) == slash || isDirectoryRelative) {
theChars = new char[strlen]; ^-------- this one was added from Java 9
parent.getChars(0, parentEnd, theChars, 0);
child.getChars(childStart, cn, theChars, parentEnd);
} else {
theChars = new char[strlen + 1];
parent.getChars(0, parentEnd, theChars, 0);
theChars[parentEnd] = slash;
child.getChars(childStart, cn, theChars, parentEnd + 1);
}
Consequences
About your question :
Could you please address is there any known issue or solution for the
case
The difference between the two JDK versions matters.
It concerns both the value of the abstract pathname's normalized pathname (File.getPath()
) and the value of the absolute path File.getAbsolutePath()
as now new File("C:", "Workspace")
produces a relative path.
If your application relies on File.getPath()
to do some parsing on that, it could have a distinct behavior and create some issues.
To have a portable code between the JDK versions, any parsing on the resolved path should consider as optional the \
just after the Windows drive.
In this way C:\
and C:
would be handled in the same way.
If your application relies on File.getAbsolutePath()
, it could also have some surprises from Java 9 as now the path that is relative will be resolved against the filesystem (before as an absolute path this just returned itself).
So instead, you should so probably use File.getPath()
to not resolve the path against the file system.
C:
means the current directory on drive C and when you appendWorkspace
it should become the relativeC:Workspace
. If you start with `C:\` then you should get the other result. – Solander