Thanks Jk1 for pointing me to the issue. The answer is found here.
In summary, the FileMonitorAgent class in vfs removes the listener when a file gets deleted. (see the check method) below is the important block:
// If the file existed and now doesn't
if (this.exists && !this.file.exists())
{
this.exists = this.file.exists();
this.timestamp = -1;
// Fire delete event
((AbstractFileSystem)
this.file.getFileSystem()).fireFileDeleted(this.file);
// Remove listener in case file is re-created. Don't want to fire twice.
if (this.fm.getFileListener() != null)
{
this.file.getFileSystem().removeListener(this.file,
this.fm.getFileListener());
}
// Remove from map
this.fm.queueRemoveFile(this.file);
}
The link supplies a solution that has been submitted to vfs. I think the only solution at this point is to spawn a thread that re-adds the file to vfs after a few seconds. You have to sleep a few seconds because you get notified (via fireFileDeleted) and then the vfs code clears the listener, so you can re-add the listener until after you get notified and the vfs code clears the existing listener.