Tony Edwards Tony Edwards - 29 days ago 10x
Java Question

AcceptOnceFileFilter keeps other filters from working in a CompositeFileListFilter

I have beat my head against the wall for quite some time on this issue and tested it multiple ways plus dug into the source code and cannot find out why it is not working.

I have the need for a composite filter so that I can filter and provide other industry standard polling checks. The code below is the core part of the issue and it is in an Inbound Channel Adapter.

The code works fine if addFilter(new AcceptOnceFileListFilter()) is not in the code. As soon as you put it in, no files are ever found. It will work if I take the RegexPatternFileListFilter out of the scenario.

CompositeFileListFilter<File> compositeFileListFilter= new CompositeFileListFilter<File>();
compositeFileListFilter.addFilter(new RegexPatternFileListFilter(".*_CLAIM_.*[.]txt"));
compositeFileListFilter.addFilter(new AcceptOnceFileListFilter<File>());

FileReadingMessageSource pollDirectory = new FileReadingMessageSource();
pollDirectory.setDirectory(new File(pollingDirectory));
pollDirectory.setLocker(new NioFileLocker());

Update 09/21/2016:
An example Spring Boot application showing this issue has been uploaded to:


Well, looks like I know where is problem.

Look into your code one more time:

CompositeFileListFilter<File> compositeFileListFilter= new CompositeFileListFilter<File>();
compositeFileListFilter.addFilter(new RegexPatternFileListFilter("(?i).*_CLAIM_.*[.]txt"));
compositeFileListFilter.addFilter(new AcceptOnceFileListFilter<File>());
compositeFileListFilter.addFilter(new IgnoreHiddenFileListFilter());

See, you are in trap because of wrong order of filters.

When you have AcceptOnceFileListFilter there in the middle, it accepts the file first time and stores it in the its cache to avoid this one for the next time.

Now we go to other filters in the chain and meet here LastModifiedFileListFilter with the age == 15 seconds. Now its JavaDocs:

* The {@link FileListFilter} implementation to filter those files which
* {@link File#lastModified()} is less than the {@link #age} in comparison
* with the current time.
* <p>
* The resolution is done in seconds.

So, if file is young enough, we skip it. Eventually that file becomes old, but (!!!). Do you remember that we have AcceptOnceFileListFilter before? So, even if that file is ready for processing by the LastModifiedFileListFilter, we don't pass because it is filtered already by the AcceptOnceFileListFilter.

So, the fix for your problem is to move AcceptOnceFileListFilter to the end of the chain.