Cross platform way to detect a symbolic link / junction point?

cross-platform, java, windows

Solution

There doesn't appear to be any cross platform mechanism for this in Java 6 or earlier, though its a fairly simple task using JNA

interface Kernel32 extends Library {
  public int GetFileAttributesW(WString fileName);
}

static Kernel32 lib = null;
public static int getWin32FileAttributes(File f) throws IOException { 
  if (lib == null) {
    synchronized (Kernel32.class) {
      lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
    }
  }
  return lib.GetFileAttributesW(new WString(f.getCanonicalPath()));
}

public static boolean isJunctionOrSymlink(File f) throws IOException {
  if (!f.exists()) { return false; }
  int attributes = getWin32FileAttributes(f);
  if (-1 == attributes) { return false; }
  return ((0x400 & attributes) != 0);
}

EDIT: updated per comment about possible error return by `getWin32FileAttributes()`

Problem

In java, a symbolic link in a Unix environment can be detected by comparing the file's canonical and absolute path. However, this trick does not work on windows. If I execute ``` mkdir c:\foo mklink /j c:\bar ``` from the command line and then execute the following lines in java ``` File f = new File("C:/bar"); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); ``` the output is ``` C:\bar C:\bar ``` Is there any pre-Java 7 way of detecting a junction in windows?

Original source