Is there a way for force polling using WatchService?
Asked Answered
S

2

16

I have working code that listens to a directory using the WatchService and responds to the events I specify. This works fine and has been tested on both linux and mac (although on the latter it's clear that polling is used).

However, when I deployed this in production it turns out the directory being monitored is an NFS mount. Since the WatchService uses inotify when running on linux there were never any events triggered because NFS mounts don't trigger inotify events (or something like this, there's more info here, which explains my problem: Java WatchService not generating events while watching mapped drives).

Since my code is already written I'd prefer to force the WatchService to use the polling implementation rather than the inotify one. Is there a way to do this?

I attempted this by finding the sun.nio.fs.PollingWatchService source code and creating an object directly (instead of using FileSystems.getDefault().newWatchService()) but when registering the service with the Path I got this exception: java.nio.file.ProviderMismatchException.

So, any ideas? Since I've already implemented the code using the WatchService and WatchKey API it'd be a lot easier to just force polling than rewrite everything using a custom or 3rd-party poller. Thanks!

Selfness answered 26/2, 2015 at 0:59 Comment(7)
This is kind of slow and inefficient but what about File f = new File(YOUR_DIRECTORY, "_garbage.tmp"); new FileOutputStream(f).close(); f.delete(); and just listen for the creation of files named "_garbage.tmp"?Fils
@k_g: Thanks for the response but I'm not understanding how that helps. Any chance you could elaborate?Selfness
If you create a file then delete it, it should fire a WatchService event, right?Fils
@k_g: Yes, but the point is the WatchService doesn't work on mapped drives. I'm just asking if we can force it to use its polling implementation instead of just getting whatever the platform supports (because this implementation doesn't work for all filesystems).Selfness
Did you manage to extend AbstractWatchService and create your own based on PollingWatchService?Contention
You could run a small WatchService-application on the remote server, then use RMI to register your local client with it as an observer.Klingensmith
@java-anto: Actually, I ended up rewriting everything using a polling library, i.e., I never figured out a way to force polling on the WatchService.Selfness
E
2

You can try the open source project jpoller. It implements a class named DirectoryPoller which periodically poll the contents of one or more directories. It is a periodic thread that looks for new files using the file last modification time. To download source you can visit http://jpoller.sourceforge.net/ Honestly, I did not used jpoller. I used JDK 7 WatcherService events.

Elodia answered 23/12, 2015 at 8:49 Comment(0)
E
0

We had a similar problem and decided to abandon using WatchService. There are a few libraries implementing pooling. I would recommend Apache Commons IO Monitor:

https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/monitor/package-summary.html

Explosive answered 25/12, 2015 at 8:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.