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.
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.
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.
Groovy vs. JRuby
Let’s compare the following aspects of the languages: Maturity, Language Features, Killer Libs, Interop with Java, Performance, and Tools.
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).
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.
There are some really fantastic technologies built on top of Groovy.
- Grails. Web application framework.
- Griffon. A Grails-like rich-application platform.
- Spock. Testing framework.
- Gradle. An enterprise automation tool.
- Geb. Browser automation tool.
Being a Ruby implementation, JRuby gives you access to all the goodness created by the Ruby community.
- Rails. Web application framework.
- Sinatra. Web application framework.
- RSpec. A state-of-the-art BDD framework.
- Rake. A software task management tool.
- Bundler. A dependency management tool.
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.
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.