sample code:
class foo {
public static void main(String ... args) throws Exception {
File f = new File("bnevins");
System.out.println("canonical --- " + f.getCanonicalPath());
System.out.println("absolute --- " + f.getAbsolutePath());
}
}
UNIX directory where I run foo:
~/temp>ls -l
total 14
-rw-r--r-- 1 bnlocal other 9 Sep 17 13:24 a
-rw-r--r-- 1 bnlocal other 9 Sep 17 13:25 b
l
rwxrwxrwx 1 bnlocal other 13 Feb 28 23:32 bnevins ->
/home/bnevins/
~/temp>java foo
canonical --- /home/bnevins
absolute --- /export/home/bnlocal/temp/bnevins
------------------------------------------------------
There are 2 interesting properties of canonical vs. absolute files:
1) on all platforms there is one and only one canonical filename for a
file. There are many possible absolute filenames for a given file. So
if you are comparing filenames to see if they are pointing at the same
file -- canonical is guaranteed to work and absolute isn't.
2) on *NIX platforms, but not on Windows, absolute is the link file
itself. canonical is the file that the link is pointing at (see above).
2a) this fact is used in FileUtils to figure out if a file is a link or
a "real" file -- the canonical and absolute are different. Of course
you have to make sure you aren't using "." or ".." in the filename for
that trick to work. Java IO has no support for this otherwise.
The bug had to do with a user doing a delete-domain. User deletes a
domain that has a soft-linked file to some other area on his disk.
Using canonical paths resulted in wiping out the files that the link
pointed at. Using absolute results in just the linked file getting
deleted.
---------
The new method, absolutize() is in one and only one place so changing
all calls to getAbsolute instead of getCanonical is trivial-- if it is
decided to be an issue.
Vince Kraemer wrote:
Jerome Dochez wrote:
On Feb 28, 2008, at 10:29 AM, Kedar Mhaswade wrote:
[snip]
No, it is neither purely academic, nor is it Windows specific.
e.g. See the following snippet:
-------------------------------
import java.io.*;
class Foo {
public static void main(String ... args) throws Exception {
File f = new File("../f");
System.out.println(f.getCanonicalPath());
System.out.println(f.getAbsolutePath());
}
}
------------------------------
On my Mac OS X, this produces the following output:
------------------------------
/Users/kedar/Projects/f
/Users/kedar/Projects/Java/../f
------------------------------
Now, though these are "equivalent", I think it's related to what
the programmer wanted. Maybe the programmer thinks "absolutizing"
means the former. I see no problems with that as long as the
programmer is aware of the fact that getCanonicalPath() is going
to result in slightly lower performance because it does some
file system calls.
I thought that we were discussing getCanonicalFile()... not
getCanonicalPath()... but that is just a nit... the performance issue
may be worth noting, though.
If this file leaks out of the class (the code is in a private method
that returns a File), then getCanonicalFile() is probably a better
choice.
If the file stays under the control of the class, getAbsoluteFile() may
be the better choice...
I see, thanks for the clarification.
Now didn't we have a bug in V1 or V2 with this getCanonical() type of
calls. I seem to remember some escalations because it was failing with
NFS mounted drive or something. I don't precisely remember but maybe
someone does ?
I did not see a bug in the issuetracker that had the string
getCanonical.* in any of its description entries... I am not saying
that there wasn't an issue. I am saying it is hard to find. If there
is an issue that was caused by the use of getCanonical*(), we should
probably put that data into the issue tracker. We may need to move the
data out of the bugtraq database (after we strip any customer related
info from the entry)...
vbk
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: dev-help@glassfish.dev.java.net
--
Byron Nevins Work 408-276-4089, Home 650-359-1290, Cell 650-784-4123 - Sun Microsystems, Inc.