private void startWatcher() throws IOException {
        try {
            watchService = FileSystems.getDefault().newWatchService();
        } catch (IOException e) {
            throw new RuntimeException(LogUtil.message("Error creating watch new service, {}", e.getMessage()), e);
        }

        dirToWatch.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);

        // run the watcher in its own thread else it will block app startup
        // TODO @AT Change to use CompleteableFuture.runAsync()
        watcherFuture = executorService.submit(() -> {
            WatchKey watchKey = null;

            LOGGER.info("Starting file modification watcher for {}",
                    monitoredFile.toAbsolutePath().normalize());
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    LOGGER.debug("Thread interrupted, stopping watching directory {}",
                            dirToWatch.toAbsolutePath().normalize());
                    break;
                }

                try {
                    isRunning.compareAndSet(false, true);
                    // block until the watch service spots a change
                    watchKey = watchService.take();
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    // continue to re-use the if block above
                    continue;
                }

                for (WatchEvent<?> event : watchKey.pollEvents()) {
                    if (LOGGER.isDebugEnabled()) {
                        if (event == null) {
                            LOGGER.debug("Event is null");
                        } else {
                            final String name = event.kind() != null
                                    ? event.kind().name()
                                    : "kind==null";
                            final String type = event.kind() != null
                                    ? event.kind().type().getSimpleName()
                                    : "kind==null";
                            LOGGER.debug("Dir watch event {}, {}, {}", name, type, event.context());
                        }
                    }

                    if (event.kind().equals(OVERFLOW)) {
                        LOGGER.warn("{} event detected breaking out. Retry file change", OVERFLOW.name());
                        break;
                    }
                    if (event.kind() != null && Path.class.isAssignableFrom(event.kind().type())) {
                        handleWatchEvent((WatchEvent<Path>) event);
                    } else {
                        LOGGER.debug("Not an event we care about");
                    }
                }
                boolean isValid = watchKey.reset();
                if (!isValid) {
                    LOGGER.warn("Watch key is no longer valid, the watch service may have been stopped");
                    break;
                }
            }
        });
    }
Starts the object. Called <i>before</i> the application becomes available.
stroom-util/src/main/java/stroom/util/config/AbstractFileChangeMonitor.java