FileUtils.moveFile is not always throwing IOException when it fails to move the fail in the event of disk full situation. The new file gets created but the size is 0. Below is the code
void function1 (String filePath1, String dir)
{
File file1= new File( filePath1);
File file2= new File( dir, file1.getName() );
FileUtils.moveFile( file1, file2);
}
Multiple threads are using above function. Every thread has a unique filePath1 value. The disk storage is controlled by a NFS server. So some of the threads are throwing following exception (file names have been masked) when move file fails and empty file is created.
Failed to copy full contents from '######' to '######' Expected length: 239 ?Actual: 0
at org.apache.commons.io.FileUtils.doCopyFile(FileUtils.java:1164)
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1088)
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1040)
at org.apache.commons.io.FileUtils.moveFile(FileUtils.java:2993)
at function1
But some of them do not throw any exception, and destination file is empty.
To verify this I added check for file size.
void function1 (String filePath1, String dir)
{
File file1= new File( filePath1);
File file2= new File( dir, file1.getName() );
long sizeOfFile1 = FileUtils.sizeOf( file1);
FileUtils.moveFile( file1, file2);
long sizeOfFile2 = FileUtils.sizeOf( file2);
if( sizeOFile1 != sizeOfFile2 )
LOG.error( "###### expected size " + sizeOFile1 + " but actual size " + sizeOfFile2 + " for thread " + ######## );
throw new IOException();
}
}
After this every thread that was not throwing exception earlier started printing the error in above function
expected size 239 but actual size 0 for thread
So I wanted to understand if there is something else that could have been done in case of NFS storage or is there a bug in JVM due to which it doesn’t inform the application when it has failed to move the file?
The normal behavior for a write(...) syscall to a full filesystem is to fail and set errno to ENOSPC. The Java would then turn that into an IOException.
However, it appears that your NFS mount is not reporting file-system-full like a normal file system would. Here is some evidence that this kind of thing can happen:
If the write syscall is not reporting an error, there is nothing that the Java runtime can do to detect the problem. If this is what is happening, then it is not a Java bug. It is probably a bug in the implementation of the NFS server or client-side implementation that you are using.
I would expect the FileUtils.moveFile and copyFile methods to detect the problem. However you didn't say which version of Apache Commons you are using, so I can't be sure of that. Also, since you are using multiple threads to move files, it is possible that two threads are trying to move the same file, and that that is causing problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With