I have some code that saves some preferences to file using FileOutputStream
. It is standard code I've written a thousand times:
FileOutputStream out = new FileOutputStream(file);
try {
BufferedOutputStream bos = new BufferedOutputStream(out);
try {
store(bos, comments);
} finally {
bos.close();
}
} finally {
out.close();
}
One of our users is reporting the following error on Linux during the close()
call.
java.io.IOException: Inappropriate ioctl for device
at java.io.FileOutputStream.close0(Native Method)
at java.io.FileOutputStream.close(FileOutputStream.java:341)
at java.io.FilterOutputStream.close(FilterOutputStream.java:160)
Does anybody know if this ONLY happens when incorrectly launching the JVM with the wrong -d32 or -d64 parameter (like in this question), or is there possibly something else going on?
Java's
close()
method is a thin wrapper around the OS native close(); it will translate the native error code into an exception.The linked-to docs are relatively ambiguous about what could cause a close to fail, noting that errors during write may be reported by close, and that "This can especially be observed with NFS...".
So, to debug I'd first look at the name of the file, and where the file is being stored for this particular user. I wouldn't place too much emphasis on non-close()-related hits for "Inappropriate ioctl".
I am pretty sure you are correct with the 32/64 bit mode idea. We had this issue a couple of years ago working on an embedded device, the error was stemming from a lib that we were using to talk to a pci switch and the library did not support 64 bit ioctls.
My suggestion if you really want to get to the bottom of it and I have used this technique to debug jni code. Set a break point in the java app, then use gdb to attach to the process. You can then set a break point in gdb to watch for the ioctl on the device. See which request is being sent to the device and verify that it is correctly support for that architecture.
If fileoutput stream is reading from a filesystem file and not another type of device file. Then this is probably a problem with selinux, or some kind of virtualization like a chroot environment as in the following link.
This link may point in the right direction. It was a problem with the chroot
http://us.generation-nt.com/answer/sndctl-tmr-timebase-tcgets-help-170073041.html
Also definitely check the jre they are running, is it openjdk or is it sun java? I have had some very odd quirks with the older gcc jdk java and this may explain some of the discrepancies.