I have thread which is watching folder set in settings file. If I change the settings I would like to stop the thread and start new thread with actual folder to watch. This code is running "fine" but getting some error message.
public static void resetWatch() throws FileNotFoundException, IOException, InterruptedException {
BufferedReader setup = new BufferedReader(new FileReader(new File("setup\\setup.dat")));
String DirtoWatch = setup.readLine();
Path toWatch = Paths.get(DirtoWatch);
if(toWatch == null) {
throw new UnsupportedOperationException("Directory not found");
}
// make a new watch service that we can register interest in
// directories and files with.
myWatcher = toWatch.getFileSystem().newWatchService();
// start the file watcher thread below
fileWatcher = new Watcher(myWatcher, toWatch);
th = new Thread(fileWatcher, "FileWatcher");
th.start();
System.out.println("Monitoring " + DirtoWatch + " for changes...");
// register a file
toWatch.register(myWatcher, ENTRY_CREATE);
th.join();
}
Watcher class
public class Watcher implements Runnable {
private WatchService myWatcher;
public Path path;
private WatchKey key;
public Watcher(WatchService myWatcher, Path path) {
this.myWatcher = myWatcher;
this.path = path;
}
@Override
public void run() {
String evCon;
try {
// get the first event before looping
key = myWatcher.take();
while(key != null) {
for (WatchEvent event : key.pollEvents()) {
evCon = event.context().toString();
System.out.println("New file: " + evCon);
Thread.sleep(500);
folder_changed(path.toString() + "/" + evCon);
}
key.reset();
key = myWatcher.take();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException ex) {
Logger.getLogger(Watcher.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Stopping thread");
}
public void stopThread() {
try {
System.out.println("Closing the ws");
myWatcher.close();
if(key!=null) {
key.cancel();
}
Thread.currentThread().interrupt();
} catch (IOException | ClosedWatchServiceException exc) { System.out.println("Closing thread exception"); }
}
}
And if I change the settings I update the setup file and then I try to close watcher and run thread again:
try{
fileWatcher.stopThread();
myWatcher.close();
}
catch(ClosedWatchServiceException | IOException ex) { System.out.println("Watch Service exc. "); }
try {
resetWatch();
} catch (IOException | InterruptedException ex) { System.out.println("Recall resetWatch exc. "); }
Then Its "running" but I get follow exception pointing to watch key:
Monitoring ..path.. for changes...
Closing the ws
Monitoring ..path.. for changes...
Exception in thread "FileWatcher" java.nio.file.ClosedWatchServiceException
Recall resetWatch exc.
at sun.nio.fs.AbstractWatchService.checkOpen(AbstractWatchService.java:80)
at sun.nio.fs.AbstractWatchService.checkKey(AbstractWatchService.java:92)
at sun.nio.fs.AbstractWatchService.take(AbstractWatchService.java:119)
at jstockcheck.Watcher.run(Watcher.java:40)
at java.lang.Thread.run(Thread.java:748)
Any suggestions how to avoid this errors? Thanks!
The
close
method may be invoked at any time to close the service causing any threads waiting to retrieve keys, to throwClosedWatchServiceException
.ClosedWatchServiceException
- if this watch service is closed, or it is closed while waiting for the next key.In your case, I think, it's just a matter of catching exception when
take
is called and handling it silently, for example:This is according to: https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html