Why does the method relativize behave differently on java-8 and java-11?
Path path1 = Paths.get("/a/./b/../image.png");
Path path2 = Paths.get("/a/file.txt");
Path path = path1.relativize(path2);
System.out.println(path);
- java-8 (1.8.0_66 to be exact) prints
../../../../file.txt. JavaDoc. - java-11 (11.0.4 to be exact) prints
../file.txt. JavaDoc.
The JavaDoc description of both versions is equal. I feel the java-11 way looks like a correct behavior to me:
path1:/a/./b/../image.pngnormalizes to/a/b/../image.pngwhich normalizes to/a/image.pngpath2:/a/file.txt- the way to navigate from
/a/image.pngand/a/file.txtis../file.txt
Questions
How is the java-8 way supposed to be calculated? Doesn't it normalize the path? I don't understand how to get the result from head.
Why is there a difference between these two versions that is not documented at all?
Windows based source-code answer here.
From the observation of the source codes (let's take a look at
sun.nio.fs.WindowsPath, one of the implementations ofPath) in java-11 is has additional code including normalization compared to java-8.sun.nio.fs.WindowsPathsource code at GitHubsun.nio.fs.WindowsPathsource code at GitHubThe key line of the latter implementation starts at the line 411, so basically, the latter implementation normalizes the paths before taking into calculation of the relative path:
Digging further, the implementation changes between
jdk8-b120(source) andjdk-9+95(source). Since the modular system was introduced, both the classes implementation and location differ:/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.javaThe most straightforward way to go is to normalize both paths first before relativizing them. But I have no idea whether it completely covers all the
java.nio.file.Pathimplementations and is safe to do so.