Description
In what version(s) of Spring Integration are you seeing this issue?
6.0.1.RELEASE
Describe the bug
The bug is related to the FileReadingMessageSource when using it for watching the directory with the (Java 7) WatchService feature enabled.
More specifically, the new files are not detected in the sub-directory of the watched folder after renaming it.
This issue has been discovered on Windows when using File Explorer to create a new directory ('New Folder' temporary name is used initially and user edits the name after that). In such a case 2 file events are generated.
To Reproduce
- Add the following logger in the logback-spring.xml to see the debug messages of the FileReadingMessageSource class
<logger name="org.springframework.integration.file" level="DEBUG" additivity="false">
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</logger>
- Use the following FileReadingMessageSource instance to watch the directory [C:\sandbox\test]:
FileReadingMessageSourceImproved messageSource = new FileReadingMessageSourceImproved();
messageSource.setDirectory(new File(inputDirectory));
messageSource.setUseWatchService(true);
messageSource.setWatchEvents(CREATE, MODIFY);
- [case A - New Folder] Create new sub-directory (PL) using Windows File Explorer in the watched folder and observe the logs:
Watch event [ENTRY_CREATE] for file [C:\sandbox\test\New folder]
registering: C:\sandbox\test\New folder for file events
Watch event [ENTRY_CREATE] for file [C:\sandbox\test\PL]
registering: C:\sandbox\test\PL for file events
- [case A - New Folder] Copy file (6017405.eml) into the new PL directory and observe the logs (The file is ignored !):
Watch event [ENTRY_CREATE] for file [C:\sandbox\test\New folder\6017405.eml]
A file [C:\sandbox\test\New folder\6017405.eml] for the event [ENTRY_CREATE] doesn't exist. Ignored.
- [case B - Renaming the folder] Now, create a new empty directory(de) in the watched folder and observe the logs:
Watch event [ENTRY_CREATE] for file [C:\sandbox\test\de]
registering: C:\sandbox\test\de for file events
- [case B - Renaming the folder] Rename the folder to ee and observe the logs:
Watch event [ENTRY_CREATE] for file [C:\sandbox\test\ee]
registering: C:\sandbox\test\ee for file events
- [case B - Renaming the folder] Copy file (6017408.eml) to the ee folder and observe the logs (The file is ignored):
Watch event [ENTRY_CREATE] for file [C:\sandbox\test\de\6017408.eml]
A file [C:\sandbox\test\de\6017408.eml] for the event [ENTRY_CREATE] doesn't exist. Ignored.
Expected behavior
The file is detected properly in the sub-directory after renaming this sub-directory in the watched folder.
Sample
//TBC
The fix that seems to solve the issue on Windows (not sure about other OS'es) - the only method changed in the FileReadingMessageSource is registerWatch:
private void registerWatch(Path dir) throws IOException {
if (!this.pathKeys.containsKey(dir)) {
logger.debug(() -> "registering: " + dir + " for file events");
WatchKey watchKey = dir.register(this.watcher, this.kinds);
if (this.pathKeys.containsValue(watchKey)) {
File previousDir = ((Path) watchKey.watchable()).toAbsolutePath().toFile();
logger.debug(() -> "unregistering: " + previousDir + " for file events");
watchKey.cancel();
watchKey = dir.register(this.watcher, this.kinds);
}
this.pathKeys.putIfAbsent(dir, watchKey);
}
}
Potentially the ExtendedWatchEventModifier.FILE_TREE modifier can be used for that but it seems it is only working for Windows.