The symptoms are simple: Windows refuses to delete a directory because it thinks that its contents are still there -- although the recursive delete just deleted them. So my first guess is that there is a flush/sync or similar missing on the parent directory after deleting its contents and before deleting it.
I tried commons-io version 2.5 FileUtils.deleteDirectory and FileUtils.cleanDirectory functions as well as my own simplified test:
@Test
public void testMySimpleDelete() throws IOException, InterruptedException {
File dir = TEST_DIR;
for (int i = 0; i < 10; i++) {
dir = new File(dir, Integer.toString(i));
}
for (int i = 0; i < 1000; i++) {
LOG.info(""+i);
assertTrue("loop #" + i, dir.mkdirs());
mySimpleDelete(Paths.get(TEST_DIR.getAbsolutePath()));
assertFalse(TEST_DIR.exists());
}
}
private void mySimpleDelete(Path file) throws IOException, InterruptedException {
Files.walkFileTree(file, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
//LOG.info(dir.toString());
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
All show the same results/symptoms.
If you want to verify this behavior for yourself (on Windows only! Linux does not lock anything at all and behaves in a way more lenient way), simply check out https://github.com/jjYBdx4IL/java-evaluation and run "mvn test -Dtest=org.apache.commons.io.FileUtilsTest".