JRuby class loader by example


Everybody knows that JRuby lets us to load java jar files using require, but it seems that just a few people know that there are two other methods to do it and how they work under the hood. Our new and shiny wiki page includes a couple of examples but let me go further anyway.

As I said, the first method to load java classes into our ruby application is require. It works like it does with any ruby file but with jar files, so if we invoke a code like this we’ll end up with a bunch of java classes loaded:

This method, just lets us to load jar files, it doesn’t work with java class directories, though.

The second strategy to load java classes is using the variable $CLASSPATH. It behaves exactly like $LOADPATH so we can append or remove paths from the list. The advantage of this strategy is that it also allows to load directories that contain java classes, so these calls are completely valid:

If we wanted to digg into both methods, require and $CLASSPATH, we’ll find out that at the end when we use require we are actually adding our library to the $CLASSPATH:

The third method is for sure the most unknown but it’s actually where everything ends. When we use JRuby one of the constants that we have accessible is JRuby. This constant, among other things, lets us to reach the runtime itself with JRuby.runtime and from here we also have available the java class loader that JRuby uses, JRuby.runtime.jruby_class_loader.

The JRuby class loader also lets us to load jar files and class directories but it’s a little bit harder to do it:

If this time we take a look at the JRuby source code itself, we’ll discover that when we append something to the $CLASSPATH variable we are actually adding it to the JRuby class loader:

So now, the question is which one we have to use. For the day to day the best option is require. Most of the java code we are going to deal with is packed as jar files, and it has a syntax well known. If we need to work with class directories too or we have any other special case, probably our best option is $CLASSPATH. It gives us what we need, we don’t have to deal with urls and java idioms, and it’s still a syntax that we know. And finally, I’d leave the third option for cases when we need to work with the class loader explicitily. For instance, I use this option in Trinidad because each one of the deployed applications can include their own jar files, so this option lets me create new class loaders for each application and ensure they are completely isolated.

blog comments powered by Disqus