FULL PRODUCT VERSION :
java version "1.7.0_60"
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)
Java HotSpot(TM) Client VM (build 24.60-b09, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Quoting from the specification for method FileChannel.lock(), "FileLockInterruptionException is thrown- If the invoking thread is interrupted while blocked in this method".
However, if the current thread was interrupted (interrupt status of thread is set and not cleared) before making a call to FileChannel.lock(), then FileLockInterruptionException is thrown.
Receiving a FileLockInterruptionException is unexpected, since the thread was not blocked on FileChannel.lock() and then the thread was interrupted.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.nio.channels.FileLock;
import java.nio.channels.FileLockInterruptionException;
/**
* Test case for verifying file lock when the thread status is interrupted.
*/
public class TestFileLock {
/**
* @param args
*/
public static void main(String[] args) {
testFileLock();
}
private static void testFileLock() {
try {
// For JDK 6, there is related issue with locking for FileOutStream
// channel when thread has interrupted status.
// See bug
// http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7024131.
System.out
.println("When thread's interrupt status is true, inputstream.getChannel.lock() will always return null on JDK 6.");
System.out
.println("When thread's interrupt status is true, inputstream.getChannel.lock() will throw FileLockInterruptionException on JDK 7.");
System.out.println("Java Version: " + System.getProperty("java.version"));
System.out.println("Java VM Version: " + System.getProperty("java.vm.version"));
// COMMENT BELOW LINE AND THE FILE CHANNEL LOCK WILL BE CLAIMED
// SUCCESSFULLY.
Thread.currentThread().interrupt();
System.out.println("Is thread interrupted: " + Thread.currentThread().isInterrupted());
for (int i = 0; i < 10; i++) {
File testFile = File.createTempFile("test-file-lock", "txt");
testFile.deleteOnExit();
FileInputStream testInputStream = new FileInputStream(testFile);
try {
FileLock testFileLock = testInputStream.getChannel().lock(0L, testFile.length(), true);
if (testFileLock != null) {
System.out.println("Got shared lock, releasing lock.");
testFileLock.release();
} else {
System.out.println("Could not get shared lock, channel.lock() returned null.");
}
} catch (FileLockInterruptionException e) {
System.out.println("Could not get shared lock, FileLockInterruptionException was thrown.");
}
testInputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Clearing the threads interrupt status before invoking FileChannel.lock() is the workaround for the problem.
java version "1.7.0_60"
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)
Java HotSpot(TM) Client VM (build 24.60-b09, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Quoting from the specification for method FileChannel.lock(), "FileLockInterruptionException is thrown- If the invoking thread is interrupted while blocked in this method".
However, if the current thread was interrupted (interrupt status of thread is set and not cleared) before making a call to FileChannel.lock(), then FileLockInterruptionException is thrown.
Receiving a FileLockInterruptionException is unexpected, since the thread was not blocked on FileChannel.lock() and then the thread was interrupted.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.nio.channels.FileLock;
import java.nio.channels.FileLockInterruptionException;
/**
* Test case for verifying file lock when the thread status is interrupted.
*/
public class TestFileLock {
/**
* @param args
*/
public static void main(String[] args) {
testFileLock();
}
private static void testFileLock() {
try {
// For JDK 6, there is related issue with locking for FileOutStream
// channel when thread has interrupted status.
// See bug
// http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7024131.
System.out
.println("When thread's interrupt status is true, inputstream.getChannel.lock() will always return null on JDK 6.");
System.out
.println("When thread's interrupt status is true, inputstream.getChannel.lock() will throw FileLockInterruptionException on JDK 7.");
System.out.println("Java Version: " + System.getProperty("java.version"));
System.out.println("Java VM Version: " + System.getProperty("java.vm.version"));
// COMMENT BELOW LINE AND THE FILE CHANNEL LOCK WILL BE CLAIMED
// SUCCESSFULLY.
Thread.currentThread().interrupt();
System.out.println("Is thread interrupted: " + Thread.currentThread().isInterrupted());
for (int i = 0; i < 10; i++) {
File testFile = File.createTempFile("test-file-lock", "txt");
testFile.deleteOnExit();
FileInputStream testInputStream = new FileInputStream(testFile);
try {
FileLock testFileLock = testInputStream.getChannel().lock(0L, testFile.length(), true);
if (testFileLock != null) {
System.out.println("Got shared lock, releasing lock.");
testFileLock.release();
} else {
System.out.println("Could not get shared lock, channel.lock() returned null.");
}
} catch (FileLockInterruptionException e) {
System.out.println("Could not get shared lock, FileLockInterruptionException was thrown.");
}
testInputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Clearing the threads interrupt status before invoking FileChannel.lock() is the workaround for the problem.
- relates to
-
JDK-8152085 (ch) RandomAccessFile.getChannel().lock() is uninterruptible (win)
-
- Open
-