[
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)