I'm using Java's WatchService
API within my Spring Boot application to monitor a directory, and perform some actions on created files. This process is executed asynchronously: it starts automatically right after the application is ready and monitors the directory in the background until the application is stopped.
This is the configuration class:
@Configuration
public class DirectoryWatcherConfig {
@Value("${path}")
private String path;
@Bean
public WatchService watchService() throws IOException {
WatchService watchService = FileSystems.getDefault().newWatchService();
Path directoryPath = Paths.get(path);
directoryPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
return watchService;
}
}
And this is the monitoring service:
@Service
@RequiredArgsConstructor
public class DirectoryWatcherService {
private final WatchService watchService;
@Async
@EventListener(ApplicationReadyEvent.class)
public void startWatching() throws InterruptedException {
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
// actions on created files
}
key.reset();
}
}
}
This code is working as expected, with the following exception, which I'd like to fix:
Actually the solution was quite simple. Wrapping the desired actions with try/catch (catching desired exceptions) in DirectoryWatcherService
like this allows the thread to continue monitoring directories:
@Service
@RequiredArgsConstructor
public class DirectoryWatcherService {
private final WatchService watchService;
@Async
@EventListener(ApplicationReadyEvent.class)
public void startWatching() throws InterruptedException {
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
try {
// actions on created files
} catch (RuntimeException ex) {
// log exception or whatever you choose, as long as execution continues
}
}
key.reset();
}
}
}