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 ꚷ貢. 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.
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 ꚷ貢. 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.