Going Dynamic on JVM: JRuby vs. Groovy

JVM is awesome!

Many people that bash Java make the mistake of mixing up the Java language and the Java platform. Sure, the Java language is verbose; it lacks closures, mixins, etc. But the JVM is freaking awesome. It’s blazing fast, it runs everywhere, has multiple garbage collectors, has native threads and great monitoring tools. As a result, you may still want to run your server-side applications on the JVM. The best part is that you don’t have to use the Java language. If you are a fan of dynamic languages, there are lots of available options. The most mature ones are JRuby and Groovy. If you are asking yourself, “Should I pick Groovy or JRuby,” read this post and, hopefully, you will be able to make the decision.

Groovy

Groovy Logo

Let’s start with Groovy. Groovy is a dynamic language designed for the Java Virtual Machine. It takes a lot of ideas from such languages as Ruby and Python (and adds a few its own) and wraps them in a Java-like syntax. Being designed for the JVM Groovy has a few advantages over ported languages. One of them is seamless interoperability with the Java language (both Groovy to Java and Java to Groovy). However, in order to make it closer to Java, the designers of the language had to make some compromises. For instance, Groovy uses getters and setters to define properties.

Groovy Home Page

JRuby

JRuby Logo

It’s an implementation of the Ruby language on top of the JVM. Therefore, the coolest thing in JRuby is the fact it’s Ruby. This means that you can use all the goodness of the Ruby platform on the JVM. It’s not only Rails. Rubyists have developed a lot of really cool stuff, and the ability to use all these libraries rocks. However, there is a downside. JRuby’s interop with Java is not as smooth as Groovy’s.

JRuby Home Page

Groovy vs. JRuby

Let’s compare the following aspects of the languages: Maturity, Language Features, Killer Libs, Interop with Java, Performance, and Tools.

Maturity

The JRuby project celebrated its 10-year anniversary last year. It supports Ruby 1.8 and 1.9. Most gems work with JRuby without any problems. Those that don’t work have analogs written in Java (for example, Nokogiri Java). There are a few cloud solutions supporting JRuby and several robust application servers. It’s by far the fastest Ruby implementation. I think JRuby is gaining momentum right now. People are talking and writing about advantages of JRuby over MRI everywhere. It’s used in production in a lot of companies (e.g., LinkedIn and Square).

The Groovy project was started up in 2003. It became stable in 2008. In the very beginning it was used primarily as a scripting language for the Java platform, but over the last couple of years its ecosystem has really matured. A lot of idiomatic Groovy libraries (e.g., Spork, Geb, and Gradle) have come out. There are cloud deployment options for Groovy as well. Groovy is used in many companies that have existing Java infrastructure (for example Netflix).

Language Features

Since Groovy was in many ways inspired by Ruby, both languages are very similar. The emphasis though is different. Groovy has optional typing and interfaces and it’s structured more like Java, which makes it more static than Ruby. One of these “more static” features differentiating Groovy from other dynamically typed languages is compile-time metaprogramming. In Groovy you can write extensions to the compiler that will change the semantics of the language. It opens up plenty of options for implementing cool Domain Specific Languages. Spock, the testing framework, is a good example:

Similar JUnit test would look like:

It’s important to point out that Groovy does not support the ‘expect:’ and ‘where:’ keywords out of the box. Spock extends the Groovy compiler to change the execution flow of your tests. Awesome!

JRuby (or it’s better to say Ruby) has lots of nice features for writing DSLs as well. For example, the fact that class bodies are executable enables you to write some really interesting DSLs:

Overall, I find myself writing more dynamic code in Ruby that I would do in Groovy. For instance, I can generate classes on the fly:

It’s possible to write similar code in Groovy, but it’s not as elegant.

Killer Libs

There are some really fantastic technologies built on top of Groovy.

Being a Ruby implementation, JRuby gives you access to all the goodness created by the Ruby community.

Interop with Java

Using web services and message queues is a right way to integrate a new system into existing infrastructure. However, sometimes it’s impossible and you have to perform an object-level integration. Being designed for the JVM, Groovy does a better job here. It seamlessly integrates with Java. Groovy calls Java, Java calls Groovy. It just works. Ruby, on the other hand, has a different object model, different naming conventions. There is no such thing as an interface in Ruby. In addition, the libraries are different as well. Even though the JRuby team did an amazing job making this integration as smooth as possible, it’s not even close to what Groovy does.

Performance

I’m not going to show you charts. And no, I’m not going to tell you which language is faster. Why? It’s not important. You should not make your decision based on the fact that one of them is 10% faster than another one. JRuby and Groovy are slower than Java. There is nothing you can do about it. But this is all right, because they are fast enough (and they are going to be much faster after they utilize InvokeDynamic). If somehow you run into a situation when they are not, switching from JRuby to Groovy (and vice versa) won’t make the situation better. Just rewrite that class in Java and integrate it with the rest of your application.

Tools (IDEs and Text Editors)

Both languages are supported by all major text editors: Vim, Emacs, TextMate, Sublime. If you prefer IDEs, there are plugins for Eclipse, NetBeans, and IntelliJ IDEA (RubyMine). I personally prefer IntelliJ IDEA and RubyMine.

So Groovy or JRuby?

Hopefully, by now you have some idea of the pros and cons. If after weighing them up you are still not sure, here is some advice I can give you based on my own experience.

  • You are working with a large Java code base. The new module you’re planning to write will extensively interact with the existing Java code. Groovy is your choice. There is no other language on the JVM having such a seamless integration with Java.
  • You are working in a Java shop and your team consists of experienced Java developers, who are not really familiar with dynamically typed languages such as Smalltalk or Python. Again, choose Groovy. It has optional typing and interfaces. Besides, your team will be able to use existing tools and libraries. I would not say that it feels like Java, but it’s definitely an easier switch.
  • You and your team can invest a little bit more time into learning new skills. Existing infrastructure can be isolated from the new module you’re going to build by an anti-corruption layer. Maybe you are building a web app or a REST web service. Try JRuby. The Rails ecosystem is fantastic. I believe it’s the best full-stack solution for building web apps right now.
  • Your team has experience with other dynamically typed languages such as PHP, Python or Smalltalk. Go for JRuby.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Gorton

    You say “For instance, Groovy uses getters and setters to define properties”. How else could Java seamlessly interop with Groovy classes otherwise?

    As it is, you do not need to use getters and setters within a Groovy class, just dot notation.

    • http://victorsavkin.com Victor Savkin

      Thanks for your comment. That’s exactly my point. To achieve seamless interop with Java you have to make some compromises, and using getters and setters is one of them.

      You’re right saying that it’s possible to define and access properties without using getters and setters. However, getters and setters are still there, and it makes the runtime model more complicated. For example:

      class MyClass {
      def methodMissing(String name, args){
      println(“method ” + name)
      }

      def propertyMissing(String name){
      println(“property ” + name)
      }
      }

      def c = new MyClass()
      p.name // will print “property name”
      p.getName() // will print “method getName”

      “getName” is a method, but also a property. This duality confuses everyone who haven’t had any experience with Java.

      Cheers,
      Victor

  • http://dockyard.com Brian Cardarella

    The Boston Ruby Group is having a night on JRuby on June 12th for those in the Boston area that would like to lear more: http://bostonrb.org

  • http://crazy4groovy.blogspot.com Crazy4Groovy

    I just love the paragraph about Performance. Well said!! :)

  • Stephen Boesch

    JRuby more mature than Scala?? Not by a long shot. Wondering why Scala (and maybe Clojure as well) fell off the radar on this article. At the least an explanation of why the author chose not to include them would be helpful.

    Scala is written by Martin Oderskey ( original author of java generics and the JIT compiler) and has been endorsed by none other than the author of Groovy (look it up).

    • http://victorsavkin.com Victor Savkin

      Scala wasn’t included because it’s a statically typed language, and the article is about dynamically typed languages.
      Clojure, on the other hand, is dynamically typed, but it’s a completely different beast and comparing it to, for example, Groovy is a little bit weird.

      Cheers,
      Victor

  • van Geir

    You gave 4 scenarios in your summary:

    1. You are working with a large Java code base. The new module you’re planning to write will extensively interact with the existing Java code. Groovy is your choice

    2. You are working in a Java shop and your team consists of experienced Java developers, who are not really familiar with dynamically typed languages [...] choose Groovy

    3. You and your team can invest a little bit more time into learning new skills. [...] Try JRuby

    4. Your team has experience with other dynamically typed languages such as PHP, Python or Smalltalk. Go for JRuby.

    For option 1, I’d suggest more Java. Groovy has just introduced a statically-compiled mode in v 2.0, and is aiming to take over Java’s domain. Based on closely watching Groovy’s development process over the past 6 years, I’m guessing they’ll focus less on fixing Java compatibility bugs in their dynamic codebase, nudging users over to the newer static-compilation codebase.

    And really, just how common is option 2 ? Options 3 and 4 are far more frequent in industry.

    • Anthony

      Actually, much more common than you’d think.
      At work, we have grizzled Java consultants working with us who know the ins-and-outs of Java, but dynamic langs? Not so much.

      I frankly don’t see the argument for JRuby in 3 & 4 though. If you have the time to invest in new skills, or your team has experience in dynamic langs, why not learn Groovy, the language that provides a completely seamless integration with your Java code, and does not need an “anti-corruption” layer?

      IMO, there are only 2 scenarios where you should consider JRuby over Groovy.
      1) Your team uses Java, but you need/want to use a Ruby library
      2) Your team uses Ruby, and you want to migrate from MRI to get the JVM’s awesomeness (and if you don’t want to migrate from MRI, you have bigger problems…)
      In any other scenario, for a Java shop considering adding support for a dynamic language, go Groovy for a better experience.

  • http://xprogramsfixed1.wordpress.com Brendan

    Excellent web site you have got here.. It’s hard to find quality writing like yours nowadays. I truly appreciate people like you! Take care!!