Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Any failure during the execution makes the monitoring to stop (obviously), and I don't know how to restart the monitoring after such events occur
like image 480
thmasker Avatar asked Oct 17 '25 15:10

thmasker


1 Answers

You should change the loop with and add a try/Catch, in the catch restarting the service. As you commented you need to keep in even if is interrupted , so you will need the use of ExecutorService. Declare the Executor out of the method

@Autowired
private ExecutorService executor;

and inside the method something similar to my last answer but using the executor

Runnable task = () -> {
        while (true) {
            try {
                WatchKey key = watchService.take();
                if (key != null) {
                    for (WatchEvent<?> event : key.pollEvents()) {
                        // Perform actions on created files here
                    }
                    key.reset();
                }
            } catch (Exception e) {
                // Wait for some time before starting the thread again
                Thread.sleep(5000);
            }
        }
    };
    //submit the task to the executor
    executor.submit(task);
like image 63
Jonxag Avatar answered Oct 20 '25 05:10

Jonxag



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!