On Thu, 11 Dec 2025 01:09:48 GMT, Weijun Wang <[email protected]> wrote:
>> Hmm, I also got confused for a moment, it seems important to make a >> distinction between file links and directory links, and how each platform >> handles each of them. >> >> We are no longer resolving any type of link, here: >> >> https://github.com/openjdk/jdk/blob/c33bf62c2831acefd90ec476fcfb6d853be873ee/src/java.base/share/classes/java/security/Security.java#L250-L258 >> >> `currentPath.resolveSibling(path)` is equivalent to >> `currentPath.getParent().resolve(path)` when `currentPath` has a parent. >> >> If `currentPath` is `/tmp/a/b/f1` and `path` is `../f2`, after line 257, >> path will be `/tmp/a/b/../f2`. >> >> In the [previous _Linux_ example](#discussion_r2607247993), `/tmp/a/b` is a >> **directory** symbolic link to `/tmp/x/y`, so `/tmp/a/b/../f2` still reads >> `/tmp/x/f2` (at the OS level) when opening the file. >> >> <details> >> <summary>Extension of that <em>Linux</em> example's <code>jshell</code> >> snippet showing how <code>/tmp/a/b/../f2</code> can be opened</summary> >> >> >> jshell -<<'EOF' >> Path current = Path.of("/tmp/a/b/f1"); >> Path included = current.resolveSibling("../f2"); >> >> Map<String, Path> opts = new LinkedHashMap<String, Path>(); >> opts.put("included", included); >> opts.put("included.toRealPath()", included.toRealPath()); >> opts.put("included.toRealPath(LinkOption.NOFOLLOW_LINKS)", >> included.toRealPath(LinkOption.NOFOLLOW_LINKS)); >> opts.put("included.normalize()", included.normalize()); >> >> for (Map.Entry<String, Path> opt : opts.entrySet()) { >> System.out.println(); >> System.out.println(opt.getKey() + " -> " + opt.getValue()); >> Files.newInputStream(opt.getValue()); >> System.out.println("succesfully opened"); >> } >> EOF >> >> >> Output: >> >> >> included -> /tmp/a/b/../f2 >> succesfully opened >> >> included.toRealPath() -> /tmp/x/f2 >> succesfully opened >> >> included.toRealPath(LinkOption.NOFOLLOW_LINKS) -> /tmp/a/b/../f2 >> succesfully opened >> >> included.normalize() -> /tmp/a/f2 >> Exception java.nio.file.NoSuchFileException: /tmp/a/f2 >> at UnixException.translateToIOException (UnixException.java:92) >> at UnixException.rethrowAsIOException (UnixException.java:106) >> at UnixException.rethrowAsIOException (UnixException.java:111) >> at UnixFileSystemProvider.newByteChannel >> (UnixFileSystemProvider.java:261) >> at Files.newByteChannel (Files.java:380) >> at Files.newByteChannel (Files.java:432) >> at FileSystemProvider.newInputStream (FileSystemProvider.java:420) >> at Files.newInp... > > Thanks for the detailed explanation. > > I like your attitude to leave the path resolution to the simplest API. > > For debugging output, I prefer the 3rd choice for the same reason that it's > the simplest. Also, it preserves the original include form. I would assume > the reader wants to see this. Great, so I'll leave it as it currently is, and update the PR description. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24465#discussion_r2610336040
