I'm trying to resolve canonical paths for all the files in a folder tree, but for some reason it will not resolve them (and intermittently the JVM security code will resolve the symlink properly within the FilePermission and cause a security error).
Env:
$ java -version
java version "1.6.0_23"
OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre11-0ubuntu1.11.10.2)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
A known symlink in the system is /usr/share/java/gnome-java-bridge.jar:
$ ls -l /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar
lrwxrwxrwx 1 root root 50 2012-02-24 13:39 /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar -> ../../../../../../share/java/gnome-java-bridge.jar
The following code should resolve this known symlink:
String symlinkedFilePath =
"/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar";
File symlinkedFile = new File(symlinkedFilePath);
System.out.println(symlinkedFile.getAbsolutePath());
System.out.println(symlinkedFile.getCanonicalPath());
but produces:
/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar
/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar
A further test, using the following code, will sometimes return true for the permission check, but sometimes will return false:
String symlinkedFilePath =
"/usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar";
File symlinkedFile = new File(symlinkedFilePath);
FilePermission recursivePermission = new FilePermission(
symlinkedFile.getParentFile().getParent() + "/-", "read");
FilePermission filePermission = new FilePermission(
symlinkedFile.getAbsolutePath(), "read");
System.out.println(recursivePermission);
System.out.println(filePermission);
System.out.println(
"Can read symlink: " + recursivePermission.implies(filePermission));
The typical result is:
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/- read)
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar read)
Can read symlink: true
but when debugging, if I step through the creation of the FilePermission on the target file, internally the path is resolved to the symlink, and the output results in:
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/- read)
(java.io.FilePermission /usr/lib/jvm/java-6-openjdk/jre/lib/ext/gnome-java-bridge.jar read)
Can read symlink: false
The problem is that within the context of the app in which the permission checking actually takes place, the symlink is always resolved by the FilePermission object, but never by my own calls to file.getCanonicalPath() as demonstrated above.
Does this make sense to anyone?
The only way to fix these broken symlinks is by deleting them. Your system contains hundreds of dangling links and no one has the time to check for these links manually. In such cases, Linux tools and commands prove to be really helpful.
There are two ways to solve the “Too many levels of symbolic links” error. We can pass the source parameter as either an absolute or relative path.
A symlink is a symbolic Linux/ UNIX link that points to another file or folder on your computer, or a connected file system. This is similar to a Windows shortcut. Symlinks can take two forms: Soft links are similar to shortcuts, and can point to another file or directory in any file system.
Detecting a Symbolic Link To determine whether a Path instance is a symbolic link, you can use the isSymbolicLink(Path) method. The following code snippet shows how: Path file = ...; boolean isSymbolicLink = Files. isSymbolicLink(file);
A colleague of mine confirmed the issue on OpenJDK 6u23, but not on any prior or following versions. That being said, since the issue has
A) a work around in the form of the system property
-Dsun.io.useCanonCaches=false
OR
-Dsun.io.useCanonPrefixCache=false
B) appears to be resolved in the later build (u24)
there appears to be little motivation to dig any deeper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With