I committed an update to my fix for JRUBY-5114. Originally I had hoped we could get away with never autoclosing streams, since users SHOULD be closing them manually and not leaving them for GC to clean up. However, that behavior is expected by so many Ruby users, I backed off on that change.
Instead, all IO objects now have an "autoclose" flag, just like Ruby 1.9.2 does (and obviously, we'd have needed it for 1.9 support anyway). All IO objects (with a couple exceptions, below) will default to autoclose=true, meaning that when they finalize, they'll attempt to close their associated stream (if other IOs hold references to the same stream, it will remain open until they finalize or close too). Setting autoclose=false disables the close-on-finalize behavior, leaving IO channels floating. The ultimate cause of JRUBY-5114 was the fact that all IO objects autoclosed, even those wrapping streams/channels "adopted" from other parts of the JVM. The servlet engine would give JRuby a servlet stream to process a POST request, we'd wrap it in an IO and do some basic operations, and then we'd dereference it. That would frequently cause it to GC, finalize, and close before the servlet engine had a chance to flush and close it itself, resulting in the EBADF and 500 errors many of you have seen. jruby-rack and other libraries that integrate JRuby with externally-sourced IO streams/channels will need to use autoclose=false to avoid our IO objects damaging streams coming from outside. Alternatively, you can do what I believe the Torquebox guys did...wrap the stream in a pseudo-stream that has a stubbed-out dummy "close" method. Either way, because of Ruby semantics, Ruby IO objects will autoclose on finalize by default...so you need to tell it not to. We probably want to mark all paths that construct RubyIO objects with CLEARLY STATED javadoc indicating that you're handing the stream off and it will be autoclosed. It may also be useful to add some Java APIs so you can create new IO wrappers without autoclose defaulting to true. To that end, I've modified some of our Java extensions: InputStream#to_io, OutputStream#to_io, and Channel#to_io now accept hash args :autoclose = (true|false), so when coercing a Java stream or channel to an IO from Ruby you can disable autoclose at the same time. I have also made IO#autoclose and IO#autoclose= methods available in 1.8 mode, since without them it's difficult to disable autoclosing from Ruby. RubyIO itself has isAutoclose() and setAutoclose() Java methods, as you'd expect. Thanks for your patience, folks. - Charlie --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email