jruby from inside out - arguments


posted by qmx on 30 November 2010
http://www.flickr.com/photos/orbitaljoe/4038901965/sizes/s/in/photostream/

Have you ever wondered how JVM-based languages work? Any clues on how can they be so fast? What are the tricks used to keep integration away from all the noise behind the scenes?

In my studies on jruby’s architecture, I’ve found so many smart solutions, that was almost impossible to miss the opportunity to share and explain how these things work.

When we call a java method, we can pass ruby objects as arguments. But how those types get resolved?

Suppose I have a method doIt at a simple java class:

public class DumbTaskExecutor {
    public void doIt(Runnable task) {
        ...
    }
}

here in ruby, I get a new instance of DumbTaskExecutor

require ‘java’

task_executor = Java::DumbTaskExecutor.new

task_executor.do_it(????)

What can I pass to this method? How to make a Runnable on ruby? Our solution lies on ruby’s duck typing:

The Runnable interface has just one method on it:

public interface Runnable {
    public void run();
}

So, in an ideal world we would do this:

class MyTask
    def run
        puts ‘done’
    end
end

Is this MyTask class a Runnable? Even if it hasn’t referenced Runnable, it responds to ‘run’ message. The big deal is that with duck typing, the class’s interface is composed solely of what this class knows how to do.

Then we can do this easily:

task_executor.do_it(MyTask.new)

What happens inside is a true masterpiece. JRuby takes this steps:

  1. introspects the java method looking for what are the arguments types
  2. generate a wrapper class on runtime that implements the given types
  3. delegate all the calls to the ruby object. To avoid infinite class generation, it has a very smart cache of generated classes, that will try to reuse this generated wrappers, by giving them hashcode-based names.

The result is that these calls have minimum overhead (despite class generation), and can be optimized by JVM’s JIT.

What do you think about this? Want to know about a specific topic about jruby? ping me on comments ;)