You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Michael Ludwig <mi...@gmx.de> on 2009/04/19 12:00:28 UTC

Delete task eagerness on Windows

Ant (version 1.7.1), or more precisely: Ant's Delete task merrily
deletes write-protected files and directories on Windows XP that cannot
be deleted using the DEL (without /f) and RD commands from the cmd.exe
console.

In cmd.exe, type:

more > ant-delete.xml
<project name="DeleteTest" basedir="C:/temp/DeleteTest"
default="create">
        <property name="test.dir" location="abc"/>
        <property name="test.file" location="abc.txt"/>
        <target name="create">
                <echo message="Moin" file="${test.file}"/>
                <mkdir dir="${test.dir}"/>
        </target>
        <target name="clean">
                <delete file="${test.file}"/>
                <delete dir="${test.dir}"/>
        </target>
</project>
^Z (hit <F6>)

rem Create project folder
md C:\temp\DeleteTest

rem Create file and folder
ant -f ant-delete.xml

rem Set write-protection
attrib +R C:\temp\DeleteTest
attrib +R C:\temp\DeleteTest\abc
attrib +R C:\temp\DeleteTest\abc.txt

rem Try to delete using RD and DEL, which fails
rd C:\temp\DeleteTest\abc
del C:\temp\DeleteTest\abc.txt

rem But Ant unscrupulously cleans up ...
ant -f ant-delete.xml clean

Now abc and abc.txt are gone, despite being write-protected. I find it
difficult to consider this a feature. Is this behaviour intentional?

Note that as a consequence, <delete dir="${some.dir}"/> on Windows means
to recursively and unconditionally remove ${some.dir}, which even on
UNIX would require the user to spell out `rm -rf'.

Note that on UNIX, a `chmod a-w' on the project folder prevents Ant
from deleting file and folder.

Michael

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


Re: Delete task eagerness on Windows

Posted by Michael Ludwig <mi...@gmx.de>.
Jan.Materne@rzf.fin-nrw.de schrieb am 20.04.2009 um 06:49:04 (+0200):
> > Ant (version 1.7.1), or more precisely: Ant's Delete task merrily
> > deletes write-protected files and directories on Windows XP that
> > cannot be deleted using the DEL (without /f) and RD commands from
> > the cmd.exe console.

> > Now abc and abc.txt are gone, despite being write-protected. I find
> > it difficult to consider this a feature. Is this behaviour
> > intentional?
> > 
> > Note that as a consequence, <delete dir="${some.dir}"/> on Windows
> > means to recursively and unconditionally remove ${some.dir}, which
> > even on UNIX would require the user to spell out `rm -rf'.
> > 
> > Note that on UNIX, a `chmod a-w' on the project folder prevents Ant
> > from deleting file and folder.

> So basically the task tries one or two time the deletion via the JVM.
> According to that I would think that the ignorance of the read-only
> attribute is inside the JVM.
> 
> Could you try deleting the file via another Java application eg
> NetBeans/Eclipse? (Running on the same VM)

Moin Jan,

this may be a JVM issue, indeed; but Ant aggravates it considerably by
applying recursion.

The doc for "public boolean java.io.File#delete()" says:

| Deletes the file or directory denoted by this abstract pathname.
| If this pathname denotes a directory, then the directory must be
| empty in order to be deleted.

Write-protection is not mentioned here, and indeed disregarded.
I think this can be considered a horrible bug.

The JVM has no problems setting write-protection.

import java.io.File;
import java.io.IOException;

public class SetReadOnly {
  public static void main( String[] args) throws IOException {
    if ( args.length < 1 ) {
      System.err.println( "Argumente!");
      System.exit(1);
    }
    for ( String arg : args ) {
      File f = new File( arg);
      if ( ! f.createNewFile() ) {
        System.err.format( "Kann %s nicht anlegen!%n", f);
        continue;
      }
      if ( ! f.setReadOnly() ) {
        System.err.format( "Kann %s nicht schreibschuetzen!%n", f);
      }
    }
  }
}

java SetReadOnly a b c
attrib /s

But then it gets quite hilarious, and could get quite tragical.

import java.io.File;
import java.io.IOException;

public class ReadOnlyOrMaybeNot {
  public static void main( String[] args) throws IOException {
    if ( args.length < 1 ) {
      System.err.println( "Argumente!");
      System.exit(1);
    }
    for ( String arg : args ) {
      File f = new File( arg);
      System.err.format( "%s - canWrite() ? %s%n", f, f.canWrite());
      System.err.format( "%s - delete() ? %s%n", f, f.delete());
      System.err.format( "%s - exists() ? %s%n", f, f.exists());
    }
  }
}

java ReadOnlyOrMaybeNot a b c
a - canWrite() ? false
a - delete() ? true
a - exists() ? false
b - canWrite() ? false
b - delete() ? true
b - exists() ? false
c - canWrite() ? false
c - delete() ? true
c - exists() ? false

So, yes, the files are write-protected, but no, it doesn't matter.

Tested with Sun jdk1.6.0_11, jdk1.6.0_07 and jre1.5.0_09.

I made a slight modification to my Ant script to create a file inside
the folder to see if that prevents Ant from erasing it.

more > ant-delete-2.build
<project name="DeleteTest" basedir="C:/temp/DeleteTest"
default="create">
  <property name="test.dir" location="abc"/>
  <property name="test.file" location="abc.txt"/>
  <target name="create">
    <echo message="Moin" file="${test.file}"/>
    <mkdir dir="${test.dir}"/>
    <!-- Put a file in so File#delete() on the folder will fail. -->
    <echo message="Moin" file="${test.dir}/moin.txt"/>
  </target>
  <target name="clean">
    <delete file="${test.file}"/>
    <delete dir="${test.dir}"/>
  </target>
</project>

Then a shell for cmd.exe to test the behaviour.

more > readonly.cmd
@echo off
setlocal
set ANT_OPTS=-showversion
set ANT_ARGS=-v
call ant -v -f ant-delete-2.xml
set test_dir=C:\temp\DeleteTest
pushd %test_dir%
attrib /s /d +R
attrib /s /d
popd
call ant -v -f ant-delete-2.xml clean
echo on
dir /s /b %test_dir%
@echo off
echo Alles futsch ...
endlocal

So what Ant does seems to be a recursive and unconditional application
of what I think is a horrible JVM/Windows bug.

Which I hope Larry Ellison is going to fix now!

Michael Ludwig

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


AW: Delete task eagerness on Windows

Posted by Ja...@rzf.fin-nrw.de.
> Ant (version 1.7.1), or more precisely: Ant's Delete task merrily
> deletes write-protected files and directories on Windows XP 
> that cannot
> be deleted using the DEL (without /f) and RD commands from the cmd.exe
> console.
> 
> In cmd.exe, type:
> 
> more > ant-delete.xml
> <project name="DeleteTest" basedir="C:/temp/DeleteTest"
> default="create">
>         <property name="test.dir" location="abc"/>
>         <property name="test.file" location="abc.txt"/>
>         <target name="create">
>                 <echo message="Moin" file="${test.file}"/>
>                 <mkdir dir="${test.dir}"/>
>         </target>
>         <target name="clean">
>                 <delete file="${test.file}"/>
>                 <delete dir="${test.dir}"/>
>         </target>
> </project>
> ^Z (hit <F6>)
> 
> rem Create project folder
> md C:\temp\DeleteTest
> 
> rem Create file and folder
> ant -f ant-delete.xml
> 
> rem Set write-protection
> attrib +R C:\temp\DeleteTest
> attrib +R C:\temp\DeleteTest\abc
> attrib +R C:\temp\DeleteTest\abc.txt
> 
> rem Try to delete using RD and DEL, which fails
> rd C:\temp\DeleteTest\abc
> del C:\temp\DeleteTest\abc.txt
> 
> rem But Ant unscrupulously cleans up ...
> ant -f ant-delete.xml clean
> 
> Now abc and abc.txt are gone, despite being write-protected. I find it
> difficult to consider this a feature. Is this behaviour intentional?
> 
> Note that as a consequence, <delete dir="${some.dir}"/> on 
> Windows means
> to recursively and unconditionally remove ${some.dir}, which even on
> UNIX would require the user to spell out `rm -rf'.
> 
> Note that on UNIX, a `chmod a-w' on the project folder prevents Ant
> from deleting file and folder.


Searching ...

The main parts are in <taskdef> (Delete.java)
http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools
/ant/taskdefs/Delete.java
    private boolean delete(File f) {
        if (!FILE_UTILS.tryHardToDelete(f)) {
            if (deleteOnExit) {
                int level = quiet ? Project.MSG_VERBOSE :
Project.MSG_INFO;
                log("Failed to delete " + f + ", calling deleteOnExit."
                    + " This attempts to delete the file when the Ant
jvm"
                    + " has exited and might not succeed.", level);
                f.deleteOnExit();
                return true;
            }
            return false;
        }
        return true;
    }

http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools
/ant/util/FileUtils.java
    /**
     * Accommodate Windows bug encountered in both Sun and IBM JDKs.
     * Others possible. If the delete does not work, call System.gc(),
     * wait a little and try again.
     *
     * @return whether deletion was successful
     * @since Ant 1.8.0
     */
    public boolean tryHardToDelete(File f) {
        if (!f.delete()) {
            if (ON_WINDOWS) {
                System.gc();
            }
            try {
                Thread.sleep(DELETE_RETRY_SLEEP_MILLIS);
            } catch (InterruptedException ex) {
                // Ignore Exception
            }
            return f.delete();
        }
        return true;
    }


So basically the task tries one or two time the deletion via the JVM.
According to that I would think that the ignorance of the read-only
attribute is inside the JVM.

Could you try deleting the file via another Java application eg
NetBeans/Eclipse? (Running on the same
VM)


Jan

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