gmethvin / directory-watcher

A cross-platform Java recursive directory watcher, with a JNA macOS watcher and Scala better-files integration
Apache License 2.0
264 stars 34 forks source link

Absolute path prevents events on macOS #49

Closed hansenc closed 4 years ago

hansenc commented 4 years ago

Using directory-watcher 0.9.9 on macOS Mojave 10.14.6, the following test fails:

Path testFile = Paths.get("target/testFile.txt");
createIfNeeded(testFile);
DirectoryChangeListener mockListener = mock(DirectoryChangeListener.class);
when(mockListener.isWatching()).thenReturn(true);

DirectoryWatcher watcher = DirectoryWatcher.builder()
        .path(testFile.getParent().toAbsolutePath())
        .listener(mockListener)
        .build();
watcher.watchAsync();

try {
    Files.setLastModifiedTime(testFile, FileTime.from(Instant.now()));
    Thread.sleep(100);
}
finally {
    watcher.close();
}

verify(mockListener, atLeastOnce()).onEvent(any());

.. but if you use .path(testFile.getParent()) instead, it passes. Then, hardcode an absolute path and it fails again.

gmethvin commented 4 years ago

Sorry I haven't had a chance to look into this yet. If you have an idea of the cause I'm happy to discuss here or help out with a pull request.

hansenc commented 4 years ago

I haven't looked further, but it may be related to file hashing (enabled by default) since the test passes with file hashing disabled (both absolute and relative paths). I needed to turn off file hashing for my use case anyway and I haven't run into this since.

gmethvin commented 4 years ago

Oh, okay, I think I see what's happening now. The hash takes into account both the path of the file and the content. It's actually the intended behavior for it to not emit an event if the content hasn't changed. The modify time isn't taken into account in the hash (maybe it should be, but that's another question...). The bug here is that we aren't standardizing the path in this case, so we are seeing these as different paths from a hashing perspective.