You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Stefan Bodewig <bo...@apache.org> on 2026/02/06 20:31:20 UTC

Windows Changes in Current master

Hi all

in the "Planning a Release" thread I said

> Personally I have at least one Bugzilla issue I want to look into and a
> small improvement waiting where we can get rid of some pre-Java7ism.

The small improvement I had in mind was using Path.toRealPath instead of
getCanonical file as it was supposed to be better in some way.  While
testing the change on Windows I realized it has in fact become inferior
with Java 24.

Until Java 24, toRealPath would resolve symlinks and junctions (a
special kind of NTFS only symbolic link only for directories and not
allowed to cross volume boundaries) while getCanonicalPath did not -
with 24 getCanonicalPath has caught up. Unlike getCanonicalPath
toRealPath throws an exception when the file or the link target doesn't
exist, this is why I call it inferior.

So instead of replacing all getCanonicalPath invocations with toRealPath
I plan to replace them with a wrapper than only uses toRealPath if
running on Windows and on Java prior to 21 and if the file actually
exists.

This change also made it easier to deal with junctions points, something
Maarten asked for about three and a half years ago
https://bz.apache.org/bugzilla/show_bug.cgi?id=66293

I intend to make all of Ant treat junctions like symlinks before cutting
the release.

All of this is introduces subtle changes on Windows while nothing really
changes for any other platform. I don't really expect people to be
affected much as I don't expect file system links to be common at
all. In either case some extended testing by Windows users would be good
and I plan to ask people on the users mailing list once the RC is ready
to be voted on.

What I still plan to do:

* look through all tasks with special handling of symlinks and make sure
  they also know about junctions.

* introduce a condition "can I create symlinks" as <symlink> should also
  work on Windows if the stars are properly aligned (basically if Ant
  runs as admin or developer mode is enabled). This would allow some
  "unix only" tests to also run on (some) Windows boxes

* make sure the manual states what really happens WRT symlinks in
  several places.

I have already introduced a new task <mklink> that only works on Windows
(as it uses a cmd.exe built-in) which can be used to create hardlinks,
symbolic links and junctions on NTFS.

Stefan

PS I learned so many new things about NTFS during this, which alone has
been worth the effort :-)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Windows Changes in Current master

Posted by Stefan Bodewig <bo...@apache.org>.
Hi Jens

On 2026/02/09 09:24:30 Jens Hofschröer wrote:

> With the release candicate 1 this no longer works an my build breaks.
> I created a simple sample script to demonstrate the difference:

I have just pushed a change to Ant's master branch that should "properly" resolve symbolic links or junctions in parent directories of non-existant files. Is there any chance you could try the current master?

Cheers

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Need Advice (was Re: Windows Changes in Current master)

Posted by Stefan Bodewig <bo...@apache.org>.
On 2026-03-24, Jaikiran Pai wrote:

> Hello Stefan,

> On 22/02/26 4:58 pm, Stefan Bodewig wrote:
>>> Should be try to emulate Linux behavior on Windows? I.e. set basedir to
>>> the resolved symlink junction when starting? I'm not sure this would
>>> break more things.
>> I'd leave it at what we currently have.

> I had a look at the latest Ant master branch and what you have looks
> fine to me. I think trying to do something very specific to basedir to
> match how it behaves on Linux isn't worth the unexpected issues it
> might introduce.

Thank you Jaikiran.

I'll cut a new release candidate the coming days.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Need Advice (was Re: Windows Changes in Current master)

Posted by Jaikiran Pai <ja...@apache.org>.
Hello Stefan,

On 22/02/26 4:58 pm, Stefan Bodewig wrote:
>> Should be try to emulate Linux behavior on Windows? I.e. set basedir to
>> the resolved symlink junction when starting? I'm not sure this would
>> break more things.
> I'd leave it at what we currently have.

I had a look at the latest Ant master branch and what you have looks 
fine to me. I think trying to do something very specific to basedir to 
match how it behaves on Linux isn't worth the unexpected issues it might 
introduce.

-Jaikiran


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Need Advice (was Re: Windows Changes in Current master)

Posted by Stefan Bodewig <bo...@apache.org>.

On 2026/02/14 16:59:08 Stefan Bodewig wrote:

> getCanonicalPath/toRealPath only
> resolve symlinks for files/directories that exist.

Actually Path#toRealPath always throws if the file doesn't exist (and is documented to do so).
The real difference between Windows and Unix is in getCanonicalPath which
doesn't resolve symlinks in ancestors on Windows if the file itself doesn't exist. It
does (in Java 24+) if the file exists. On Linux (where I tested it), it will resolve symlinks
in ancestors in either case. 

> We could (a) live with it and document it, (b) try to be smart make
> getResolvedPath walk up a files parents until it finds one that exists,
> resolve that and then append the paths we've stripped back again. Any
> other ideas?

I intend to open a bug report on this with Java. And by now I believe we must implement
 the "walk up the tree" fallback in Ant in order to avoid breaking builds. Builds already
break for people upgrading Java running the last released version of Ant.

> > Another difference is that on Linux Ant has already resolved the symlink
> > from the start. ${ant.file} and ${basedir} point to the real paths while
> > they are still their symlinked/junctioned version on Windows.
> 
> This is Java's File constructor.

I'll also open a bug report about that.

> Should be try to emulate Linux behavior on Windows? I.e. set basedir to
> the resolved symlink junction when starting? I'm not sure this would
> break more things.

I'd leave it at what we currently have.

Something I also realized during testing is that because of this running a build via
<antcall> setting the basedir sees a different basedir than running a fresh Ant build
inside the directory of the antcall'ed build. We don't resolve the "basedir" so it ends up
with unresolved symlinks. I'd document this.

Also I'm thinking about adding a new attribute to <property location> that would resolve
symlinks/junctions before setting the property.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Need Advice (was Re: Windows Changes in Current master)

Posted by Stefan Bodewig <bo...@apache.org>.
[context: https://gist.github.com/bodewig/1c48a3ff2faf44ec21aae93ee922c3bd]

On 2026-02-14, Stefan Bodewig wrote:

> What I didn't expect: only the result of Java21/Ant 1.10.15 on Windows
> looks like the one on Linux as far as the "relative" property is
> concerned. For the other cases it looks as if the relative resultion
> happens between a basedir that has been resolved to the
> non-linked/junctioned version and a file that still has the
> symlink/junctioned path on Windows.

The reason is the file doesn't exist. getCanonicalPath/toRealPath only
resolve symlinks for files/directories that exist. If I add

    <mkdir dir="build"/>
    <touch file="${tempfile}"/>

to Jens' build file just before the relative property is resolved, then
I get the expected result of build\somefile.txt.

So this means the new FileUtils.resolveFile only works properly for
existing files/directories - for others it may fail to resolve symlinks.

In most cases this is not relevant, but in Jens' case it is as we
compare a non-existent and an existent file.

We could (a) live with it and document it, (b) try to be smart make
getResolvedPath walk up a files parents until it finds one that exists,
resolve that and then append the paths we've stripped back again. Any
other ideas?

> Another difference is that on Linux Ant has already resolved the symlink
> from the start. ${ant.file} and ${basedir} point to the real paths while
> they are still their symlinked/junctioned version on Windows.

This is Java's File constructor.

new File(".").getAbsolutePath() already points to the resolved directory
when the current working directory is a symlink on Linux. It does not on
Windows.

Should be try to emulate Linux behavior on Windows? I.e. set basedir to
the resolved symlink junction when starting? I'm not sure this would
break more things.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Windows Changes in Current master

Posted by Stefan Bodewig <bo...@apache.org>.
On 2026-02-09, Jens Hofschröer wrote:

> I think this _will_ break some builds. At least mine.
> I am working inside a folder from a junctioned path. In my buildscript
> I need to find a relative path to a file. This works find in 1.10.15.

> With the release candicate 1 this no longer works an my build breaks.
> I created a simple sample script to demonstrate the difference:

I've expanded on this a bit in
https://gist.github.com/bodewig/1c48a3ff2faf44ec21aae93ee922c3bd
and the results surprised me.

There is no difference between 1.10.15 and 1.10.16 on Linux which is
expected. Also the Windows results of the combination Java 21/Ant
1.10.15 is different from each other combination (i.e. upgrading Java or
Ant alone is enough and the results for the other three combinations are
identical). I also expected this.

What I didn't expect: only the result of Java21/Ant 1.10.15 on Windows
looks like the one on Linux as far as the "relative" property is
concerned. For the other cases it looks as if the relative resultion
happens between a basedir that has been resolved to the
non-linked/junctioned version and a file that still has the
symlink/junctioned path on Windows.

Another difference is that on Linux Ant has already resolved the symlink
from the start. ${ant.file} and ${basedir} point to the real paths while
they are still their symlinked/junctioned version on Windows. It looks
as if the resolution happens for basedir on the fly when the relative
property is resolved but not for the file that is resolved. At first
glance I don't see why. Need to dig deeper.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Windows Changes in Current master

Posted by Stefan Bodewig <bo...@apache.org>.
On 2026-02-09, Jens Hofschröer wrote:

> Am 09.02.2026 um 12:25 schrieb Stefan Bodewig:
>> Many thanks Jens, this is exactly why I asked people to test the release
>> candidate.

>> Can you tell us which version of Java you are using?

>> I suspect you are using Java < 24 and things would break with Java 24+
>> (i.e. the current LTS of 25) for you even when using Ant 1.10.15.

>> Prior to Java 24 File#getCanonicalPath does not follow junctions or
>> symlinks on Windows while Path#toRealPath does. One change in 1.10.16 is
>> to use Path#toRealPath here. But if I'm correct, then the change to
>> getCanonicalPath in Java 24+ would have the same effect on your build.
> Yes, you are right. I first run it with JDK17 and testet it now with
> JDK21 and JDK25 with your expected result.

Great, so Java 24 breaks Ant in subtle ways.

>> For your specific case we probably need something like followSymlinks on
>> <property> that you would need to set to false in order to resolve the
>> file the same way as before.

> This would be a valid workaround I think.

Yes. I'll be looking for similar cases where we can at least help our
users, even though it is not really related to the changes in 1.10.16 -
the issues just show up earlier.

We'll defer the release for the changes necessary.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Windows Changes in Current master

Posted by Jens Hofschröer <em...@nigjo.de>.
Hi

Am 09.02.2026 um 12:25 schrieb Stefan Bodewig:
> Many thanks Jens, this is exactly why I asked people to test the release
> candidate.
> 
> Can you tell us which version of Java you are using?
> 
> I suspect you are using Java < 24 and things would break with Java 24+
> (i.e. the current LTS of 25) for you even when using Ant 1.10.15.
> 
> Prior to Java 24 File#getCanonicalPath does not follow junctions or
> symlinks on Windows while Path#toRealPath does. One change in 1.10.16 is
> to use Path#toRealPath here. But if I'm correct, then the change to
> getCanonicalPath in Java 24+ would have the same effect on your build.
Yes, you are right. I first run it with JDK17 and testet it now with 
JDK21 and JDK25 with your expected result.

> For your specific case we probably need something like followSymlinks on
> <property> that you would need to set to false in order to resolve the
> file the same way as before.
This would be a valid workaround I think.

Jens

> On 2026-02-09, Jens Hofschröer wrote:
> 
>> I think this _will_ break some builds. At least mine.
>> I am working inside a folder from a junctioned path. In my buildscript
>> I need to find a relative path to a file. This works find in 1.10.15.
> 
>> With the release candicate 1 this no longer works an my build breaks.
>> I created a simple sample script to demonstrate the difference:
> 
[cut]

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Windows Changes in Current master

Posted by Stefan Bodewig <bo...@apache.org>.
Many thanks Jens, this is exactly why I asked people to test the release
candidate.

Can you tell us which version of Java you are using?

I suspect you are using Java < 24 and things would break with Java 24+
(i.e. the current LTS of 25) for you even when using Ant 1.10.15.

Prior to Java 24 File#getCanonicalPath does not follow junctions or
symlinks on Windows while Path#toRealPath does. One change in 1.10.16 is
to use Path#toRealPath here. But if I'm correct, then the change to
getCanonicalPath in Java 24+ would have the same effect on your build.

For your specific case we probably need something like followSymlinks on
<property> that you would need to set to false in order to resolve the
file the same way as before.

Stefan

On 2026-02-09, Jens Hofschröer wrote:

> I think this _will_ break some builds. At least mine.
> I am working inside a folder from a junctioned path. In my buildscript
> I need to find a relative path to a file. This works find in 1.10.15.

> With the release candicate 1 this no longer works an my build breaks.
> I created a simple sample script to demonstrate the difference:

> ```xml
> <?xml version="1.0" encoding="UTF-8"?>
> <project name="reldemo_for_1.10.16" default="demo" basedir=".">
>   <!-- create C:\Temp\reldemo and copy this file to that folder. -->
>   <!-- call: mklink /J C:\Temp\reldemo_junction C:\Temp\reldemo -->
>   <!-- C:\Temp\reldemo_junction> ant -->
>   <target name="demo">
>     <property name="tempfile" value="build/somefile.txt"/>
>     <echo>target:${tempfile}</echo>
>     <property name="tmp.resolved" location="${tempfile}"/>
>     <echo>resolved:${tmp.resolved}</echo>
>     <property name="tmp.relative" location="${tmp.resolved}"
>                   relative="true" basedir="${basedir}" />
>     <echo>relative:${tmp.relative}</echo>
>   </target>

>   <!-- Result from 1.10.15:
> demo:
>      [echo] target:build/somefile.txt
>      [echo] resolved:d:\Temp\reldemo_junction\build\somefile.txt
>      [echo] relative:build\somefile.txt
>   -->

>   <!-- Result from 1.10.16:
> demo:
>      [echo] target:build/somefile.txt
>      [echo] resolved:d:\Temp\reldemo_junction\build\somefile.txt
>      [echo] relative:..\reldemo_junction\build\somefile.txt
>   -->

> </project>
> ```

> The relative path needs to be resolved from the basedir. It should not
> depend on beeing inside a Junction or not.

> Greetings
> Jens

> Am 06.02.2026 um 21:31 schrieb Stefan Bodewig:
>> Hi all

>> in the "Planning a Release" thread I said

>>> Personally I have at least one Bugzilla issue I want to look into and a
>>> small improvement waiting where we can get rid of some pre-Java7ism.

>> The small improvement I had in mind was using Path.toRealPath instead of
>> getCanonical file as it was supposed to be better in some way.  While
>> testing the change on Windows I realized it has in fact become inferior
>> with Java 24.

>> Until Java 24, toRealPath would resolve symlinks and junctions (a
>> special kind of NTFS only symbolic link only for directories and not
>> allowed to cross volume boundaries) while getCanonicalPath did not -
>> with 24 getCanonicalPath has caught up. Unlike getCanonicalPath
>> toRealPath throws an exception when the file or the link target doesn't
>> exist, this is why I call it inferior.

>> So instead of replacing all getCanonicalPath invocations with toRealPath
>> I plan to replace them with a wrapper than only uses toRealPath if
>> running on Windows and on Java prior to 21 and if the file actually
>> exists.

>> This change also made it easier to deal with junctions points, something
>> Maarten asked for about three and a half years ago
>> https://bz.apache.org/bugzilla/show_bug.cgi?id=66293

>> I intend to make all of Ant treat junctions like symlinks before cutting
>> the release.

>> All of this is introduces subtle changes on Windows while nothing really
>> changes for any other platform. I don't really expect people to be
>> affected much as I don't expect file system links to be common at
>> all. In either case some extended testing by Windows users would be good
>> and I plan to ask people on the users mailing list once the RC is ready
>> to be voted on.

>> What I still plan to do:

>> * look through all tasks with special handling of symlinks and make sure
>>    they also know about junctions.

>> * introduce a condition "can I create symlinks" as <symlink> should also
>>    work on Windows if the stars are properly aligned (basically if Ant
>>    runs as admin or developer mode is enabled). This would allow some
>>    "unix only" tests to also run on (some) Windows boxes

>> * make sure the manual states what really happens WRT symlinks in
>>    several places.

>> I have already introduced a new task <mklink> that only works on Windows
>> (as it uses a cmd.exe built-in) which can be used to create hardlinks,
>> symbolic links and junctions on NTFS.

>> Stefan

>> PS I learned so many new things about NTFS during this, which alone has
>> been worth the effort :-)

>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
>> For additional commands, e-mail: dev-help@ant.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Windows Changes in Current master

Posted by Jens Hofschröer <em...@nigjo.de>.
Hi

I think this _will_ break some builds. At least mine.
I am working inside a folder from a junctioned path. In my buildscript I 
need to find a relative path to a file. This works find in 1.10.15.

With the release candicate 1 this no longer works an my build breaks.
I created a simple sample script to demonstrate the difference:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="reldemo_for_1.10.16" default="demo" basedir=".">
   <!-- create C:\Temp\reldemo and copy this file to that folder. -->
   <!-- call: mklink /J C:\Temp\reldemo_junction C:\Temp\reldemo -->
   <!-- C:\Temp\reldemo_junction> ant -->
   <target name="demo">
     <property name="tempfile" value="build/somefile.txt"/>
     <echo>target:${tempfile}</echo>
     <property name="tmp.resolved" location="${tempfile}"/>
     <echo>resolved:${tmp.resolved}</echo>
     <property name="tmp.relative" location="${tmp.resolved}"
                   relative="true" basedir="${basedir}" />
     <echo>relative:${tmp.relative}</echo>
   </target>

   <!-- Result from 1.10.15:
demo:
      [echo] target:build/somefile.txt
      [echo] resolved:d:\Temp\reldemo_junction\build\somefile.txt
      [echo] relative:build\somefile.txt
   -->

   <!-- Result from 1.10.16:
demo:
      [echo] target:build/somefile.txt
      [echo] resolved:d:\Temp\reldemo_junction\build\somefile.txt
      [echo] relative:..\reldemo_junction\build\somefile.txt
   -->

</project>
```

The relative path needs to be resolved from the basedir. It should not 
depend on beeing inside a Junction or not.

Greetings
Jens

Am 06.02.2026 um 21:31 schrieb Stefan Bodewig:
> Hi all
> 
> in the "Planning a Release" thread I said
> 
>> Personally I have at least one Bugzilla issue I want to look into and a
>> small improvement waiting where we can get rid of some pre-Java7ism.
> 
> The small improvement I had in mind was using Path.toRealPath instead of
> getCanonical file as it was supposed to be better in some way.  While
> testing the change on Windows I realized it has in fact become inferior
> with Java 24.
> 
> Until Java 24, toRealPath would resolve symlinks and junctions (a
> special kind of NTFS only symbolic link only for directories and not
> allowed to cross volume boundaries) while getCanonicalPath did not -
> with 24 getCanonicalPath has caught up. Unlike getCanonicalPath
> toRealPath throws an exception when the file or the link target doesn't
> exist, this is why I call it inferior.
> 
> So instead of replacing all getCanonicalPath invocations with toRealPath
> I plan to replace them with a wrapper than only uses toRealPath if
> running on Windows and on Java prior to 21 and if the file actually
> exists.
> 
> This change also made it easier to deal with junctions points, something
> Maarten asked for about three and a half years ago
> https://bz.apache.org/bugzilla/show_bug.cgi?id=66293
> 
> I intend to make all of Ant treat junctions like symlinks before cutting
> the release.
> 
> All of this is introduces subtle changes on Windows while nothing really
> changes for any other platform. I don't really expect people to be
> affected much as I don't expect file system links to be common at
> all. In either case some extended testing by Windows users would be good
> and I plan to ask people on the users mailing list once the RC is ready
> to be voted on.
> 
> What I still plan to do:
> 
> * look through all tasks with special handling of symlinks and make sure
>    they also know about junctions.
> 
> * introduce a condition "can I create symlinks" as <symlink> should also
>    work on Windows if the stars are properly aligned (basically if Ant
>    runs as admin or developer mode is enabled). This would allow some
>    "unix only" tests to also run on (some) Windows boxes
> 
> * make sure the manual states what really happens WRT symlinks in
>    several places.
> 
> I have already introduced a new task <mklink> that only works on Windows
> (as it uses a cmd.exe built-in) which can be used to create hardlinks,
> symbolic links and junctions on NTFS.
> 
> Stefan
> 
> PS I learned so many new things about NTFS during this, which alone has
> been worth the effort :-)
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
> 


-- 
http://blog.nigjo.de/netbeans
https://threema.id/3Y279Z3U

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org