JDK-8029516 : (fs) WatchKey cancel unreliable on Windows
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7u45,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • Submitted: 2013-12-03
  • Updated: 2017-10-24
  • Resolved: 2014-09-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u72Fixed 9 b31Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)

Microsoft Windows [Version 6.1.7601]

Reproducible using SSD or platter HDD devices on these laptops:

OS NameMicrosoft Windows 7 Enterprise
Version6.1.7601 Service Pack 1 Build 7601
System ManufacturerDell Inc.
System ModelPrecision M6600
System Typex64-based PC
ProcessorIntel(R) Core(TM) i7-2720QM CPU @ 2.20GHz, 2201 Mhz, 4 Core(s), 8 Logical Processor(s)
BIOS Version/DateDell Inc. A06, 10/2/2011
SMBIOS Version2.6
Windows DirectoryC:\windows
System DirectoryC:\windows\system32
Boot Device\Device\HarddiskVolume1
Hardware Abstraction LayerVersion = "6.1.7601.17514"
Installed Physical Memory (RAM)8.00 GB
  Total Physical Memory7.96 GB
Available Physical Memory4.34 GB
  Total Virtual Memory9.96 GB
Available Virtual Memory6.02 GB
Page File Space2.00 GB
Page FileC:\pagefile.sys

Multithreaded use of the WatchService and WatchKey classes causes JVM crash in rare circumstances.

The issue occurs with one thread responsible for registering and unregistering Path objects with the WatchService while another thread listens for and handles events from the WatchService. Javadoc paragraph 4 for the WatchService class indicates "A watch service is safe for use by multiple concurrent consumers". Furthermore, synchronized access to the WatchService does not work around this issue.

I have not been able to narrow down the conditions of the crash to my own satisfaction. However, I have had good success using the attached distilled test class, but only with some additional system conditions occurring during the test. The directories used by the test class should be one within the other, and the file create/delete events (line 77) should be occurring within the inner directory (path2). Lastly, another application should be accessing or monitoring the same directory where the file system events are occurring (for example, open an Explorer window to that directory, or run 'dir' in a loop to constantly list the files). I don't believe all of these conditions are directly relevant to causing the issue, but they cause it to occur with the greatest regularity.

This is a contrived use case under normal circumstances, but it can occur regularly in a unit test environment where the classes being tested wrap WatchService.  Thus, this bug can occur often in unit test environments but rarely in almost all other situations.

One last detail: I have seen the JVM crash with three different Java stack traces in the error logs.  Each stack trace is within "AbstractPoller.processRequests" as follows.  Full error logs can be provided.
NativeBuffer$Deallocator.run --> Unsafe.freeMemory
WindowsWatchService$Poller.implCancelKey --> Cleaner.clean --> NativeBuffer$Deallocator.run --> Unsafe.freeMemory
WindowsWatchService$Poller.implRegister --> NativeBuffers.getNativeBuffer --> NativeBuffers.allocNativeBuffer --> NativeBuffer.<init> --> Unsafe.allocateMemory

I did not perform any regression tests, this issue occurred in new development using JDK 1.7.

1. Configure the attached test class to point to two directories, with "path2" pointing to a directory under "path1".  Refer to the example values provided in the code.
2. Ensure the target directories already exist and are writeable.
3. Open an Explorer window to monitor the innermost of the two directories (for example, "C:\dropbox\archive\").  Alternatively, write a batch script loop which calls "dir C:\dropbox\archive\" repeatedly.  Note that this is the same directory where the test files will be created by the sample code.
4. Run the main method of the sample code.  Under the proper conditions outlined above, this issue should occur almost every time.

The main thread should terminate after the specified number of iterations.  The thread monitoring for events NEED NOT read all events from the queue before the main thread finishes.

The JVM crashes and writes an error log.

# A fatal error has been detected by the Java Runtime Environment:
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000771657d5, pid=7604, tid=7460
# JRE version: 7.0_21-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.21-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [ntdll.dll+0x257d5]  RtlAcquireSRWLockShared+0x2c5
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp

---------------  T H R E A D  ---------------

Current thread (0x000000000dd60000):  JavaThread "Thread-0" daemon [_thread_in_vm, id=7460, stack(0x000000000ee80000,0x000000000ef80000)]

siginfo: ExceptionCode=0xc0000005, reading address 0xffffffffffffffff

RAX=0x007200610000000e, RBX=0x00000000021c0000, RCX=0x0000000000100000, RDX=0x0000000000100000
RSP=0x000000000ef7ea50, RBP=0x000000000dd9dec0, RSI=0x000000000dd9deb0, RDI=0x000000000dd7f6d0
R8 =0x000000000dd7f6d0, R9 =0x00000000021c4e98, R10=0x00000000021c0158, R11=0x00000000021c4e80
R12=0x0000000000000403, R13=0x0000000000000403, R14=0x000000000ef70403, R15=0x000000000dcc0000
RIP=0x00000000771657d5, EFLAGS=0x0000000000010246

  Top of Stack: (sp=0x000000000ef7ea50)
0x000000000ef7ea50:   0000000000000000 0000000000000000
0x000000000ef7ea60:   000000000200585a 0000000000000000
0x000000000ef7ea70:   0000000000000000 0000000000000000
0x000000000ef7ea80:   000000000dd7f6d0 0000000000000000
0x000000000ef7ea90:   000000000200585a 0000000000000000
0x000000000ef7eaa0:   0000000002000002 0000000000000000
0x000000000ef7eab0:   0000000007000403 0000000000000000
0x000000000ef7eac0:   0000000007000403 00000000771966e4
0x000000000ef7ead0:   0000000022000426 0000000000000000
0x000000000ef7eae0:   0000000000000000 000000000ef7f000
0x000000000ef7eaf0:   000000000dd9dec0 0000000000000001
0x000000000ef7eb00:   00000000021c0000 000000000dd9deb0
0x000000000ef7eb10:   000000000dd9deb0 0000000077165b00
0x000000000ef7eb20:   0000000000000403 0000000061c45fda
0x000000000ef7eb30:   0000000000000001 000000000ef70403
0x000000000ef7eb40:   0000000000000000 0000000000000000

Instructions: (pc=0x00000000771657d5)
0x00000000771657b5:   00 00 00 89 44 24 70 0f b7 44 24 70 0f b7 c0 4c
0x00000000771657c5:   3b e0 0f 87 f4 3d 07 00 49 8b 40 08 48 8d 6e 10
0x00000000771657d5:   48 8b 08 49 3b c8 0f 85 f1 3d 07 00 4c 89 45 00
0x00000000771657e5:   48 89 45 08 48 89 28 49 89 68 08 0f b7 46 08 48

Register to memory mapping:

RAX=0x007200610000000e is an unknown value
RBX=0x00000000021c0000 is an unknown value
RCX=0x0000000000100000 is an unknown value
RDX=0x0000000000100000 is an unknown value
RSP=0x000000000ef7ea50 is pointing into the stack for thread: 0x000000000dd60000
RBP=0x000000000dd9dec0 is an unknown value
RSI=0x000000000dd9deb0 is an unknown value
RDI=0x000000000dd7f6d0 is an unknown value
R8 =0x000000000dd7f6d0 is an unknown value
R9 =0x00000000021c4e98 is an unknown value
R10=0x00000000021c0158 is an unknown value
R11=0x00000000021c4e80 is an unknown value
R12=0x0000000000000403 is an unknown value
R13=0x0000000000000403 is an unknown value
R14=0x000000000ef70403 is pointing into the stack for thread: 0x000000000dd60000
R15=0x000000000dcc0000 is pointing into the stack for thread: 0x000000000bf0e800

Stack: [0x000000000ee80000,0x000000000ef80000],  sp=0x000000000ef7ea50,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [ntdll.dll+0x257d5]  RtlAcquireSRWLockShared+0x2c5

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sun.misc.Unsafe.freeMemory(J)V+0
j  sun.nio.fs.NativeBuffer$Deallocator.run()V+7
J  sun.nio.fs.AbstractPoller.processRequests()Z
j  sun.nio.fs.WindowsWatchService$Poller.run()V+27
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x000000000dd60800 JavaThread "Key Polling Thread" [_thread_blocked, id=6016, stack(0x000000000f010000,0x000000000f110000)]
=>0x000000000dd60000 JavaThread "Thread-0" daemon [_thread_in_vm, id=7460, stack(0x000000000ee80000,0x000000000ef80000)]
  0x000000000dd37000 JavaThread "Service Thread" daemon [_thread_blocked, id=8076, stack(0x000000000e780000,0x000000000e880000)]
  0x000000000dd24000 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=4768, stack(0x000000000e540000,0x000000000e640000)]
  0x000000000dd0f800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=6740, stack(0x000000000e3e0000,0x000000000e4e0000)]
  0x000000000dd0e800 JavaThread "Attach Listener" daemon [_thread_blocked, id=5920, stack(0x000000000e0e0000,0x000000000e1e0000)]
  0x000000000dd0d800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=6624, stack(0x000000000e240000,0x000000000e340000)]
  0x000000000bf18000 JavaThread "Finalizer" daemon [_thread_blocked, id=8128, stack(0x0000000002300000,0x0000000002400000)]
  0x000000000bf0e800 JavaThread "Reference Handler" daemon [_thread_blocked, id=7944, stack(0x000000000dbc0000,0x000000000dcc0000)]
  0x00000000021ce800 JavaThread "main" [_thread_blocked, id=5908, stack(0x0000000002400000,0x0000000002500000)]

Other Threads:
  0x000000000bf08000 VMThread [stack: 0x000000000da60000,0x000000000db60000] [id=5876]
  0x000000000dd3f800 WatcherThread [stack: 0x000000000e8d0000,0x000000000e9d0000] [id=6572]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

 PSYoungGen      total 38080K, used 9812K [0x00000007d58b0000, 0x00000007d8320000, 0x0000000800000000)
  eden space 32704K, 30% used [0x00000007d58b0000,0x00000007d62452a8,0x00000007d78a0000)
  from space 5376K, 0% used [0x00000007d7de0000,0x00000007d7de0000,0x00000007d8320000)
  to   space 5376K, 0% used [0x00000007d78a0000,0x00000007d78a0000,0x00000007d7de0000)
 ParOldGen       total 86976K, used 0K [0x0000000780a00000, 0x0000000785ef0000, 0x00000007d58b0000)
  object space 86976K, 0% used [0x0000000780a00000,0x0000000780a00000,0x0000000785ef0000)
 PSPermGen       total 21248K, used 3159K [0x000000077b800000, 0x000000077ccc0000, 0x0000000780a00000)
  object space 21248K, 14% used [0x000000077b800000,0x000000077bb15c08,0x000000077ccc0000)

Card table byte_map: [0x0000000005500000,0x0000000005930000] byte_map_base: 0x0000000001924000

Polling page: 0x0000000000420000

Code Cache  [0x0000000002500000, 0x0000000002770000, 0x0000000005500000)
 total_blobs=284 nmethods=75 adapters=160 free_code_cache=48664Kb largest_free_block=49819136

Compilation events (10 events):
Event: 2.002 Thread 0x000000000dd0f800 nmethod 68 0x00000000025794d0 code [0x00000000025796e0, 0x000000000257a2a0]
Event: 2.002 Thread 0x000000000dd0f800   71             sun.nio.fs.WindowsPath::hashCode (52 bytes)
Event: 2.006 Thread 0x000000000dd0f800 nmethod 71 0x0000000002576110 code [0x0000000002576260, 0x00000000025765d8]
Event: 2.008 Thread 0x000000000dd24000 nmethod 70 0x0000000002577710 code [0x0000000002577920, 0x0000000002578830]
Event: 2.131 Thread 0x000000000dd0f800   72             java.nio.ByteBuffer::arrayOffset (35 bytes)
Event: 2.132 Thread 0x000000000dd0f800 nmethod 72 0x0000000002575ed0 code [0x0000000002576000, 0x0000000002576098]
Event: 2.164 Thread 0x000000000dd24000   73             java.util.HashMap::get (29 bytes)
Event: 2.167 Thread 0x000000000dd24000 nmethod 73 0x000000000257b150 code [0x000000000257b2c0, 0x000000000257b568]
Event: 2.167 Thread 0x000000000dd0f800   74             sun.nio.fs.NativeBuffer::setOwner (6 bytes)
Event: 2.167 Thread 0x000000000dd0f800 nmethod 74 0x000000000257b850 code [0x000000000257b980, 0x000000000257b9f8]

GC Heap History (0 events):
No events

Deoptimization events (0 events):
No events

Internal exceptions (3 events):
Event: 0.025 Thread 0x00000000021ce800 Threw 0x00000007d58b61b0 at C:\jdk7u2_64p\jdk7u21\hotspot\src\share\vm\prims\jni.cpp:3994
Event: 0.055 Thread 0x00000000021ce800 Threw 0x00000007d58feb08 at C:\jdk7u2_64p\jdk7u21\hotspot\src\share\vm\prims\jvm.cpp:1166
Event: 0.595 Thread 0x00000000021ce800 Threw 0x00000007d590bc70 at C:\jdk7u2_64p\jdk7u21\hotspot\src\share\vm\prims\jvm.cpp:1166

Events (10 events):
Event: 0.617 loading class 0x000000000dd5e070
Event: 0.617 loading class 0x000000000dd5e070 done
Event: 0.618 loading class 0x000000000dd5d860
Event: 0.618 loading class 0x000000000dd5d860 done
Event: 0.618 loading class 0x000000000dd6c890
Event: 0.618 loading class 0x000000000dd5d770
Event: 0.618 loading class 0x000000000dd5e2b0
Event: 0.618 loading class 0x000000000dd5e2b0 done
Event: 0.618 loading class 0x000000000dd5d770 done
Event: 0.618 loading class 0x000000000dd6c890 done

Dynamic libraries:
0x000000013fe70000 - 0x000000013fea3000 C:\Program Files\Java\jdk1.7.0_21\bin\javaw.exe
0x0000000077140000 - 0x00000000772e9000 C:\windows\SYSTEM32
0x0000000076a60000 - 0x0000000076b7f000 C:\windows\system32\kernel32.dll
0x000007fefd750000 - 0x000007fefd7bb000 C:\windows\system32\KERNELBASE.dll
0x000007fefee00000 - 0x000007fefeedb000 C:\windows\system32\ADVAPI32.dll
0x000007feff230000 - 0x000007feff2cf000 C:\windows\system32\msvcrt.dll
0x000007feff1a0000 - 0x000007feff1bf000 C:\windows\SYSTEM32\sechost.dll
0x000007feff310000 - 0x000007feff43d000 C:\windows\system32\RPCRT4.dll
0x0000000076e30000 - 0x0000000076f2a000 C:\windows\system32\USER32.dll
0x000007feff1c0000 - 0x000007feff227000 C:\windows\system32\GDI32.dll
0x000007feff440000 - 0x000007feff44e000 C:\windows\system32\LPK.dll
0x000007fefdc00000 - 0x000007fefdcc9000 C:\windows\system32\USP10.dll
0x000007fefbc00000 - 0x000007fefbdf4000 C:\windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_fa396087175ac9ac\COMCTL32.dll
0x000007fefdb80000 - 0x000007fefdbf1000 C:\windows\system32\SHLWAPI.dll
0x000007feff2e0000 - 0x000007feff30e000 C:\windows\system32\IMM32.DLL
0x000007feff090000 - 0x000007feff199000 C:\windows\system32\MSCTF.dll
0x000000006fa40000 - 0x000000006fb11000 C:\Program Files\Java\jdk1.7.0_21\jre\bin\msvcr100.dll
0x0000000061c10000 - 0x0000000062331000 C:\Program Files\Java\jdk1.7.0_21\jre\bin\server\jvm.dll
0x000007fef8d80000 - 0x000007fef8d89000 C:\windows\system32\WSOCK32.dll
0x000007fefeee0000 - 0x000007fefef2d000 C:\windows\system32\WS2_32.dll
0x000007feff2d0000 - 0x000007feff2d8000 C:\windows\system32\NSI.dll
0x000007fefc1e0000 - 0x000007fefc21b000 C:\windows\system32\WINMM.dll
0x0000000077300000 - 0x0000000077307000 C:\windows\system32\PSAPI.DLL
0x000000006f9d0000 - 0x000000006f9df000 C:\Program Files\Java\jdk1.7.0_21\jre\bin\verify.dll
0x000000006f8e0000 - 0x000000006f908000 C:\Program Files\Java\jdk1.7.0_21\jre\bin\java.dll
0x000000006f8c0000 - 0x000000006f8d5000 C:\Program Files\Java\jdk1.7.0_21\jre\bin\zip.dll
0x000000006f8a0000 - 0x000000006f8b9000 C:\Program Files\Java\jdk1.7.0_21\jre\bin
0x000007fefcea0000 - 0x000007fefcef5000 C:\windows\system32\mswsock.dll
0x000007fefcfb0000 - 0x000007fefcfb7000 C:\windows\System32\wship6.dll
0x000000006f880000 - 0x000000006f891000 C:\Program Files\Java\jdk1.7.0_21\jre\bin
0x000007fedd2b0000 - 0x000007fedd3d5000 C:\windows\system32\dbghelp.dll

VM Arguments:
jvm_args: -Dfile.encoding=Cp1252
java_command: WatchServiceBug
Launcher Type: SUN_STANDARD

Environment Variables:
JAVA_HOME=C:\Program Files (x86)\Java\jdk1.7.0_21
PATH=C:\Program Files (x86)\Java\jdk1.7.0_21\bin;C:\Program Files (x86)\Java\apache-maven-3.0.4\bin;;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Perforce;C:\Program Files\Common Files\Microsoft Shared\Microsoft Online Services;C:\Program Files (x86)\Common Files\Microsoft Shared\Microsoft Online Services;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\xmlstarlet-1.5.0;C:\Program Files\xidel-0.7.win32;C:\Program Files (x86)\wget-1.11.4-1-bin\bin;C:\Program Files (x86)\openssl-0.9.8h-1-bin\bin;C:\Program Files (x86)\xerces-c-3.1.1\bin;c:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files\Microsoft SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;;C:\Program Files\cURL\bin;C:\Program Files\Microsoft SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\DTS\BinnUSERNAME=msanders
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 42 Stepping 7, GenuineIntel

---------------  S Y S T E M  ---------------

OS: Windows 7 , 64 bit Build 7601 Service Pack 1

CPU:total 8 (4 cores per cpu, 2 threads per core) family 6 model 42 stepping 7, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, ht, tsc, tscinvbit

Memory: 4k page, physical 8344444k(4473736k free), swap 10439736k(5956748k free)

vm_info: Java HotSpot(TM) 64-Bit Server VM (23.21-b01) for windows-amd64 JRE (1.7.0_21-b11), built on Apr  4 2013 08:11:28 by "java_re" with unknown MS VC++:1600

time: Tue Dec 03 12:53:10 2013
elapsed time: 2 seconds

This bug can be reproduced rarely.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.WatchEvent.Kind;
import java.util.List;
import java.util.concurrent.TimeUnit;

 * Running this class demonstrates a bug which causes a core crash.
public class WatchServiceBug {

 * WatchService instance shared between threads.
public static WatchService sWatchService = null;

 * Main method to run the test.  No parameters required.
public static void main(String[] args) throws IOException, InterruptedException {

// Paths to register.
//String path = args[0];
//String path1 = System.getenv("TEMP");
String path1 = "C:\\dropbox\\";
String path2 = "C:\\dropbox\\archive\\";

Path watchDirectory1 = Paths.get(path1);
Path watchDirectory2 = Paths.get(path2);

// WatchService to register with.
try {
sWatchService = FileSystems.getDefault().newWatchService();
} catch (IOException e) {
System.out.println("Cannot create the file system watch service: " + e.getMessage());

// Event kinds to subscribe to.
Kind<?>[] eventKinds = new Kind<?>[] {

// Start a thread which watches for events.
WatchServiceBug.KeyWatcher runnable = new WatchServiceBug().new KeyWatcher();
Thread keyThread = new Thread(runnable);
keyThread.setName("Key Polling Thread");

// Register the directory with the service many times.
System.out.println("Register/unregister loop starting");
for (int i=1; i<=10000; i++) {
try {
// Register for events.
WatchKey watchKey1;
WatchKey watchKey2;
//synchronized (sWatchService) {
watchKey1 = watchDirectory1.register(sWatchService, eventKinds);
watchKey2 = watchDirectory2.register(sWatchService, eventKinds);

// Create a file to trigger some events.
Path testFile = Paths.get(path2, Integer.toString(i));

// Cancel the subscriptions before the next loop adds them again.
//synchronized (sWatchService) {

//System.out.println("Registered trial #" + i);
} catch (FileAlreadyExistsException e) {
System.out.println("File " + i + "already exists, deleting!");
} catch (Exception e) {
System.out.println("Register/unregister loop completed");

// Close service and stop worker thread.
runnable.mActive = false;

 * Inner runnable class which polls the WatchService for events.
public class KeyWatcher implements Runnable {

 * For graceful thread termination.
public boolean mActive = true;

 * Run method to implement Runnable.
public void run() {
// Some config flags to tweak behavior.
boolean useTake = true;
boolean useTimeout = false;

while (mActive) {
// Poll the service for events.
WatchKey theKey;
try {
//synchronized (sWatchService) {
if (useTake) {
theKey = sWatchService.take();
} else if (useTimeout) {
theKey = sWatchService.poll(1, TimeUnit.MILLISECONDS);
} else {
theKey = sWatchService.poll();
} catch (Exception e) {

// If no key was returned, just try again.
if (theKey == null) {

// Dump the list of events and reset the key.
List<WatchEvent<?>> events = theKey.pollEvents();
for (WatchEvent<?> event : events) {
System.out.println(event.kind() + " for " + theKey.watchable().toString()
+ File.separator + ((Path)event.context()).toString());

---------- END SOURCE ----------

I know of no workarounds.

Most attempts at workarounds seem to work initially, but merely result in a change in the performance profile which causes the issue to occur with different frequency.  Even adding additional logging or sleep statements causes the issue to occur differently.

Adding synchronized access to the WatchService instance does not help the issue.  The attached sample still crashes if using "WatchService.poll()", or deadlocks if using "WatchService.take()".
We have preliminary patch to address this to cancel the outstanding ReadDirectoryChangesW and synchronously wait for it to complete before closing the directory handle. The changes are more that originally expected and the patch will require a lot of testing.

The test case is useful, it appears that we have an issue with I/O cancellation when there is a pending ReadDirectoryChangesW outstanding. Further study is required to diagnose this.