Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

Open Source

Language of the Month: JRuby

Stealing the Right Tools from Other Languages

Maybe you've already heard this advice: Choose the right tool for the job.

JRuby brings new scope to tis idea. The Java tooling ecosystem is huge, and JRuby gives you the opportunity to add that ecosystem to your toolbox, while still keeping those nice Ruby idioms that you already know. JRuby adds new capabilities to the require method that enable it to load desired Java libraries using their path:

	require 'clojure.jar'
	java_import 'clojure.lang.PersistentHashMap'
map = PersistentHashMap.create(:a => 1, :b => 2)

In this example, you can see how we loaded the Clojure core library and used one of its hashes specialization. JRuby uses a global variable called $CLASSPATH to store the routes to these new libraries, so they are not mixed with the Ruby load path:

jruby-1.6.5 :001 > require 'clojure.jar'

	jruby-1.6.5 :002 > $LOAD_PATH
	=> ["."]
	jruby-1.6.5 :003 > $CLASSPATH
	=> ["file:/Users/david/clojure.jar"]

This environment variable, of course, acts like any other array, so you can also manipulate it from your code:

jruby-1.6.5 :003 > $CLASSPATH << './tomcat.jar'
	=> ["file:/Users/david/clojure.jar", "./tomcat.jar"]

However, the task of managing external dependencies on our own can be tedious and rather complicated when our application starts to grow. Maven is the default dependencies management tool for Java, and JRuby integrates it to make your life easier when you want to use Java tools. If you have Maven set in your path, you'll also be able to install Java libraries as Ruby gems from any Maven repository.

In the previous example, we needed to download the Clojure library and add it to our application. With this integration, we can install it as a Ruby gem, as shown in the example below. The name of our new gem is composed of the prefix mvn followed by the name of the java package (in this case, org.clojure) and followed by the name of the package (clojure), with everything separated by a colon.

$ gem install mvn:org.clojure:clojure
Successfully installed mvn:org.clojure:clojure-1.4.0.a.2-java
1 gem installed

Then, you just need to require your new gem in your program:

	require 'rubygems'
	require 'mvn:org.clojure:clojure'
	java_import 'clojure.lang.PersistentHashMap'
map = PersistentHashMap.create(:a => 1, :b => 2)

Fortunately, some Java libraries have already been packaged to work in the Ruby world. In the next section, I'll discuss some examples of how well-known Java tools can be integrated and used by our Ruby applications.

Further Integration With Java Tools

Ruby on Rails is one of the reasons for the success of Ruby as a programming language. But for years, the framework and its environment lacked something that the Java community had owned for decades: high-performing and fully featured application servers. With the arrival of JRuby, the door was opened to bring those application servers to the Ruby world.

This is the case, for instance, with Trinidad, an OSS project I work on. It's a Ruby application server built on top of Apache Tomcat. Trinidad is available as a Ruby gem and bundled with a light version of Apache Tomcat. Trinidad started as an internal project in an environment that mixed Ruby and Java web development, and it is open source. Given this mixed heritage, it was designed to support hybrid environments where both languages work together without losing the simplicity that other well-known Ruby servers had already shown.

Following these principles, it had to be easy to install and execute. After downloading the gem, you can run Trinidad directly from the application's path:

$ cd your_web_application
	$ jruby -S trinidad

Or add it to the bundler file and run it after loading all the application's dependencies:

source :rubygems
gem 'trinidad'

$ cd your_web_application
	$ bundle exec trinidad

Behind this, a fully featured server is hidden, and anyone should be able to customize and configure it. Rather than exposing the user to complicated configuration files written in plain XML, Trinidad offers a Ruby DSL to access those features:

Trinidad.configure do |config|
	 config.port = 4000
	 config.http = { :maxThreads => 200 }

Trinidad is only one of many projects developed because of JRuby. Torquebox is another adaptation of a full-featured Java server (JBoss) that brings a whole ecosystem of Java tools to the Ruby world. Redcar is a multiplatform text editor based on JRuby that uses Java graphic libraries and well-known frameworks such as Lucene under the hood. It's written in pure Ruby. There are several other projects that have taken advantage of the best parts of both platforms.

Present and Future

JRuby has become a mature and stable project during last 10 years. In that time, it has evolved into a first-class Ruby implementation. JRuby 1.7 is around the corner. It's going to be the first major version released after Java 7, and it will include support for the new invokedynamic instruction added to the JVM. 

Whether you need a high-performance Ruby, better tools for your day-to-day work and your production systems, or you're just comfortable with the Java ecosystem, you should consider using JRuby.

David Calavera is a member of the JRuby Core Team, the lead developer of Trinidad, and contributor to many other open source projects. He works at Engine Yard as a developer.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.