How to check symbolic link in Java and why Apache common.io.FileUtils implementation is wrong

By angsuman, Gaea News Network
Saturday, December 4, 2010

Checking for symbolic link (in supported platform) is a long time requirement of Java developers.

Patrick @ onyxbits solved the problem using JNI which is a legitimate approach. However it is platform dependent and consequently you will have to provide precompiled binary for every supported platform.

Apache commons project used an interesting approach in an attempt to solve it using pure Java. The method from FileUtils trunk reads:

/**
 * Determines whether the specified file is a Symbolic Link rather than an actual file.
 *


 * Will not return true if there is a Symbolic Link anywhere in the path,
 * only if the specific file is.
 *
 * @param file the file to check
 * @return true if the file is a Symbolic Link
 * @throws IOException if an IO error occurs while checking the file
 * @since Commons IO 2.0
 */
public static boolean isSymlink(File file) throws IOException {
    if (file == null) {
        throw new NullPointerException("File must not be null");
    }
    if (FilenameUtils.isSystemWindows()) {
        return false;
    }
    File fileInCanonicalDir = null;
    if (file.getParent() == null) {
        fileInCanonicalDir = file;
    } else {
        File canonicalDir = file.getParentFile().getCanonicalFile();
        fileInCanonicalDir = new File(canonicalDir, file.getName());
    }
    if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) {
        return false;
    } else {
    return true;
}

Unfortunately this method is incorrect. For example, calling isSymlink() with “.” or “..” returns true. Also Windows 2000, Windows 7 and Windows Vista supports symbolic links which this method seems to ignore.

Fortunately Java, specifically JDK 7, has provided as much simpler pure-Java solution to the symbolic link problem. Here is how you can check for symbolic link in Java:

public static boolean isSymLink(File file) {
    return java.nio.file.attribute.Attributes.readBasicFileAttributes(file.toPath(), java.nio.file.LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
}

Note: I have noticed that some early version of JDK 7 didn’t support it. However the later and recent versions has support for it.

YOUR VIEW POINT
NAME : (REQUIRED)
MAIL : (REQUIRED)
will not be displayed
WEBSITE : (OPTIONAL)
YOUR
COMMENT :