You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by "David R. Hoffman" <dh...@capario.com> on 2014/06/17 20:29:43 UTC

Bug in org.apache.camel.util.FileUtil.renameFile(...) introduced in 2.13.0.

For some time the method renameFile() in the class
org.apache.camel.util.FileUtil has supported the flag
copyAndDeleteOnRenameFail.  When this flag is set and the
java.io.File.renameTo() method fails, the FileUtil.renameFile() attempts to
rename the file using copy and delete.  Up to version 2.12.3 the code for
this was contained in this block of code where renamed was returned by the
FileUtil.renameFile() method:

        // we could not rename using renameTo, so lets fallback and do a
copy/delete approach.
        // for example if you move files between different file systems
(linux -> windows etc.)
        if (!renamed && copyAndDeleteOnRenameFail) {
            // now do a copy and delete as all rename attempts failed
            LOG.debug("Cannot rename file from: {} to: {}, will now use a
copy/delete approach instead", from, to);
            copyFile(from, to);
            if (!deleteFile(from)) {
                throw new IOException("Renaming file from: " + from + " to:
" + to + " failed due cannot delete from file: " + from + " after copy
succeeded");
            } else {
                renamed = true;
            }
        }

Starting in version 2.13.0 and continuing into version 2.13.1 the code for
this logic now looks like this:

        // we could not rename using renameTo, so lets fallback and do a
copy/delete approach.
        // for example if you move files between different file systems
(linux -> windows etc.)
        if (!renamed && copyAndDeleteOnRenameFail) {
            // now do a copy and delete as all rename attempts failed
            LOG.debug("Cannot rename file from: {} to: {}, will now use a
copy/delete approach instead", from, to);
            renameFileUsingCopy(from, to);
        }

Note that the calls to the methods copyFile() and deleteFile() have been
replaced by a single call to the method renameFileUsingCopy(), but that the
boolean return value of that method is not assigned to the renamed flag
which is still returned from the renameFile() method.

To correct this the line calling the renameFileUsingCopy() method should be
changed to:

            renamed = renameFileUsingCopy(from, to);

The problem this causes for us is that we have a route that picks up files
and uses &preMove.  This means that the
GenericFileProcessStrategySupport.renameFile() method gets called and the
following block of code is executed:

        log.debug("Renaming file: {} to: {}", from, to);
        boolean renamed = operations.renameFile(from.getAbsoluteFilePath(),
to.getAbsoluteFilePath());
        if (!renamed) {
            throw new GenericFileOperationFailedException("Cannot rename
file: " + from + " to: " + to);
        }

This in turn calls the FileOperations.renameFile() method which has the
following code:

            if (endpoint.isRenameUsingCopy()) {
                renamed = FileUtil.renameFileUsingCopy(file, target);
            } else {
                renamed = FileUtil.renameFile(file, target,
endpoint.isCopyAndDeleteOnRenameFail());
            }

In our case the endpoint.isRenameUsingCopy() flag returns false, so the
FileUtil.renameFile() method is called with the
endpoint.isCopyAndDeleteOnRenameFail() value true.  The renamed return value
is passed back up to the GenericFileProcessStrategySupport.renameFile()
method, and a GenericFileOperationFailedException gets thrown, stopping the
processing of the file.

In the meantime, the file is actually copied to the target location and
deleted from the original location.



--
View this message in context: http://camel.465427.n5.nabble.com/Bug-in-org-apache-camel-util-FileUtil-renameFile-introduced-in-2-13-0-tp5752450.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Bug in org.apache.camel.util.FileUtil.renameFile(...) introduced in 2.13.0.

Posted by "David R. Hoffman" <dh...@capario.com>.
Thanks for the speedy response.  In the meantime I should be able to work
around this by setting renameUsingCopy=true in my route.  Correct me if I am
wrong.



--
View this message in context: http://camel.465427.n5.nabble.com/Bug-in-org-apache-camel-util-FileUtil-renameFile-introduced-in-2-13-0-tp5752450p5752455.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Bug in org.apache.camel.util.FileUtil.renameFile(...) introduced in 2.13.0.

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Thanks for the detailed report. I have logged a ticket and commited a fix
https://issues.apache.org/jira/browse/CAMEL-7518

On Tue, Jun 17, 2014 at 8:29 PM, David R. Hoffman <dh...@capario.com> wrote:
> For some time the method renameFile() in the class
> org.apache.camel.util.FileUtil has supported the flag
> copyAndDeleteOnRenameFail.  When this flag is set and the
> java.io.File.renameTo() method fails, the FileUtil.renameFile() attempts to
> rename the file using copy and delete.  Up to version 2.12.3 the code for
> this was contained in this block of code where renamed was returned by the
> FileUtil.renameFile() method:
>
>         // we could not rename using renameTo, so lets fallback and do a
> copy/delete approach.
>         // for example if you move files between different file systems
> (linux -> windows etc.)
>         if (!renamed && copyAndDeleteOnRenameFail) {
>             // now do a copy and delete as all rename attempts failed
>             LOG.debug("Cannot rename file from: {} to: {}, will now use a
> copy/delete approach instead", from, to);
>             copyFile(from, to);
>             if (!deleteFile(from)) {
>                 throw new IOException("Renaming file from: " + from + " to:
> " + to + " failed due cannot delete from file: " + from + " after copy
> succeeded");
>             } else {
>                 renamed = true;
>             }
>         }
>
> Starting in version 2.13.0 and continuing into version 2.13.1 the code for
> this logic now looks like this:
>
>         // we could not rename using renameTo, so lets fallback and do a
> copy/delete approach.
>         // for example if you move files between different file systems
> (linux -> windows etc.)
>         if (!renamed && copyAndDeleteOnRenameFail) {
>             // now do a copy and delete as all rename attempts failed
>             LOG.debug("Cannot rename file from: {} to: {}, will now use a
> copy/delete approach instead", from, to);
>             renameFileUsingCopy(from, to);
>         }
>
> Note that the calls to the methods copyFile() and deleteFile() have been
> replaced by a single call to the method renameFileUsingCopy(), but that the
> boolean return value of that method is not assigned to the renamed flag
> which is still returned from the renameFile() method.
>
> To correct this the line calling the renameFileUsingCopy() method should be
> changed to:
>
>             renamed = renameFileUsingCopy(from, to);
>
> The problem this causes for us is that we have a route that picks up files
> and uses &preMove.  This means that the
> GenericFileProcessStrategySupport.renameFile() method gets called and the
> following block of code is executed:
>
>         log.debug("Renaming file: {} to: {}", from, to);
>         boolean renamed = operations.renameFile(from.getAbsoluteFilePath(),
> to.getAbsoluteFilePath());
>         if (!renamed) {
>             throw new GenericFileOperationFailedException("Cannot rename
> file: " + from + " to: " + to);
>         }
>
> This in turn calls the FileOperations.renameFile() method which has the
> following code:
>
>             if (endpoint.isRenameUsingCopy()) {
>                 renamed = FileUtil.renameFileUsingCopy(file, target);
>             } else {
>                 renamed = FileUtil.renameFile(file, target,
> endpoint.isCopyAndDeleteOnRenameFail());
>             }
>
> In our case the endpoint.isRenameUsingCopy() flag returns false, so the
> FileUtil.renameFile() method is called with the
> endpoint.isCopyAndDeleteOnRenameFail() value true.  The renamed return value
> is passed back up to the GenericFileProcessStrategySupport.renameFile()
> method, and a GenericFileOperationFailedException gets thrown, stopping the
> processing of the file.
>
> In the meantime, the file is actually copied to the target location and
> deleted from the original location.
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Bug-in-org-apache-camel-util-FileUtil-renameFile-introduced-in-2-13-0-tp5752450.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/