[ 
https://issues.apache.org/jira/browse/IO-692?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Emmanuel Bourg resolved IO-692.
-------------------------------
    Resolution: Fixed

Thank you for the report, the suggested fix has been applied.

> PathUtils delete throws an exception when deleting a symlink that points to a 
> file that does not exist
> ------------------------------------------------------------------------------------------------------
>
>                 Key: IO-692
>                 URL: https://issues.apache.org/jira/browse/IO-692
>             Project: Commons IO
>          Issue Type: Bug
>    Affects Versions: 2.8.0
>         Environment: {noformat}
> java version "1.8.0_202" Java(TM) SE Runtime Environment (build 
> 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed 
> mode)
> {noformat}
>            Reporter: Matthew Rooney
>            Priority: Major
>             Fix For: 2.9.0
>
>
> *PathUtils.delete* throws an Exception when deleting a symlink to a file that 
> doesn't exist, in our case this was when the files were deleted out of 
> sequence.
> Minimal reproducing code running as a unit test (scala). This creates a 
> symlink to a fail that does not exist at all.
> {code:java}
> val file = Files.createSymbolicLink(
>   Paths.get("target", "x.txt"),
>   Paths.get("target",  "y.txt").toAbsolutePath,
> )
> PathUtils.delete(file)
> {code}
> This throws the following exception
> {noformat}
> [error]    java.nio.file.NoSuchFileException: target/x.txt 
> (UnixException.java:86)
> [error] sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
> [error] sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
> [error] sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
> [error] 
> sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
> [error] 
> sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:144)
> [error] org.apache.commons.io.file.PathUtils.deleteFile(PathUtils.java:361)
> [error] org.apache.commons.io.file.PathUtils.delete(PathUtils.java:304)
> [error] 
> org.apache.commons.io.file.PathUtils.delete(PathUtils.java:280){noformat}
> The offending code is this in *PathUtils*
> {code:java}
> public static PathCounters deleteFile(final Path file, final DeleteOption... 
> options) throws IOException {
>     // Files.deleteIfExists() never follows links, so use 
> LinkOption.NOFOLLOW_LINKS in other calls to Files.
>     if (Files.isDirectory(file, LinkOption.NOFOLLOW_LINKS)) {
>         throw new NoSuchFileException(file.toString());
>     }
>     final PathCounters pathCounts = Counters.longPathCounters();
>     final boolean exists = Files.exists(file, LinkOption.NOFOLLOW_LINKS);
>     final long size = exists ? Files.size(file) : 0;
>     if (overrideReadOnly(options) && exists) {
>         setReadOnly(file, false, LinkOption.NOFOLLOW_LINKS);
>     }
>     if (Files.deleteIfExists(file)) {
>         pathCounts.getFileCounter().increment();
>         pathCounts.getByteCounter().add(size);
>     }
>     return pathCounts;
> }
> {code}
> This manifests because 
> {code:java}
> Files.exists(file, LinkOption.NOFOLLOW_LINKS); // this always returns true if 
> the symlink exists
> Files.size(file) // this throws an exception because there is no file to 
> check the size of{code}
> A guess at the solution would be to only check the size if the file exists 
> and is not a symlink
> {code:java}
> final long size = exists && !Files.isSymbolicLink() ? Files.size(file) : 
> 0;{code}
> This was discovered when using *FileUtils.deleteDirectory* where we have a 
> structure like the following. We clean up these directories when the process 
> finishes, since upgrading to 2.8.0 this fails if the parent directory is 
> deleted before the child.
> {code:java}
>  work_dir/
>    parent_dir/
>      big_file.txt
>    child_dir/
>      symlink_to_big_file.txt{code}
> As a work around using *PathUtils.deleteDirectory* seems to work regardless 
> of the deletion order
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to