I can reproduce this with trunk r4889. The problem seems to be that since the underlying IOHandlers are closed by the java finalizer when they are garbage-collected, the ruby finalizer is throwing EBADF when it tries to close the already closed file:
/Users/rlynch/Development/Projects/ruby/jruby/trunk/jruby/lib/ruby/1.8/tempfile.rb:146:in `callback': Bad file descriptor (Errno::EBADF)
JRuby then gives up on running any other finalizers, leaving behind the tempfiles.
A couple of questions to answer in resolving this:
- Should JRuby be so aggressive about closing IOHandlers? Ruby provides the IO::open block syntax if you want to automatically close file descriptors at the end of the scope of the objects that open them. But JRuby automatically closes them whenever the IO objects fall out of scope, regardless of how they are instantiated. This bug is one example of the incompatibilities that could result, but any case where filenos are maintained separately from IO instances may see similar results – see also
JRUBY-1079, where sysopen allocates a fileno without returning an IO instance. Both of these problems could be resolved by making the ioHandlers hash hold hard references, thereby keeping the file descriptors open until global destruction, or until they are explicitly closed.
- Is this the correct behavior for finalizers at global destruction: Should an exception in one finalizer abort the execution of other finalizers?
Can you check this against JRuby 1.0.2 and 1.1b1?