Skip to content

Commit 442b98c

Browse files
committed
Add system property to configure which WatchService implementation should be used
1 parent 76eb623 commit 442b98c

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![javadoc](https://javadoc.io/badge2/engineering.swat/java-watch/docs.svg?style=flat-square)](https://javadoc.io/doc/engineering.swat/java-watch)
44
[![Codecov](https://img.shields.io/codecov/c/github/SWAT-engineering/java-watch?style=flat-square)](https://codecov.io/gh/SWAT-engineering/java-watch)
55

6-
a java file watcher that works across platforms and supports recursion, single file watches, and tries to make sure no events are missed. Where possible it uses Java's NIO WatchService.
6+
A Java file watcher that works across platforms and supports recursion, single file watches, and tries to make sure no events are missed.
77

88
## Features
99

@@ -21,7 +21,6 @@ Features:
2121

2222
Planned features:
2323

24-
- Avoid poll based watcher in macOS/OSX that only detects changes every 2 seconds (see [#4](https://github.com/SWAT-engineering/java-watch/issues/4))
2524
- Support single file watches natively in linux (see [#11](https://github.com/SWAT-engineering/java-watch/issues/11))
2625
- Monitor only specific events (such as only CREATE events)
2726

@@ -58,6 +57,14 @@ try(var active = watcherSetup.start()) {
5857
// no new events will be scheduled on the threadpool
5958
```
6059

60+
## Internals
61+
62+
On all platforms except macOS, the library internally uses the JDK default implementation of the Java NIO [`WatchService`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/WatchService.html) API.
63+
64+
On macOS, the library internally uses our custom `WatchService` implementation based on macOS's native [file system event streams](https://developer.apple.com/documentation/coreservices/file_system_events?language=objc) (using JNA).
65+
Generally, it offers better performance than the JDK default implementation (because the latter uses a polling loop to detect changes only once every two seconds).
66+
To force the library to use the JDK default implementation on macOS, set system property `engineering.swat.watch.impl` to `default`.
67+
6168
## Related work
6269

6370
Before starting this library, we wanted to use existing libraries, but they all lacked proper support for recursive file watches, single file watches or lacked configurability. This library now has a growing collection of tests and a small API that should allow for future improvements without breaking compatibility.

src/main/java/engineering/swat/watch/impl/jdk/JDKPoller.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,24 @@ public Watchable newWatchable(Path path) {
188188
}
189189
};
190190

191-
static final Platform CURRENT = // Assumption: the platform doesn't change
192-
com.sun.jna.Platform.isMac() ? MAC : DEFAULT;
191+
static final Platform CURRENT = current(); // Assumption: the platform doesn't change
192+
193+
private static Platform current() {
194+
var key = "engineering.swat.watch.impl";
195+
var val = System.getProperty(key);
196+
if (val != null) {
197+
if (val.equals("mac")) {
198+
return MAC;
199+
} else if (val.equals("default")) {
200+
return DEFAULT;
201+
} else {
202+
logger.warn("Unexpected value \"{}\" for system property \"{}\". Using value \"default\" instead.", val, key);
203+
return DEFAULT;
204+
}
205+
}
206+
207+
return com.sun.jna.Platform.isMac() ? MAC : DEFAULT;
208+
}
193209

194210
static Platform get() {
195211
return CURRENT;

0 commit comments

Comments
 (0)