I'm trying to create a watcher that looks for changes to a particular folder. I've created a watcher and put this within an Async method, but when I call it from a service the application pauses due to the while loop in the watcher method. It is like the method isn't being execute within a new thread.
Here is the class that contains the method I'm trying to execute;
@Service
public class FileWatcher {
@Async
public Future<Object> watch(Path path, DataParser parser) throws IOException, InterruptedException {
WatchService watchService = FileSystems.getDefault().newWatchService();
path.register(
watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
File file = new File(path.toString() + "/" + event.context());
if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
parser.fileChanged(file);
}
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
parser.fileCreated(file);
}
if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
parser.fileRemoved(file);
}
}
key.reset();
}
return null;
}
}
Then, I'm calling this within the constructor of a service.
@Service
public class SPIService {
private final String DATAFOLDER = "/spi";
private Path dataPath;
public SPIService(@Value("${com.zf.trw.visualisation.data.path}") String dataPath) {
this.dataPath = Paths.get(dataPath + DATAFOLDER);
FileWatcher fileWatcher = new FileWatcher();
try {
fileWatcher.watch(this.dataPath, new SPIParser());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Why isn't this working? Is it because I'm calling the method from the constructor of a service?