javaspring-bootwatchservice

Restart WatchService after exceptions


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:


Solution

  • 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();
            }
        }
    
    }