Backend Development 9 min read

File Change Monitoring in Java: WatchService, JDK Bug, and Inotify

This article examines Java file change monitoring, explains the limitations of a simple timestamp‑polling approach, details a JDK bug that loses millisecond precision, explores the built‑in WatchService and its fallback to polling, and demonstrates how Linux inotify provides a more reliable solution.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
File Change Monitoring in Java: WatchService, JDK Bug, and Inotify

The author encountered a file‑change‑monitoring problem in a configuration‑distribution service and shares a detailed investigation and solution.

Initially the implementation used a dedicated thread that periodically read each file's last-modified timestamp, which suffered from delayed detection and, due to a JDK bug, could lose millisecond precision, causing missed updates.

The bug (JDK‑8177809) was demonstrated on JDK 1.8.0_261 and JDK 11.0.6, showing that on affected versions the file timestamp is rounded to whole seconds, increasing the chance of undetected changes within the same second.

Discovering Java's WatchService , the author wrote a demo to watch a directory, but observed that on macOS the first modify event appeared after about 9.5 seconds, indicating the service was using a polling implementation.

public static void watchDir(String dir) {
    Path path = Paths.get(dir);
    try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
        path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE,
                StandardWatchEventKinds.OVERFLOW);
        while (true) {
            WatchKey key = watchService.take();
            for (WatchEvent
watchEvent : key.pollEvents()) {
                if (watchEvent.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
                    System.out.println("create..." + System.currentTimeMillis());
                } else if (watchEvent.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
                    System.out.println("modify..." + System.currentTimeMillis());
                } else if (watchEvent.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
                    System.out.println("delete..." + System.currentTimeMillis());
                } else if (watchEvent.kind() == StandardWatchEventKinds.OVERFLOW) {
                    System.out.println("overflow..." + System.currentTimeMillis());
                }
            }
            if (!key.reset()) {
                System.out.println("reset false");
                return;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Debugging revealed that WatchService instantiated a PollingWatchService on macOS, which internally polls file timestamps much like the original approach, and thus inherits the same precision bug.

On Linux, however, the service uses LinuxWatchService , which leverages the kernel's inotify mechanism. The author examined native inotify‑based libraries (e.g., Jinotify) and confirmed that Linux receives events promptly.

class sun.nio.fs.PollingWatchService
class sun.nio.fs.LinuxWatchService

Experiments comparing macOS and Linux showed many more events and near‑real‑time delivery on Linux. Using strace -f -o s.txt java FileTime captured inotify system calls, confirming the native implementation.

To work around the JDK bug, the team added a separate version file containing the MD5 of the configuration file; the application reloads the config only when the version changes, avoiding reliance on timestamp precision.

In conclusion, the author stresses that hidden bugs can cause production failures, encourages deep technical investigation, and suggests consulting domain experts when needed.

Javabackend developmentinotifyfile monitoringJDK BugWatchService
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.