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!
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.
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
Related
I'm using WatchService for synchronization data files with the application workbench. When I rename/move the watched directory I don't get any event nor the WatchKey won't become invalid. I still get events from the renamed directory but as far as I know there no way to find out the actual Path for the WatchKey besides WatchKey.watchable() which however still returns original directory path. I would like to avoid need of locking the watched directory against changes since I want to keep the application as lightweight as possible.
I have experienced this problem with JDK 7u10 on Windows 7
Do you know any workaround for this issue without locking the directory or watching all directories to the root?
UPDATE
On Linux I have observed the same behavior.
So far it seems I have three options now.
1) Rely on user's discipline that he/she won't move the data directories. I don't really like this options since it might lead to undefined behavior.
2) Use more extensive non-standard native library
3) Create hierarchy of watchdogs on superior directories. These would accept only ENTRY_DELETE events since this event (or OVERFLOW) must appear at the moment the actual watched directory is moved or deleted and thus invalid.
My understanding is that renaming a directory will generate file system events on the old and new parent directories, not on the directory that is renamed. According to the answer to Can iNotify tell me where a monitored file is moved?, the OS cannot tell you where something was moved to unless you are monitoring the destination directory. (And besides, in Java 7/8 MOVE events aren't handled by the watch service implementation.)
UPDATE
You could try the jpathwatch project that adds support for (platform specific) extended events using the standard Java7 WatchService APIs.
References:
documentation - http://jpathwatch.wordpress.com/
javadoc - http://jpathwatch.sourceforge.net/
I have written a server application but I want to be able to edit the server's configuration while it is running and reload it into the server's memory without restarting, is there any way to do this in java other than creating a listening socket for configuration purposes?
In the library Apache Commons IO, you get for free a File monitor which you can use to know if a configuration file has been modified and handle the modification
In Java 7, you have a similar functionality in NIO2, a WatchService I think.
After that, correctly handling the modification depends on your architecture. You may have a look at ClassLoader to discard certain part of your configuration and load others
I have a lot of configuration files that modify how my application behaves. I want to be able to make a change and it gets reflected in the application right away when saving the file. Is there a Java library to help with this?
I could simply keep a list of files with their timestamps and continuously check in a background thread when a timestamp changes. Doesn't seem too difficult, but maybe there's a more efficient way to do this? Custom triggers when certain properties have changed would be nice.
I'm using Spring 3.1, is there a built-in mechanism or solution which works nicely with Spring?
UPDATE: Apparently JDK7 now includes this functionality through its Watch Service API: "Most file system implementations have native support for file change notification. The Watch Service API takes advantage of this support where available. However, when a file system does not support this mechanism, the Watch Service will poll the file system, waiting for events." So this'll be my motivation to migrate to JDK7.
Edited:
http://commons.apache.org/configuration/userguide/howto_filebased.html
I have a folder in which continuously new files are being dumped.In Java,what is the best way to detect changes in file-system (ie. a specified folder in which the files are being dumped) and add the newly arrived files to a queue data structure so that i can sequentially process each incoming file.
I'm aware of listFiles() function in the File class but using this I can only get files that are available at an instant of time. Of course I can continuously poll the folder and get the list of files in it using a thread.But is this the best way or is there a better way to accomplish this.
Continuously polling is the way to do it in Java as of now - though don't poll too often, it can be quite a heavy operation if the directory contains lots of entries.
JDK 7 will have a specific API for doing just this java.nio.file.WatchFile
There is unfortunately no standard way to do this until JDK7 comes out.
But there are some libraries available on the internet which use the native functions of different operating systems to do this.
The libraries which I have looked at are
jPoller and jNotify
But in the end I ended simply polling the directory which was interesting for me when I had to do that.
I have a folder in which continuously new files are being dumped.In Java,what is the best way to detect changes in file-system (ie. a specified folder in which the files are being dumped) and add the newly arrived files to a queue data structure so that i can sequentially process each incoming file.
I'm aware of listFiles() function in the File class but using this I can only get files that are available at an instant of time. Of course I can continuously poll the folder and get the list of files in it using a thread.But is this the best way or is there a better way to accomplish this.
Continuously polling is the way to do it in Java as of now - though don't poll too often, it can be quite a heavy operation if the directory contains lots of entries.
JDK 7 will have a specific API for doing just this java.nio.file.WatchFile
There is unfortunately no standard way to do this until JDK7 comes out.
But there are some libraries available on the internet which use the native functions of different operating systems to do this.
The libraries which I have looked at are
jPoller and jNotify
But in the end I ended simply polling the directory which was interesting for me when I had to do that.