JNotify

Omry Yadan (omry at yadan dot net)

Contents

1  JNotify java API
2  JNotify native API
    2.1  Linux
    2.2  Windows

1  JNotify java API

JNotify is a java library that allow java application to listen to file system events, such as:
JNotify works on both Windows (Windows 2000, XP, Vista) and Linux with INotify support (Kernel 2.6.14 and above).
// to add a watch : 
String path = System.getProperty("user.home");

// watch mask
int mask = JNotify.FILE_CREATED  |  JNotify.FILE_DELETED  |  JNotify.FILE_MODIFIED  |  JNotify.FILE_RENAMED;

//watch subtree?
boolean watchSubtree = true;

// add actual watch
int watchID = JNotify.addWatch(path, mask, watchSubtree, new JNotifyListenerImpl());

// sleep a little, the application will exit if you 
// don't (watching is asynchrnous), depending on your 
// application, this may not be required
try
{
        Thread.sleep(1000000);
}
catch (InterruptedException e1)
{
}

// to remove watch the watch
boolean res = JNotify.removeWatch(watchID);
if (!res)
{
        // invalid watch ID specified.
}
To use JNotify, you need to have the native library (jnotify.dll or jnotify.so) in your java.library.path. to do that, you need to use the -Djava.library.path prameter when you run the java application. for example:
java -cp jnotify.jar -Djava.library.path=.

2  JNotify native API

JNotify uses native library to access the system API required to listen for changes, currenly both Windows and Linux are supported.

2.1  Linux

JNotify Linux API is a thin wrapper around Linux INotify API
since Linux INotify API does not support recursive listening on a directory, JNotify add this functionality by createing an INotify watch on every sub directory under the watched directory (this is transparent to the user). this process takes a time which is linear to the number of directories in the tree being recursively watched, and require system resources, namely - INotify watches, which are limited, by default to 8192 watches per processes.
if you get an exception like :
net.contentobjects.jnotify.linux.JNotifyException_linux: Error watching /home/omry/file : No space left on device
it means the native inotify watch limit per process has been reached. the solution is to change the limit with a command like this (only root can do it):
echo 32000 > /proc/sys/fs/inotify/max_user_watches
which will set the maximum number of watches per process to 32000.
Users of JNotify need to give up some of the functionality of the underlying system, for example, linux supports IN_CLOSE_NOWRITE event, and windows does not, it means JNotify will not support it. JNotify only support events on basic operations.
it is, however, possible to use net.contentobjects.jnotify.linux.JNotify_linux class direclty, if you do not care about code portablity. this, however, means you will also no benefit from the clean API of JNotify and not from the recursive listening support.

2.2  Windows

Windows API for file system events is quite hard to use, and has forced me to put most of the logic in C++ code. however, win32 API supports recursive tree listening, which means such listening is much more efficient on Windows than in Linux in terms on system resources required. Like with Linux, it is possible to use net.contentobjects.jnotify.win32.JNotify_win32 directly to gain access to win32 specific events which are not covered by JNotify. this is, again, not recommended, as it costs in portability.