You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Emmanuel Bourg (Jira)" <ji...@apache.org> on 2020/12/06 23:27:00 UTC
[jira] [Resolved] (IO-692) PathUtils delete throws an exception
when deleting a symlink that points to a file that does not exist
[ 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)