Ok, I finally managed to look at what's happening here. And I don't know how to fix it. Here's the sequence of events:
- new is called on the Ruby subclass of a Java type
- new for a Ruby/Java subclass does two things internally:
- first, construct the Ruby wrapper object; this calls initialize on the Ruby-land code. If super is called, the Java constructor also eventually gets invoked.
- then, if it hasn't already been constructed, construct the actual Java object by invoking its constructor
- After the Java object gets constructed, it is set into the Ruby wrapper, and the Ruby wrapper is set into it. This completes the construction process, enabling bidirectional calling to work correctly.
The problem, I believe, is that because the constructor gets invoked before the wrapper/object association is "complete", the "early" constructor invocation ends up in Java-land trying to invoke a Ruby-implemented method without all the pieces in the right place. So if Ruby to Java to Ruby depends on the wrapper/object relationship already being set, and that relationship depends on the Java constructor completing, invoking Ruby-implemented methods from a Java constructor can't work right.
At the moment I don't see that this is a reconcilable problem, because with two constructor chains one of them has to complete first, which means one side always has the potential to invoke methods before the other side is ready. Once we move JRuby toward passing Object everywhere we will be able to work around this (since the Ruby subclass will just be a Java subclass), but until then I think we're stuck.
Workaround would be to provide an intermediate class that implements the abstract method...or don't call the abstract method in the constructor.
Marking for 1.2, the current target for "big changes" in JRuby.