Please refer to bug: https://jira.codehaus.org/browse/JRUBY-6705
I reduced this bug to the following code snippet. My comments and questions follow this snippet -------------------------------------------------------------------------------------- class Object def self.const_missing(*args) puts "in const_missing! #{args.inspect}" raise "this_will_get_lost!" rescue Exception => e puts "Got exception: #{e}" end end begin raise "will_not_get_lost_1" rescue Exception => e puts "Got exception: #{e}" end defined?(Foo::Bar) begin raise "will_not_get_lost_2" rescue Exception => e puts "Got exception: #{e}" end -------------------------------------------------------------------------------------- If you run this on 1.7 master, you will notice that the exception within const_missing will not be printed out in the rescue handler. But, if you revert my commit "20632af6e1fa511fd9b762beda2a60d39bf3c859", this code snippet will work as expected (unrelated observation: in -X+C mode, the const_missing method doesn't run in either case). I think my fixes in that commit are "correct" and are in the right direction. I dont think the hacky $! set should be around in the interpreter or compiler (AST or IR). Those checks were working around lost sets of "$!" when exceptions were being raised. I traced one of the instances to RubyThread and fixed it. But, as part of this bug report, I found a more important one -- where $! was not being set by any code that runs as part of an ancestor defined? call in the call stack. This bug is caused by the check on line 239 of org.jruby.exceptions.RaiseException.java. So, I wanted to check if someone knows more about why $! setting is being suppressed when in defined? code. Clearly, the interpreter/compiler hack that sets $! to the received exception essentially gets around that check. So, it looks like a different solution should be possible -- I haven't yet attempted to get rid of the check in RaiseException.java and see what happens ... but, before I did that, I thought I would check first. Subbu.