You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Jesse Glick <Je...@netbeans.com> on 2001/06/26 20:35:03 UTC

[PATCH] Avoid canonicalization of symlinks

I have some memory of a similar thread coming up on the list before but 
don't remember any particular resolution.

The attached patch avoids any use of File.getCanonicalPath() within the 
Ant core. In current sources, any file names encountered are 
canonicalized quite aggressively, which on Unix means symlinks are followed.

Why do I think this is bad? Symlink farms are broken by this "feature". 
Consider a situation like this (which has bitten me):

common/build.xml: <ant dir="../a"/> <ant dir="../b"/> ...
a/build.xml: ...
b/build.xml: ...

Pretend a/ and b/ are both major code modules, and common/ some 
infrastructure to build them both. Now imagine you want to work on a CVS 
branch of a/ while keeping the public trunk of b/. You might try this:

mkdir ~/testing
cd ~/testing
cvs co -rtestbranch a
ln -s ~/trunksrc/b b
ln -s ~/trunksrc/common common
ant -f common/build.xml

You expect this to build stuff in ~/testing/b/ == ~/trunksrc/b/, which 
it does, and ~/testing/a/, which it does *not*: it uses ~/trunksrc/a/ 
(hopefully you notice!). Is this intuitive for anyone?

The reason is that the canonicalization of the file right away tells Ant 
that the build script it is starting with is 
/home/me/trunksrc/common/build.xml, and "../a" relative to that is 
/home/me/trunksrc/a/.

The patch simply disables canonicalization while continuing to use 
absolute paths, so that Ant will think of 
/home/me/testing/common/build.xml as its starting point, and never 
explicitly know about /home/me/trunksrc/ at all. In other words, the 
symlink farm you set up is honored by Ant. (It also makes the code a bit 
simpler.)

Surely someone will have a counterexample where they *do* want symlinks 
followed (I'm not quite sure why but could imagine it). Wouldn't this 
more safely be done at explicit user request? E.g.:

<property name="maybe-symlinked" location="../other-project"/>
<!-- Hypothetical new task: -->
<canonicalize property="other-proj-dir" location="${maybe-symlinked}"/>
<!-- Task which is not symlink-safe (caches?): -->
<dosomethingwith file="${other-proj-dir}/foo"/>

Also consider build logs in a big Unix shared-disk system:

ant -f /sources/build.xml all
[javac] Compiling 2 files to /sources/java
    (vs.)
[javac] Compiling 2 files to /mnt/dsk0013/projects/foo/sources/java

There may be value in leaving canonicalization on in Path.java as it 
could prevent duplicates differing only in symlink path. I have no idea 
if this happens commonly, or if it is really a problem when it does.

Other pluses/minuses?

-Jesse

-- 
Jesse Glick   <ma...@netbeans.com>
NetBeans, Open APIs  <http://www.netbeans.org/>
tel (+4202) 3300-9161 Sun Micro x49161 Praha CR

Re: [PATCH] Avoid canonicalization of symlinks

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 26 Jun 2001, Jesse Glick <Je...@netbeans.com> wrote:

> I have some memory of a similar thread coming up on the list before
> but don't remember any particular resolution.
 
I don't think there has been some kind of resolution - it came at the
wrong time (preparation of the 1.3 release).

> The attached patch avoids any use of File.getCanonicalPath() within
> the Ant core.

I've just started to tackle the symlink related bug reports - to me it
looks as if your approach (not using the canonical path) would be the
better approach.

Stefan