http://www.developer.com/

Back to article

JRuby: Java and Ruby Together at Last


October 26, 2006

Ruby is the programming language on the tip of everyone's tongue these days. The power and ease of software development with Ruby has catapulted web frameworks such as Ruby on Rails into the forefront of web application development. Over the last 10 years, Java has grown to become the leading object-oriented software development language and runs on a multitude of platforms. JRuby is a 100% pure Java implementation of the Ruby programming language. This article gives an overview of JRuby and shows how it leverages the Java language to bring Java developers a fast and powerful alternative for creating application solutions.

Ruby: The Scripting Language that is Taking the Computing World by Storm

It is hard to imagine anyone in the programming world these days who has not heard of Ruby. The ever-increasing popularity of the Ruby on Rails web framework is helping make Ruby the language of choice for rapid application development and testing. Ruby is an interpreted scripting language that provides quick and easy object-oriented programming and contains some neat features such as closures, blocks, and mixins. Ruby is also highly portable, running on Unix/Linux, Windows, and MacOS. For those wanting a more thorough introduction to Ruby, you can read W. Jason Gilmore's article on Ruby.

Java: The Object Oriented Language with 10 Years Under Its Belt

Java was created in the early 1990s by James Gosling at Sun Microsystems. Gosling aimed to provide a virtual machine and a C-style notation language with greater uniformity and simplicity than C/C++. Another major goal of Java was to provide a "Write Once Run Anywhere" (WORA) paradigm, allowing a program to be written on one platform and run on another platform without recompilation to the target platform. The Java platform consists of a Java Runtime Environment and Java Software Development Kits (SDKs). Java now provides SDKs for platforms ranging from mobile devices to enterprise systems with its Java SE, EE, and ME technology stacks. Over the last 10 years, Java has been used on mobile devices, kiosks, web applications, financial systems, and real-time systems.

JRuby: Ruby on the Java Virtual Machine (JVM)

JRuby is a 100% pure implementation of the Ruby language, released under a tri-license of CPL, GPL, and LGPL. It is a 1.8.4 Ruby interpreter, with most of the Ruby built-in classes provided. JRuby supports interacting with and defining Java classes from within a Ruby program as well as Bean Scripting Framework support. The current version as of this writing is JRuby 0.9.1. JRuby provides Ruby programs with access to Java classes, allowing them to be used as first-class objects within them. JRuby's creators, Thomas Enebo and Charles Nutter, have been hired by Sun to work on JRuby full time.

Running Your First JRuby Program

The JRuby distribution comes as a tar.gz file. For this article, I worked on a Windows-based system using the jruby-bin-0.9.1.tar.gz binary distribution of JRuby and Java SE version 1.5.0_06. After uncompressing the distribution, I ended up with a jruby-0.9.1 folder that contained subfolders: bin, docs, lib, and samples. You can add a JRUBY_HOME environment variable pointing to this directory and then add the %JRUBY_HOME%bin ($JRUBY_HOMEbin on UNIX) to your system PATH. The JRuby distribution's bin directory contains the jruby.bat file that is used to run the JRuby interpreter. Run the command jruby –version from the command line to test that the JRuby is working:

C:JRubyjruby-0.9.1>jruby -version
ruby 1.8.5 (0) [java]

In the samples directory of the distribution, you will find some sample Ruby programs that exhibit the functionality of JRuby. As a first example, look at the java2.rb sample. This sample contains the following Ruby code:

require "java"

filename = "./samples/java2.rb"
fr = java.io.FileReader.new filename
br = java.io.BufferedReader.new fr

s = br.readLine
print "------ ", filename, "------n"

while s
   puts s.to_s
   s = br.readLine
end

print "------ ", filename, " end ------n";
br.close

The first line enables JRuby's Java support and allows a Ruby program to use Java classes.

The program defines a java.io.FileReader pointing to the file "./samples/java2.rb". It then declares a java.io.BufferedReader that buffers the data read via the FileReader. The program reads all the lines from the file and prints them to the console. Here is the result of running this Ruby script with JRuby:

C:JRubyjruby-0.9.1>jruby .samplesjava2.rb
------ ./samples/java2.rb------
require "java"

filename = "./samples/java2.rb"
fr = java.io.FileReader.new filename
br = java.io.BufferedReader.new fr

s = br.readLine

print "------ ", filename, "------n"

while s
   puts s.to_s
   s = br.readLine
end

print "------ ", filename, " end ------n";

br.close
------ ./samples/java2.rb end ------

C:JRubyjruby-0.9.1>

So, you have used JRuby to run a Ruby script that reads a file using Java classes and prints it out. This is a powerful concept that JRuby now brings to Ruby users.

Using Java Classes in JRuby (Name Clashes Included)

Now that you have run a sample, take a look at ways that JRuby allows Ruby programs to use Java classes. The most important method that JRuby provides is the Kernel#include_class method. This method is used to allow Ruby to use that Java class as is:

require "java"
# Include Java's FileReader
include_class "java.io.FileReader"

filename = "./samples/java2.rb"
fr = FileReader.new filename

However, there can be name clashes between Java class names and Ruby class names. String is an example of this; Java has java.util.String and Ruby also has Kernel::String. To resolve this name clash, you can rename the class while including it by passing a code block to the include_class method call:

require "java"
# Include Java's String as JString
include_class("java.lang.String") { |package, name| "J" + name }

s = JString.new("Hello World from JRuby!")
puts s

By defining a Ruby module that includes the Java class definitions, you also can avoid this name clash:

require "java"
module JavaLang
   include_package "java.lang"
end

s = JavaLang::String.new("Hello World from JRuby!")
puts s

Here is a sample program, javaHello.rb, that uses Java's HashMap to store three strings and print them out. The interesting thing about this program is the fact that it invokes the the Ruby 'each' method on the java.util.Set returned by the java.util.HashMap.keySet() method call. This allows the resulting keys returned by the 'each' method to be passed to the code block, which gets the String stored with that key, and print that String.

require "java"

module JavaLang
   include_package "java.lang"
end

include_class("java.util.HashMap") { |pkg, name| "J" + name }

s = JavaLang::StringBuffer.new("Hello Java World")

puts s.append(", I love JRuby")

m = JHashMap.new()

m.put("java", "Java")
m.put("ruby", "Ruby")
m.put("jruby", "JRuby")

puts m

m.keySet().each { |key| puts m.get(key) }

Here is the output when it is run with JRuby:

C:\JRuby>jruby javaHello.rb
Hello Java World, I love JRuby
{java=Java, ruby=Ruby, jruby=JRuby}
Java
Ruby
JRuby

C:\JRuby>

A similar program written entirely in Java would look like this:

StringBuffer s = new StringBuffer("Hello Java World");
s.append(", I love JRuby");
HashMap<String> m = new HashMap<String>();
m.put("java", "Java")
m.put("ruby", "Ruby")
m.put("jruby", "JRuby")
for (String key: m.keySet()) {
   println(m.get(key));
}

How About Swing in JRuby?

Swing is a GUI framework that allows developers to create graphical applications using the Java language. Here is a sample program, javaSwingHello.rb, which uses Java Swing to print a message:

require 'java'

include_class "javax.swing.JFrame"
include_class "javax.swing.JLabel"

frame  = JFrame.new()
jlabel = JLabel.new("Hello from JRuby with Swing")
frame.getContentPane().add(jlabel)
# frame.content_pane.add(label)
frame.pack()
frame.setVisible(true)

frame.visible = true

Run this from the command line as follows:

C:\JRuby>jruby javaSwingHello.rb

A new window will appear with the text "Hello from JRuby with Swing":

Conclusion

This article has provided a brief introduction to the JRuby language. JRuby should allow existing Java developers to leverage Ruby's power and ease of programming. Ruby developers will be exposed to the vast Java libraries that have made Java extensively used throughout the software development spectrum. With backing from Sun, JRuby looks to have a bright future. Take some time to look further into JRuby and see what all it has to offer you.

References

About the Author

Dominic Da Silva (http://www.dominicdasilva.com/) is the President of SilvaSoft, Inc., a software consulting company specializing Java-, Ruby-, and .NET-based web and web services development. He has worked with Java since 2000 and is a Linux user from the 1.0 days. He also is Sun Certified for the Java 2 platform. Born on the beautiful Caribbean island of Trinidad and Tobago, he now makes his home in sunny Orlando, Florida.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date