My Mule应用程序处理几个不同的目录,它会移动文件。我有一些文件入站端点和文件连接器。我有情况需要轮询不同的文件夹,处理文件,移动它们,再次轮询等。
我在日志中看到了这个异常:
java.util.ConcurrentModificationException
at java.util.ArrayList.sort(ArrayList.java:1456)
at java.util.Collections.sort(Collections.java:175)
at org.mule.transport.file.FileMessageReceiver.poll(FileMessageReceiver.java:199)
at org.mule.transport.AbstractPollingMessageReceiver.performPoll(AbstractPollingMessageReceiver.java:216)
at org.mule.transport.PollingReceiverWorker.poll(PollingReceiverWorker.java:80)
at org.mule.transport.PollingReceiverWorker.run(PollingReceiverWorker.java:49)
at org.mule.transport.TrackingWorkManager$TrackeableWork.run(TrackingWorkManager.java:267)
at org.mule.work.WorkerContext.run(WorkerContext.java:286)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
我注意到在这种情况下http://grepcode.com/file/repo1.maven.org/maven2/org.mule.transports/mule-transport-file/3.5.0/org/mule/transport/file/FileMessageReceiver.java#675每次都返回相同的集合对象files.isEmpty() - 这不是理想的,很可能是导致问题的原因。
现在,幸运的是,这个异常并不具有破坏性,除非它可能会跳过轮询周期并污染日志。
之前有人见过/想法吗?
答案 0 :(得分:1)
如果在文件列表为空时更改listFiles()实现,看起来异常消失。
package org.mule.transport.file;
import org.mule.api.MuleException;
import org.mule.api.construct.FlowConstruct;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.api.lifecycle.CreateException;
import org.mule.api.transport.Connector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class PatchedFileMessageReceiver extends FileMessageReceiver
{
private static final Logger log = LoggerFactory.getLogger(PatchedFileMessageReceiver.class);
/**
*
* @param connector
* @param flowConstruct
* @param endpoint
* @param readDir
* @param moveDir
* @param moveToPattern
* @param frequency
* @throws CreateException
*/
public PatchedFileMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint, String readDir, String moveDir, String moveToPattern, long frequency) throws CreateException
{
super(connector, flowConstruct, endpoint, readDir, moveDir, moveToPattern, frequency);
}
/**
*
* @return
* @throws MuleException
*/
@Override
List<File> listFiles() throws MuleException
{
List<File> list = super.listFiles();
if(list.isEmpty()) {
log.trace("List of files is empty, I'm gonna return a new empty ArrayList");
}
return ( list.isEmpty() ? new ArrayList<File>() : list );
}
}
然后在文件连接器上设置自定义FileMessageReceiver,如下所示
<file:connector name="source-file-connector" autoDelete="false" fileAge="1000" pollingFrequency="1000" >
<service-overrides messageReceiver="org.mule.transport.file.PatchedFileMessageReceiver" />
</file:connector>
这个东西应该在上游真正固定。作为用户,人们期望不必处理这类问题。
答案 1 :(得分:1)
看起来像一个问题,应该确实修复。我为你创建了issue。密切注意它,以了解修复的进展。
答案 2 :(得分:1)
比每次调用listFiles()(并且没有文件)时返回新列表更好的解决方案是在http://grepcode.com/file/repo1.maven.org/maven2/org.mule.transports/mule-transport-file/3.5.0/org/mule/transport/file/FileMessageReceiver.java#64使用CopyOnWriteArrayList for NO_FILES
private static final List<File> NO_FILES = new CopyOnWriteArrayList<File>();
这样您就可以避免实例创建。