« Recursive git: rgitRails 2.2 localization and gettext »

Why I'm starting to like JRuby even though I dislike Java

Permalink Posted by Andreas Email on September 26, 2008 at 11:36 pm. Categories: Ruby on Rails

Among my friends, it's not a secret that I personally don't like Java. During my time at the university, I had to deal with it for some courses, but somehow nobody could convince me to really like the language. With Ruby, it was the exact opposite - I saw a few code examples, read some articles about it and I immediately started to like the language and its charming way of doing OO like I always wanted it to be.

When I discovered JRuby, I therefore didn't take it serious and overlooked its potential. Today, I'm starting to like JRuby. Why? Because JRuby is actually pretty cool. It runs code of my favorite language (Ruby) on a wide-spread and highly optimized platform (the Java Virtual Machine, aka JVM). You can use JRuby to run Ruby code without even knowing a single bit about Java - but it runs on the JVM (which has several advantages as stated below).

Follow up:

Java actually consists of two different parts. On the one hand, there's the Java compiler that reads programs written in the Java language and translates them to bytecode - and on the other hand, there's the Java Virtual Machine that executes bytecode. But the JVM doesn't only run Java programs - actually there are several compilers that translate various programming languages into bytecode that runs on a JVM - amongst them is JRuby which compiles my favorite programming language into bytecode for a JVM.

Interestingly, JRuby seems to have hard times getting accepted in the Ruby community. Charles Nutter from the JRuby team recently told how he experienced hate and anger against JRuby in the Ruby community - in contrary to the Python community, where Jython is very appreciated. That's kind of strange, since even Matz seems to like JRuby. I have to admit that I also found JRuby uninteresting at first. I didn't hate it, I just (to quote Charles) "... found it interesting ... for Java developers". Today, I'm starting to like JRuby, and here's why:

JRuby advantages

JVM runtime optimization

The Java VM is a runtime environment that has been worked on for years now and can be considered very stable and mature. It does pretty cool stuff to optimize the runtime execution of bytecode. There are two execution modes: In -client mode (which is the default), the program startup time and memory usage is minimized (which is good for a local application or an applet, since you usually want to bring it up fast if you start it). The other mode -server optimizes for runtime speed; an application takes more time to start up and needs more memory in this mode, but it runs slightly faster. The JVM can even dynamically optimize the bytecode during runtime (e.g. optimize inner loops). Therefore, a server application becomes faster after a while, once the JVM has "warmed up". Compared to the original Ruby (also called MRI), JRuby runs faster, but needs more memory.

Memory usage

The memory usage of a single instance of a Ruby application is higher in JRuby if compared to original Ruby. However, this drawback disappears if you run multiple application instances (like multiple mongrels on a production server). JRuby can run multiple instances of an application in a single JVM (e.g. with jrubysrv). This way, memory can be shared between application instances so that e.g. the Rails framework is only kept in memory once. I don't have any practical experience with this topic, but JRuby is told to be more memory efficient especially when running many smaller applications on a single server.

Native Threads

JRuby has real native threads so you can easily spread work on multiple processor cores. And with upcoming thread-safe Rails 2.2, it'll greatly reduce the memory usage of a Rails application.

Garbage collection

The JVM is told to have a great garbage collection, making memory usage more efficient. (However, I don't have any experience on this topic yet).

JIT and AOT compilation

We all love open source software, but to be honest, sometimes there are situations in business where you cannot or don't want to give out the source (no, I don't want to hide my bad coding style... it's just that most companies aren't happy with publishing sources). Using ahead-of-time (AOT) compilation, an application can be compiled into bytecode and can therefore be shared without exposing the source.

Integration with Java libraries

From JRuby, you can use other Java libraries and vice-versa. This one is mostly unimportant to me, since I don't use/know Java libraries, but this feature probably is very attractive to Java programmers who want to switch to Ruby.

Running Rails applications on existing Java application servers

Using Warbler, a Rails application can easily be packed into a .WAR file, which is the default archive format for a Java web application. Warbler packs the Rails application, all required gems, the JRuby library and a little wrapper plus the required metadata into a .WAR file. This way, the resulting .WAR file can be easily deployed to an existing application server infrastructure. This compatibility certainly is attractive for people with existing java application servers.

Documentation and Specs

JRuby (amongst others) is told to bring the Ruby language a big step forward by helping to create a clear language documentation and language specs. The language itself was told to be not so well documented and MRI's release management is told to be kind of clumsy. (more on this in the Google talk about Rails scalability; again, I don't have personal experiences here).

JRuby disadvantages

Nothing comes without a price - so here are the JRuby disadvantages I found so far.

Larger memory footprint and startup time

A single JRuby instance needs more memory than a single Ruby instance, but in a typical production server environment with multiple mongrels, memory can be shared so that I expect a lower or at least equal memory usage in total. JRuby's startup time is higher than MRI, but once the JVM has "warmed up" after a few minutes, it usually runs faster than MRI.

No native C extension

Due to the nature of Java, it is impossible to run any native extension. So there are several gems that don't work since they rely on a C extension. However, there's ongoing effort to create alternative gems that are compatible to JRuby. E.g. mongrel uses a native C extension, but if you install the mongrel gem using JRuby, it automatically installs a java-enhanced version.

JRuby is not technically complete

It's told that there are cases where JRuby is not 100% compatible with MRI, however, I think these are very special cases; at least I didn't encounter any problems yet. Big Frameworks like Rails are tested with JRuby, so I currently don't expect any problems with it.

Conclusion

I'm starting to like JRuby and I think I'll use it in production for my next project to see myself how it works out. However, for development, I currently still use MRI since the long startup time of JRuby is kind of annoying during development.

Trackback address for this post

Trackback URL (right click and copy shortcut/link location)

15 comments

Comment from: Jason [Visitor]
****-
Does each new version of rails run automatically on jruby?

Or are there special considerations that need to be addressed first?
09/27/08 @ 05:25
Comment from: Richard [Visitor] · http://codediving.wordpress.com/
****-
Hi Andreas.
You mentioned the integration of Java libraries as the most important advantage of JRuby over MRI, which is my opinion too. For example I haven't seen a better user interface library yet than Eclipse's SWT. But when I thought of switching to JRuby I did not like to take the disadvantages only to gain access to Java libraries. So I started a new project called HybridRuby which allows me to connect both worlds of MRI and JRuby. The idea is to start JRuby in some kind of "server mode" and run your application itself with MRI. And when you try to access something that only JRuby can handle the calls are redirected to the JRuby server and the results are mirrored back. With this approach you can combine many advantages of both (e.g. you have nearly no startup time because JRuby is already running). I already got a sample application running which creates a SWT window and adds some widgets and more will follow. What do you think of this project? I will write more about it in my new blog soon.
09/28/08 @ 15:29
Comment from: Andreas [Member] Email
@Jason: I'm not completely sure if JRuby compatibility is an official feature of Rails, but I watched the commits in the Rails repository for a while now and from now and then it happens that something is reverted or changed because it would break Rails under JRuby - so there's definitely effort to keep it working. From what I know, there are only minor things to address in a Rails application, like checking compatibility of all used gems and checking the db connector (change the database.yml to use JDBC to connect to the db)

@Richard: personally I don't care about the integration with Java libs, since I still don't like to use them. However, it'll without doubt attract a lot of people. Your project HybridRuby sounds interesting, though I basically would prefer to have only one environment rather than two different mixed when I think about memory usage and maintenance work. However, there might be cases where one needs both. I'm curious to read more about it.

09/28/08 @ 16:32
Comment from: Richard [Visitor] · http://codediving.wordpress.com/
****-
Crap, I should read more carefully. You've written "unimportant" and I've read "important", maybe because it reflects my own opinion... And yes, running two environments consumes more resources, but I think the speed of new MRI versions will again outperform JRuby. So using MRI while still being able to access Java libraries is my preferred way to go. About the maintenance factor: I am trying to make HybridRuby as transparent as possible, so that theoretically any JRuby specific script which you run with "jruby script.rb" can also be run with "ruby -r hybrid_ruby script.rb". Or you can also switch the roles and run the script mainly in JRuby and only redirect calls to MRI-specific libraries (all these beautiful gems...). HybridRuby is pure Ruby code, so both server and client should work on every Ruby environment.
09/28/08 @ 17:23
Comment from: Mark Thomas [Visitor] Email · http://www.markthomas.org/
*****
If you use NetBeans as your IDE, you can eliminate the JRuby startup time. NetBeans is a great IDE for JRuby. In fact, it uses JRuby by default.
09/28/08 @ 19:48
Comment from: Huw Collingbourne [Visitor] · http://www.sapphiresteel.com
Bear in mind that our IDE for Visual Studio, Ruby In Steel Developer, also supports JRuby - including a fully integrated step+drill-down debugger.

best wishes
Huw
09/29/08 @ 11:27
Comment from: Andreas [Member] Email
Ruby 1.9 certainly is interesting - I haven't tried it much yet. I'm not sure if all compatibility issues in Rails are solved (I saw a lot of code changes related to 1.9 compatibility in Rails lately, so they're certainly working on it). Also there are Rubinious and Maglev which are promising fast VMs for Ruby (although not production ready yet).

I used NetBeans for some time, but I somehow switched to TextMate again. Maybe I should give it a try again - I really liked the quick documentation lookup and code references. Unfortunately, NetBeans has no Git integration yet (but there's ongoing effort to add Git support to NetBeans (www.nbgit.org))

09/29/08 @ 12:09
Comment from: Jeremy Leipzig [Visitor] · http://friendfeed.com/leipzig
****-
JRuby is very intriguing. I have been using Groovy recently and it has been a satisfying experience, but less so for Grails. If Grails does not catch up to Rails soon I would definitely consider JRuby on Rails for my next web platform. At any rate I think it's great that the Ruby people are interested in discarding all that verbose Java syntax without losing all the libraries that have been written in Java. This can only be a good thing.
09/29/08 @ 16:27
Comment from: Phil [Visitor] · http://technomancy.us
Interesting. For me far and away the biggest disadvantage is the startup time, since this destroys any momentum you build up while doing TDD; you totally lose your train of thought as you wait 10 seconds for your tests to tell you if things are working or not.
09/29/08 @ 23:10
Comment from: Andreas [Member] Email
Yes, startup time of JRuby is annoying during development, especially in small projects where the startup takes longer than tests itself. However, you can eleminate the startup time by using autotest, which needs to be started once and additionally only runs tests of changed code during the first pass, so you get test results as fast as possible. As Mark mentionend above, NetBeans also eleminates startup time since NetBeans itself is a Java application and probably runs JRuby without starting a new VM.

09/30/08 @ 15:08
Comment from: Dick Davies [Visitor] · http://number9.hellooperator.net/
****-
Good points. I'm an ex-Java guy and been glad to come back to the JVM with Ruby (if not the Java language). Would much rather be writing my extensions in Java than C anyway :)

One thing that's worth pointing out is that Warbler actually supports any Rack-based framework ; Camping, merb, Sinatra etc. should all work too.
10/01/08 @ 11:13
Comment from: ab5tract [Visitor]
While there are a few issues at the moment, JRuby can work with Nailgun, which is an app that runs a JVM as a server process. This means no spin-up at start-time, and your code will already be warmed up if you are running tests.

http://wiki.jruby.org/wiki/JRuby_with_Nailgun
10/01/08 @ 21:23
Comment from: Emmanuel Pirsch [Visitor] Email
****-
JRuby is becoming my main Ruby implementation. Besides the fact that I can run Rails application on any J2EE application server (which makes selling Rails a lot easier to many organizations), I can reuse libraries from a really large pool of availlable libraries. And these library are cross-platform so I do not need to worry about portability.

And when I need to acces native function, I can do that in a portable way using JNA. JNA is far supperior to any MRI alternative to access native shared libraries. It requires very little code (you basically just recreate the equivalent of a .h). If your native shared libraries has been ported to many platform, then you application stays portable.
10/03/08 @ 18:39
Comment from: Trevor [Visitor]
Typo: "it's charming way" --> "its charming way"
10/07/08 @ 15:51
Comment from: Andreas [Member] Email
Oops. Corrected. Thanks.
10/07/08 @ 18:22

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
PoorExcellent
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)

Search

Subscribe

Twitter

    Loading...

Latest articles

Contact me: zoojange@zargony.com epiduaso@zargony.com

powered by b2evolution free blog software