Summary
Improve the specification of java.nio.channels.FileLock.overlaps()
and adjust its behavior to match. In the java.nio.channels
classes AsynchronousFileChannel
and FileChannel
, clarify and make consistent the behavior of creating a FileLock
when the size
parameter is zero.
Problem
The method FileLock.overlaps(position,size)
does not place any constraints on its parameters unlike the constructors of the class, and does not behave in a useful way when the size
parameter is negative, or the sum of the position
and size
parameters overflows a long
.
The lock creation methods in AsynchronousFileChannel
and FileChannel
which accept position and size parameters are not sufficiently clear that a size parameter of zero means to lock all bytes from the position onward whether or not the size of the file subsequently changes.
Solution
Make FileLock.overlaps
handle a negative size and an overflowing sum of position and size in a reasonable way.
Make it clear that the lock creation methods in AsynchronousFileChannel
and FileChannel
which accept position and size parameters will create a lock of size Long.MAX_VALUE - position
when the size
parameter is zero, and that this means that all bytes from position onward are locked regardless of file size changes.
Specification
--- a/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java
@@ -425,10 +425,13 @@ public abstract class AsynchronousFileChannel
* required then a region starting at zero, and no smaller than the
* expected maximum size of the file, should be locked. The two-argument
* {@link #lock(Object,CompletionHandler)} method simply locks a region
- * of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested
- * region is already held by this Java virtual machine, or this method has
- * been invoked to lock an overlapping region and that operation has not
- * completed, then this method throws {@link OverlappingFileLockException}.
+ * of size {@link Long#MAX_VALUE}. If the {@code position} is non-negative
+ * and the {@code size} is zero, then a lock of size
+ * {@code Long.MAX_VALUE - position} is returned. If a lock that
+ * overlaps the requested region is already held by this Java virtual
+ * machine, or this method has been invoked to lock an overlapping region
+ * and that operation has not completed, then this method throws
+ * {@link OverlappingFileLockException}.
*
* <p> Some operating systems do not support a mechanism to acquire a file
* lock in an asynchronous manner. Consequently an implementation may
@@ -454,7 +457,10 @@ public abstract class AsynchronousFileChannel
* non-negative
* @param size
* The size of the locked region; must be non-negative, and the sum
- * {@code position} + {@code size} must be non-negative
+ * {@code position} + {@code size} must be non-negative.
+ * A value of zero means to lock all bytes from the specified
+ * starting position to the end of the file, regardless of whether
+ * the file is subsequently extended or truncated
* @param shared
* {@code true} to request a shared lock, in which case this
* channel must be open for reading (and possibly writing);
@@ -532,7 +538,10 @@ public abstract class AsynchronousFileChannel
* non-negative
* @param size
* The size of the locked region; must be non-negative, and the sum
- * {@code position} + {@code size} must be non-negative
+ * {@code position} + {@code size} must be non-negative.
+ * A value of zero means to lock all bytes from the specified
+ * starting position to the end of the file, regardless of whether
+ * the file is subsequently extended or truncated
* @param shared
* {@code true} to request a shared lock, in which case this
* channel must be open for reading (and possibly writing);
@@ -586,7 +595,9 @@ public abstract class AsynchronousFileChannel
* either having acquired a lock on the requested region or having failed to
* do so. If it fails to acquire a lock because an overlapping lock is held
* by another program then it returns {@code null}. If it fails to acquire
- * a lock for any other reason then an appropriate exception is thrown.
+ * a lock for any other reason then an appropriate exception is thrown. If
+ * the {@code position} is non-negative and the {@code size} is zero, then a
+ * lock of size {@code Long.MAX_VALUE - position} is returned.
*
* @param position
* The position at which the locked region is to start; must be
@@ -594,7 +605,10 @@ public abstract class AsynchronousFileChannel
*
* @param size
* The size of the locked region; must be non-negative, and the sum
- * {@code position} + {@code size} must be non-negative
+ * {@code position} + {@code size} must be non-negative.
+ * A value of zero means to lock all bytes from the specified
+ * starting position to the end of the file, regardless of whether
+ * the file is subsequently extended or truncated
*
* @param shared
* {@code true} to request a shared lock,
--- a/src/java.base/share/classes/java/nio/channels/FileChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java
@@ -981,7 +981,9 @@ public abstract class FileChannel
* required then a region starting at zero, and no smaller than the
* expected maximum size of the file, should be locked. The zero-argument
* {@link #lock()} method simply locks a region of size {@link
- * Long#MAX_VALUE}.
+ * Long#MAX_VALUE}. If the {@code position} is non-negative and the
+ * {@code size} is zero, then a lock of size
+ * {@code Long.MAX_VALUE - position} is returned.
*
* <p> Some operating systems do not support shared locks, in which case a
* request for a shared lock is automatically converted into a request for
@@ -999,7 +1001,10 @@ public abstract class FileChannel
*
* @param size
* The size of the locked region; must be non-negative, and the sum
- * {@code position} + {@code size} must be non-negative
+ * {@code position} + {@code size} must be non-negative.
+ * A value of zero means to lock all bytes from the specified
+ * starting position to the end of the file, regardless of whether
+ * the file is subsequently extended or truncated
*
* @param shared
* {@code true} to request a shared lock, in which case this
@@ -1108,7 +1113,9 @@ public abstract class FileChannel
* required then a region starting at zero, and no smaller than the
* expected maximum size of the file, should be locked. The zero-argument
* {@link #tryLock()} method simply locks a region of size {@link
- * Long#MAX_VALUE}.
+ * Long#MAX_VALUE}. If the {@code position} is non-negative and the
+ * {@code size} is zero, then a lock of size
+ * {@code Long.MAX_VALUE - position} is returned.
*
* <p> Some operating systems do not support shared locks, in which case a
* request for a shared lock is automatically converted into a request for
@@ -1126,7 +1133,10 @@ public abstract class FileChannel
*
* @param size
* The size of the locked region; must be non-negative, and the sum
- * {@code position} + {@code size} must be non-negative
+ * {@code position} + {@code size} must be non-negative.
+ * A value of zero means to lock all bytes from the specified
+ * starting position to the end of the file, regardless of whether
+ * the file is subsequently extended or truncated
*
* @param shared
* {@code true} to request a shared lock,
--- a/src/java.base/share/classes/java/nio/channels/FileLock.java
+++ b/src/java.base/share/classes/java/nio/channels/FileLock.java
@@ -269,14 +269,34 @@ public abstract class FileLock implements AutoCloseable {
* @param size
* The size of the lock range
*
- * @return {@code true} if, and only if, this lock and the given lock
- * range overlap by at least one byte
+ * @return {@code true} if this lock and the given lock range overlap
+ * by at least one byte; {@code false} if {@code size} is
+ * negative or the lock range does not overlap this lock
*/
public final boolean overlaps(long position, long size) {
- csr of
-
JDK-5041655 (ch) FileLock: negative param and overflow issues
-
- Resolved
-