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=.*$&amp;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)