Apache camel 骆驼:将文件从:xxx重命名为:xxx失败,因为复制成功后无法从文件:xxx中删除

Apache camel 骆驼:将文件从:xxx重命名为:xxx失败,因为复制成功后无法从文件:xxx中删除,apache-camel,smooks,resource-leak,Apache Camel,Smooks,Resource Leak,系统背景:Windows/ServiceMix/Camel/Smooks 我有一条骆驼路线 <camel:camelContext id="customsContext" xmlns="http://camel.apache.org/schema/spring"> <camel:route> <camel:from uri="file://C:\Camel\?delay=2000"/> <camel:convert

系统背景:Windows/ServiceMix/Camel/Smooks

我有一条骆驼路线

<camel:camelContext id="customsContext" xmlns="http://camel.apache.org/schema/spring">
    <camel:route>
        <camel:from uri="file://C:\Camel\?delay=2000"/>
        <camel:convertBodyTo type="javax.xml.transform.stream.StreamSource"/>
        <camel:to uri="smooks:smooks-config.xml"/>
    </camel:route>
</camel:camelContext>

因此,是的,该文件仍处于打开状态,阻止删除。但这就是它变得有点有趣的地方。如果您列出打开的文件,您会看到它实际上已打开多次,并且每2秒会收到另一个文件,这就是轮询延迟

#1 C:\Camel\edi-input.txt by thread:Camel (customsContext) thread #0 - file://C:%5CCamel%5C on Thu Jun 05 10:08:13 EDT 2014
    at java.io.FileInputStream.<init>(FileInputStream.java:147)
    at java.io.FileInputStream.<init>(FileInputStream.java:101)
    at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
    at java.net.URL.openStream(URL.java:1037)
    at org.milyn.delivery.AbstractParser.systemIdToStream(AbstractParser.java:192)
    at org.milyn.delivery.AbstractParser.getInputStream(AbstractParser.java:253)
    at org.milyn.delivery.AbstractParser.createInputSource(AbstractParser.java:227)
    at org.milyn.delivery.sax.SAXParser.parse(SAXParser.java:76)
    at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:86)
    at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:64)
    at org.milyn.Smooks._filter(Smooks.java:526)
    at org.milyn.Smooks.filterSource(Smooks.java:477)
    at org.milyn.smooks.camel.processor.SmooksProcessor.process(SmooksProcessor.java:112)
    at org.apache.camel.impl.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:103)
    at org.apache.camel.impl.ProcessorEndpoint$1.process(ProcessorEndpoint.java:71)
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:110)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:401)
    at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:201)
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:165)
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:187)
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:114)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
所以,我在这里有点不知所措。这是否意味着Camel正试图在Smooks完成之前在另一个线程上提交事务?

这是Smooks

在某些情况下,Smooks自己在
org.milyn.delivery.AbstractParser
类中打开流,但从不关闭它。因此,开放流将一直挂起,直到收集到已失效的对象。对于Windows,打开文件锁由操作系统强制执行,Camel无法重命名或删除文件。如果在其他操作系统或Java版本中不遵守锁,则可能不会出现这种情况


我已打开并正在进行修复。

看起来您的camelcontext未正确关闭,这就是文件锁定被保留的原因。您可能需要对锁进行一些等待。

关闭finally块中的inputstream(读取后文件未正确关闭)。这导致无法重命名现有文件的问题

if (inputStream != null) {inputStream.close();}

骆驼文件锁被释放。这是斯摩克斯永远不会关闭的小溪。
try {
    Writer writer = parser.parse(source, result, executionContext);
    writer.flush();
} catch (TerminateException e) {
    if(logger.isDebugEnabled()) {
        if(e.isTerminateBefore()) {
            logger.debug("Terminated filtering on visitBefore of element '" + SAXUtil.getXPath(e.getElement()) + "'.");
        } else {
            logger.debug("Terminated filtering on visitAfter of element '" + SAXUtil.getXPath(e.getElement()) + "'.");                  
        }
    }
} catch (Exception e) {
    throw new SmooksException("Failed to filter source.", e);
} finally {
    if(closeSource) {
        close(source);
    }
    if(closeResult) {
        close(result);
    }
}
if (inputStream != null) {inputStream.close();}