Reputation: 3255
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?
Upvotes: 1
Views: 2933
Reputation: 73558
You're using new FileWatcher()
which means the instance isn't a managed bean. This also means that @Async
is ignored (which explains your application halting). You need to @Autowire
FileWatcher
instead.
Note also that your solution seems very suspicious to me, not only for having an infinite loop, but having one in an @Async
method (this has some important consequences). I would at least use a single threaded threadpool for it.
Upvotes: 3