You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Joe Qiang Luo (JIRA)" <ji...@apache.org> on 2014/11/11 11:25:35 UTC
[jira] [Updated] (CAMEL-8032) FileUtil leaks FileInputStream when
renameFile fails due to permission issue
[ https://issues.apache.org/jira/browse/CAMEL-8032?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Joe Qiang Luo updated CAMEL-8032:
---------------------------------
Attachment: patch.txt
> FileUtil leaks FileInputStream when renameFile fails due to permission issue
> ----------------------------------------------------------------------------
>
> Key: CAMEL-8032
> URL: https://issues.apache.org/jira/browse/CAMEL-8032
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Affects Versions: 2.12.3
> Reporter: Joe Qiang Luo
> Attachments: patch.txt
>
>
> I have a simple camel route:
> {code}
> <camelContext xmlns="http://camel.apache.org/schema/spring">
> <route>
> <from uri="file:C:/tmp/data/in?include=.*$&move=C:/tmp/data/done/${file:onlyname}-${exchangeId}" />
> <setHeader headerName="CamelFileName">
> <simple>${file:onlyname}-${exchangeId}</simple>
> </setHeader>
> <to uri="file:C:/tmp/data/out" />
> </route>
> </camelContext>
> {code}
> If the destination folder "C:/tmp/data/done/" for the move operation does not allow writing, then the file dropped to the "C:/tmp/data/in/" folder will be repeatedly polled, processed and rolled back due to "Access is denied" exception.
> Even if we fix the permission issue on the folder "C:/tmp/data/done/" to allow writing, the problem still persists and above endless cycle continues. However the reason for the issue will be a bit different now. It is caused by deletion failure to the file from "C:/tmp/data/in/" folder after successful FileUtil.renameFile() operation due to fact that something is still holding the file handle.
> The root cause is in the function FileUtil.copyFile():
> {code}
> public static void copyFile(File from, File to) throws IOException {
> FileChannel in = new FileInputStream(from).getChannel();
> FileChannel out = new FileOutputStream(to).getChannel();
> try {
> if (LOG.isTraceEnabled()) {
> LOG.trace("Using FileChannel to copy from: " + in + " to: " + out);
> }
> long size = in.size();
> long position = 0;
> while (position < size) {
> position += in.transferTo(position, BUFFER_SIZE, out);
> }
> } finally {
> IOHelper.close(in, from.getName(), LOG);
> IOHelper.close(out, to.getName(), LOG);
> }
> }
> {code}
> If the destination folder "C:/tmp/data/done/" for move operation is not allowed for writing, the creation of the FileOutputStream will throw an exception straight away. However, because both FileInputStream and FileOutputStream are created outside the try{}...finally{} block, the FileInputStream is never closed. It still holds handle to the file and caused FileSystem unable to delete it. Therefore caused the whole route to fail.
> The solution is quite simple, we just need to create the Input/Output streams inside try{}...finally{} loop to make sure that the Input/Output streams get closed if something happens during creating of these objects.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)