Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8065488 | 8u45 | Ivan Gerasimov | P4 | Resolved | Fixed | b01 |
JDK-8064402 | 8u40 | Ivan Gerasimov | P4 | Resolved | Fixed | b15 |
JDK-8070039 | emb-8u47 | Ivan Gerasimov | P4 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
java version " 1.7.0_11 "
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
A thread after interrupted, calls path.register(http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html#register%28java.nio.file.WatchService,%20java.nio.file.WatchEvent.Kind...%29) method. The interrupt status gets cleared without any InterruptedException being thrown. Resulting in unsuccessful termination of a task in ExecutorService.
The documentation doesn't explain any behavior for this.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the code. You will probably have to try different sleep times to replicate it (at line c). On my computer sleep time of 10 ms replicates the case 99/100 times.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
interrupted //line 1
Interrupt Status: true at line a //line 2
Interrupt Status: true at line b. //line 3
/*
if line 1 is printed. Then line 2 and line 3 should print true. Which means that the thread was interrupted. In reality, it prints false which means the status is cleared without any exception being thrown.
*/
ACTUAL -
interrupted
Interrupt Status: true at line a
Interrupt Status: false at line b.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.*;
import java.nio.file.*;
import static java.nio.file.LinkOption.*;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.attribute.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Example to watch a directory (or tree) for changes to files.
*/
public class WatchDir {
private final WatchService watcher;
private final Map<WatchKey,Path> keys;
private final boolean recursive;
/**
* Register the given directory with the WatchService
*/
private void register(Path dir) throws IOException {
System.out.format( " Interrupt Status: " +Thread.currentThread().isInterrupted()+ " at line a
" , dir);//line a
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
System.out.format( " Interrupt Status: " +Thread.currentThread().isInterrupted()+ " at line b.
" , dir);//line b
Path prev = keys.get(key);
keys.put(key, dir);
}
/**
* Register the given directory, and all its sub-directories, with the
* WatchService.
*/
private void registerAll(final Path start) throws IOException {
// register directory and sub-directories
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
//System.out.format(Thread.currentThread().isInterrupted()+ " register: %s
" , dir);
register(dir);
return FileVisitResult.CONTINUE;
}
});
}
/**
* Creates a WatchService and registers the given directory
*/
WatchDir(Path dir, boolean recursive) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey,Path>();
this.recursive = recursive;
//System.out.format( " Scanning %s ... " +Thread.currentThread().isInterrupted()+ "
" , dir);
registerAll(dir);
}
/**
* Process all events for keys queued to the watcher
*/
public static void main(String[] args) throws Exception {
// register directory and process its events
File f = new File( " test_interrupt_status " );
f.mkdir();
Path dir = new File( " ./test_interrupt_status " ).toPath();
final Thread g = Thread.currentThread();
new Thread(new Runnable(){
public void run() {
try {
Thread.currentThread().sleep(10);//keep changing values here. line c
System.out.println( " interrupted " );
g.interrupt();
} catch (InterruptedException ex) {
Logger.getLogger(WatchDir.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
//System.out.println(Thread.currentThread().isInterrupted());
new WatchDir(dir, true);
}
}
---------- END SOURCE ----------
SUPPORT :
YES
java version " 1.7.0_11 "
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
A thread after interrupted, calls path.register(http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html#register%28java.nio.file.WatchService,%20java.nio.file.WatchEvent.Kind...%29) method. The interrupt status gets cleared without any InterruptedException being thrown. Resulting in unsuccessful termination of a task in ExecutorService.
The documentation doesn't explain any behavior for this.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the code. You will probably have to try different sleep times to replicate it (at line c). On my computer sleep time of 10 ms replicates the case 99/100 times.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
interrupted //line 1
Interrupt Status: true at line a //line 2
Interrupt Status: true at line b. //line 3
/*
if line 1 is printed. Then line 2 and line 3 should print true. Which means that the thread was interrupted. In reality, it prints false which means the status is cleared without any exception being thrown.
*/
ACTUAL -
interrupted
Interrupt Status: true at line a
Interrupt Status: false at line b.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.*;
import java.nio.file.*;
import static java.nio.file.LinkOption.*;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.attribute.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Example to watch a directory (or tree) for changes to files.
*/
public class WatchDir {
private final WatchService watcher;
private final Map<WatchKey,Path> keys;
private final boolean recursive;
/**
* Register the given directory with the WatchService
*/
private void register(Path dir) throws IOException {
System.out.format( " Interrupt Status: " +Thread.currentThread().isInterrupted()+ " at line a
" , dir);//line a
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
System.out.format( " Interrupt Status: " +Thread.currentThread().isInterrupted()+ " at line b.
" , dir);//line b
Path prev = keys.get(key);
keys.put(key, dir);
}
/**
* Register the given directory, and all its sub-directories, with the
* WatchService.
*/
private void registerAll(final Path start) throws IOException {
// register directory and sub-directories
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
//System.out.format(Thread.currentThread().isInterrupted()+ " register: %s
" , dir);
register(dir);
return FileVisitResult.CONTINUE;
}
});
}
/**
* Creates a WatchService and registers the given directory
*/
WatchDir(Path dir, boolean recursive) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey,Path>();
this.recursive = recursive;
//System.out.format( " Scanning %s ... " +Thread.currentThread().isInterrupted()+ "
" , dir);
registerAll(dir);
}
/**
* Process all events for keys queued to the watcher
*/
public static void main(String[] args) throws Exception {
// register directory and process its events
File f = new File( " test_interrupt_status " );
f.mkdir();
Path dir = new File( " ./test_interrupt_status " ).toPath();
final Thread g = Thread.currentThread();
new Thread(new Runnable(){
public void run() {
try {
Thread.currentThread().sleep(10);//keep changing values here. line c
System.out.println( " interrupted " );
g.interrupt();
} catch (InterruptedException ex) {
Logger.getLogger(WatchDir.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
//System.out.println(Thread.currentThread().isInterrupted());
new WatchDir(dir, true);
}
}
---------- END SOURCE ----------
SUPPORT :
YES
- backported by
-
JDK-8064402 (fs) Path.register(..) clears interrupt status of thread with no InterruptedException
-
- Resolved
-
-
JDK-8065488 (fs) Path.register(..) clears interrupt status of thread with no InterruptedException
-
- Resolved
-
-
JDK-8070039 (fs) Path.register(..) clears interrupt status of thread with no InterruptedException
-
- Resolved
-
- duplicates
-
JDK-8066966 java.nio.file.Path#register clears the interrupt status on windows and ubuntu
-
- Closed
-
- relates to
-
JDK-8081063 (fs) WatchService.take() ignores thread interrupt status if a WatchKey is signalled
-
- Open
-