Search code examples
javanioioexception

Why is Java returning an error rather than an IOException when try and get a file lock


This code running with Java 1.8.0_72 25.72-b15 64bit on Windows 8.1

protected FileLock getFileLockForWriting(FileChannel fileChannel, String filePath) throws IOException
    {
        logger.finest("locking fileChannel for " + filePath);
        FileLock fileLock;
        try
        {
            fileLock = fileChannel.tryLock();
        }
        //Assumes locking is not supported on this platform so just returns null
        catch (IOException exception)
        {
            return null;
        }

        //Couldnt getFields lock because file is already locked by another application
        if (fileLock == null)
        {
            throw new IOException(ErrorMessage.GENERAL_WRITE_FAILED_FILE_LOCKED.getMsg(filePath));
        }
        return fileLock;
    }

is reporting this error for a particular user

java.lang.Error: java.io.IOException: The specified server cannot perform the requested operation
    at sun.nio.ch.FileKey.create(Unknown Source)
    at sun.nio.ch.SharedFileLockTable.<init>(Unknown Source)
    at sun.nio.ch.FileLockTable.newSharedFileLockTable(Unknown Source)
    at sun.nio.ch.FileChannelImpl.fileLockTable(Unknown Source)
    at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source)
    at java.nio.channels.FileChannel.tryLock(Unknown Source)
    at org.jaudiotagger.tag.id3.AbstractID3v2Tag.getFileLockForWriting(AbstractID3v2Tag.java:1080)
    at org.jaudiotagger.tag.id3.AbstractID3v2Tag.writeBufferToFile(AbstractID3v2Tag.java:1462)
    at org.jaudiotagger.tag.id3.ID3v23Tag.write(ID3v23Tag.java:751)
    at org.jaudiotagger.audio.mp3.MP3File.save(MP3File.java:1011)
    at org.jaudiotagger.audio.mp3.MP3File.save(MP3File.java:920)
    at org.jaudiotagger.audio.mp3.MP3File.commit(MP3File.java:932)
    at com.jthink.songkong.analyse.analyser.SongSaver.realSave(SongSaver.java:798)
    at com.jthink.songkong.analyse.analyser.SongSaver.saveSongToFile(SongSaver.java:623)
    at com.jthink.songkong.analyse.analyser.SongSaver.saveChanges(SongSaver.java:185)
    at com.jthink.songkong.analyse.analyser.SongSaver.call(SongSaver.java:160)
    at com.jthink.songkong.analyse.analyser.SongSaver.call(SongSaver.java:54)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: The specified server cannot perform the requested operation
    at sun.nio.ch.FileKey.init(Native Method)
    ... 21 more

It seems it is returning an Error because file locking is not supported, but it should be returning an IOException, (my code expects an IOException), why should this be

Update I case relevent it’s a Western Digital MyBook Live 3TBNAS, Firmware version is 02.43.10-048 which running Debian 5.0.4


Solution

  • All code above FileKey.create can throw a IOException so your assumption that this behaviour is not ok is correct.

    Indeed this was already filed as bug. In Java 9 the Error will be gone and a IOException will be thrown instead.

    Therefore for now you should be prepared to catch the error and evaluate the inner IOException.