Search code examples
javawatchservice

How to terminate a WatchService on application shutdown?


I have a WatchService that throws a ClosedWatchServiceException for the following code:

final WatchService watchService = FileSystems.getDefault().newWatchService();   

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        try {
            watchService.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});

WatchKey key = null;
while (true) {
    key = watchService.take(); //throws ClosedWatchServiceException
    //execution
}

How can I shutdown the service safely without getting the exception? Or should I neglect the shutdown as any threads are anyhow killed when terminating the application?


Solution

  • First note there is nothing really wrong with your code. You just need to handle the ClosedWatchServiceException gracefully during shutdown. This is because the thread that is executing watchService.take() is blocked in that operation during the jvm shutdown execution. So the blocked thread will be unblocked as soon as the watch service is closed.

    You may prevent this by interrupting the thread that is running watchService.take() prior to calling watchService.close(). This should give you an InterruptedException that you can handle. But the contract of take is not saying anything explicit about the order of events that are taken into account when throwing an exception. So you could still end up with the ClosedWatchServiceException.

    So you could have a volatile flag to indicate application shutdown. Upon catching the ClosedWatchServiceException you can evaluate the flag and then exit gracefully if the flag is set.