springandangular
springandangular

Reputation: 145

Why does Files.createSymbolicLink() throw java.nio.file.NoSuchFileException for link parameter?

I am trying to create a symbolic link on a Linux machine using Java.

I am using java.nio.file.Files.createSymbolicLink. The first parameter is a Path link, and the second parameter is a Path target.

I have verified that the target Path exists, and that the link Path does not exist but is the symbolic link that I want created.

Why do I keep getting java.nio.file.NoSuchFileException: <link path> when the code is run? I cannot find in documentation why I would get a NoSuchFileException for the link path. I would understand getting the error for the target path, but the target path definitely exists.

public static Path createSymbolicLink(Path link,
                                      Path target,
                                      FileAttribute<?>... attrs)
                               throws IOException

I tried tried swapping target and link parameters and it worked, but the symlink is backwards. I need a symlink in /var/foo to /data/bar but instead I got a symlink from /data/bar to /var/foo.

The parent directories of link all exist.

I tried digging through the actual OpenJDK Java code to see why a NoSuchFileException is being thrown, but it is not clear.

My only guess is it is something to do with the fact that I am trying to create a symbolic link to a directory, not a file. I will tinker with trailing file slashes to see if that helps.

Upvotes: 1

Views: 1356

Answers (3)

user3076105
user3076105

Reputation: 416

This exception is also thrown when the target is an empty path. For example, with the following:

    Path l=Paths.get("mylink"), t=Paths.get("");
    Files.createSymbolicLink(l, t);

Output:

Exception java.nio.file.NoSuchFileException: mylink
      at UnixException.translateToIOException (UnixException.java:92)
      at UnixException.rethrowAsIOException (UnixException.java:106)
      at UnixException.rethrowAsIOException (UnixException.java:111)
      at UnixFileSystemProvider.createSymbolicLink (UnixFileSystemProvider.java:471)
      at Files.createSymbolicLink (Files.java:1069)
      at (#40:1)

I guess the reason for only the link showing up is that the implementation simply calls UnixException.rethrowAsIOException(link) instead of the alternative with two UnixPath arguments, UnixException.rethrowAsIOException(link, target).

The latter would end up as a new FileSystemException(file, other)

Upvotes: 0

springandangular
springandangular

Reputation: 145

I discovered the issue.

If you get a java.nio.file.NoSuchFileException which complains about the link path and not the target path, make sure your application can write to the link path.

In my case, the link path was valid and the target path was valid, but my application could not access the link path for writing so an unclear java.nio.file.NoSuchFileException was thrown.

As @ThomasKläger noted, you may also receive a NoSuchFileException if a parent directory of the symlink path does not exist.

Upvotes: 1

amy
amy

Reputation: 644

From looking at the docs it seems the target is the one that may or may not exist yet and the link attribute is the one that must indeed exist, not the other way around, as your question seems to suggest.

Upvotes: 1

Related Questions