When trying to lock a file that is on a SMB or an AFP network filesystem, FileChannel.tryLock() throws an IOException with the message "Operation not supported" .
The reason seems to be that the JRE uses the call fcntl to try to lock files on these network shares. On OS X fcntl does not support locking files on AFP or SMB (I believe NFS works alright, but am not certain). A possible alternative is perhaps the call flock for AFP and SMB.
More general information can be found on http://www.briandwells.com/main/Blog/Entries/2006/10/5_Subversion,_Mac_OS_X,_and_SMB.html
To test the problem, mount an SMB or AFP share on a OS X machine. Then run this code with one of the mounted files as argument:
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class FileLockTest {
public static void main(String[] args) throws Exception {
RandomAccessFile file = null;
FileLock fileLock = null;
try
{
file = new RandomAccessFile(args[0], "rw");
FileChannel fileChannel = file.getChannel();
fileLock = fileChannel.tryLock();
if (fileLock != null){
System.out.println("File is locked");
}
} finally{
if (fileLock != null){
fileLock.release();
}
}
}
}
When working properly, you should see the text "File is locked".
When failing, you see something like:
Exception in thread "main" java.io.IOException: Operation not supported
at sun.nio.ch.FileDispatcherImpl.lock0(Native Method)
at sun.nio.ch.FileDispatcherImpl.lock(FileDispatcherImpl.java:90)
at sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:1114)
at java.nio.channels.FileChannel.tryLock(FileChannel.java:1155)
at FileLockTest.main(FileLockTest.java:15)
Please note that the thrown exception is not very helpful, because it is a plain IOException with some message. As a programmer, I'd like to distinguish between a real failure or an unsupported operation. Even if for some reason proper locking cannot be implemented, please implement a specific exception that is thrown in case a file cannot be locked, because the mechanism isn't properly implemented or supported by the OS. Something like FileLockUnsupportedException (subclass of IOException) with a proper reason that perhaps contains the filesystem type.
The reason seems to be that the JRE uses the call fcntl to try to lock files on these network shares. On OS X fcntl does not support locking files on AFP or SMB (I believe NFS works alright, but am not certain). A possible alternative is perhaps the call flock for AFP and SMB.
More general information can be found on http://www.briandwells.com/main/Blog/Entries/2006/10/5_Subversion,_Mac_OS_X,_and_SMB.html
To test the problem, mount an SMB or AFP share on a OS X machine. Then run this code with one of the mounted files as argument:
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class FileLockTest {
public static void main(String[] args) throws Exception {
RandomAccessFile file = null;
FileLock fileLock = null;
try
{
file = new RandomAccessFile(args[0], "rw");
FileChannel fileChannel = file.getChannel();
fileLock = fileChannel.tryLock();
if (fileLock != null){
System.out.println("File is locked");
}
} finally{
if (fileLock != null){
fileLock.release();
}
}
}
}
When working properly, you should see the text "File is locked".
When failing, you see something like:
Exception in thread "main" java.io.IOException: Operation not supported
at sun.nio.ch.FileDispatcherImpl.lock0(Native Method)
at sun.nio.ch.FileDispatcherImpl.lock(FileDispatcherImpl.java:90)
at sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:1114)
at java.nio.channels.FileChannel.tryLock(FileChannel.java:1155)
at FileLockTest.main(FileLockTest.java:15)
Please note that the thrown exception is not very helpful, because it is a plain IOException with some message. As a programmer, I'd like to distinguish between a real failure or an unsupported operation. Even if for some reason proper locking cannot be implemented, please implement a specific exception that is thrown in case a file cannot be locked, because the mechanism isn't properly implemented or supported by the OS. Something like FileLockUnsupportedException (subclass of IOException) with a proper reason that perhaps contains the filesystem type.