Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training,
learning paths, books, tutorials, and more.

Chapter 1. Getting Started

Introduction

JRuby is an open source implementation of the Ruby programming
language for the Java Virtual Machine (JVM). It allows Ruby applications
to be run within a Java Virtual Machine and interface with libraries
written in either Java or Ruby. Although the JRuby project was initiated
in 2001, interest in JRuby has grown significantly over the last few
years, reflecting an overall growth in interest in Ruby sparked by the
success of the Ruby on Rails framework. Sun has contributed to JRuby’s
success by employing members of the core development team and providing
support for JRuby in the NetBeans development environment, among other
efforts. The website for the JRuby project is currently http://www.jruby.org.

Ruby

Ruby is a dynamic object-oriented programming language created
by Yukihiro Matsumoto, known by the nickname Matz, in the mid-1990s.
Ruby follows a style of versioning similar to the Linux kernel, where
an even minor version number indicates a stable release and an odd
minor version number indicates a development release. As a result,
there are two current versions of Ruby: 1.8.6,
released in March 2007, is the current stable release, and 1.9.0,
released in December 2007, is the current development release. The
standard Ruby interpreter[1] is written in C. There are several alternate implementations of the interpreter,
including JRuby, IronRuby (for Microsoft’s .NET framework), and
Rubinius. Ruby does not have a formal language specification;
however, one is being developed through the wiki at http://spec.ruby-doc.org.

As an object-orientated language, many of the underlying
concepts of Ruby will be familiar to Java developers, even if the
syntax is not. The biggest exception to this is Ruby’s support for
blocks. In Ruby, a block is a grouping of code
that gets passed to a method call. The receiving method can invoke the
block any number of times and can pass parameters to the block.
Support for a similar type of element, a closure,
is being contemplated for inclusion in Java 7; there are several
competing proposals and it is unclear which proposal, if any, will be
adopted. Example 1-1 contains a
simple Ruby class demonstrating the two ways of defining a block in
Ruby. The former syntax, using braces, is typically used to create a
block for a single statement. The latter syntax, using the do and end keywords, is typically used for
multistatement blocks.

Note

The Ruby yield function
transfers control to the block argument.

This isn’t to suggest that blocks are the only substantial
difference between Ruby and Java, but it is certainly one of the most
significant, as block usage is so prevalent within typical Ruby code.
For example, outputting the list of numbers between 1 and 10 in Java
would look something like the code in Example 1-2.
The corresponding Ruby code is shown in Example 1-3.

Example 1-2. Loop in Java

for (int i = 1; i <= 10; i++) {
System.out.println(i);
}

Example 1-3. Loop in Ruby

1.upto(10) { |x| puts x }

Ruby has an active developer community both online and in local
developer groups. The Ruby language website, http://www.ruby-lang.org, has more information about
these user groups. A wide array of books about Ruby have been
published, perhaps most famously Programming Ruby: The
Pragmatic Programmers’s Guide (Pragmatic Bookshelf) by Dave
Thomas, Chad Fowler, and Andy Hunt, known as the “pickaxe book” because of its cover, and
The Ruby Programming Language by David Flanagan
and Yukihiro Matsumoto (O’Reilly).

JRuby

JRuby began its life as a direct port of the C-based interpreter
for Ruby 1.6 written by a programmer named Jan Arne Petersen in 2001.
For the next few years, it was an interesting project, but had serious
performance limitations. Following the release of Ruby 1.8 in 2003 and
then the release of the Ruby on Rails web framework in 2004, a
significant amount of effort has been put into developing JRuby,
especially in the areas of compatibility and performance. In September
2006, Sun Microsystems effectively endorsed JRuby when it hired two of
the lead developers, Charles Nutter and Thomas Enebo, to work on JRuby
full-time. Since then, a third lead developer, Nick Sieger, has become
a Sun employee.[2]

For Sun, JRuby represents an opportunity to expand the
prevalence of the Java Virtual Machine. Although the JVM was
originally tied very closely to the Java language, the emergence of
projects like JRuby, Jython (a Java implementation of Python), Groovy (a scripting language inspired by
Ruby), and Scala (a functional/object-oriented programming language)
have proved that the JVM can host a wide variety of languages. This
trend culminated with the development of Java Specification Request
(JSR) 223, Scripting for the Java Platform. JSR 223 defines a standard
API (Application Programming Interface) for scripting languages to
integrate with the JVM. Implementations of the JSR 223 API are
available for 25 different languages from https://scripting.dev.java.net. This API will be
discussed further in Chapter 3.

For users, JRuby represents a different opportunity: to take
advantage of the power of a dynamic language such as Ruby while still
being able to leverage existing Java libraries and application
servers. This area will be explored in the first two chapters.

With the release of JRuby 1.1 in April 2008, JRuby has closed
the performance gap with the C Ruby interpreter and is in many cases
faster. In terms of compatibility, the JRuby project strives to
duplicate the behavior of the standard Ruby interpreter whenever
possible, even at the expense of consistency with Java. Most of the
core Ruby classes are included, as is much of the standard Ruby
library, the RubyGems package management system, RDoc documentation
support, and the Rake build system. Despite these efforts at compatibility,
there are some areas where JRuby deviates from behavior exhibited by
the C Ruby interpreter. The most visible example of this is how JRuby
handles threads. In this case, however, JRuby is actually
ahead of the standard Ruby interpreter in that
Ruby 2.0 is expected to have a similar threading model to what JRuby
already supports.

This chapter goes through the JRuby installation process, some
core Java/Ruby integration information, and finally a variety of IDE
integration options.

Installing JRuby

Problem

You want to install JRuby.

Solution

Download and extract the latest binary release from the JRuby
website, http://www.jruby.org. Add the bin directory to the PATH environment variable.

Discussion

Windows

The JRuby website makes binary releases available in both ZIP
and TGZ file formats. Since Windows XP, Windows operating system
software has included support for extracting ZIP files. Commercial and
open source software packages are available that include support for
TGZ files, such as WinZip (http://www.winzip.com), 7-Zip (http://www.7-zip.org), and IZArc (http://www.izarc.com).

It is not necessary to install JRuby in any particular
location on your computer. My preference is to install Java
libraries and executables in subdirectories of C:\java. The results of extracting the
binary for the latest release at the time of this writing, 1.1, can
be seen in Figure 1-1.

After extraction, JRuby is ready to be used. The simplest way
to see JRuby in action is by running jirb, JRuby’s version of Interactive Ruby
(irb). Like irb, jirb allows you to execute Ruby statements
and immediately see the results of each statement. JRuby includes
both command-line and GUI versions of jirb in the bin directory. The command-line version, seen in Figure 1-2, can be run by executing bin\jirb.bat; the GUI version, seen in
Figure 1-3, can be run by executing bin\jirb_swing.bat. In both figures, some
trivial Ruby code has been executed. You can see that both the
output of the puts method
(Hello World) and its result
(nil) have been output.

Warning

If you launch either jirb.bat or jirb_swing.bat from Windows Explorer
and all you see is a black window appear and then disappear
quickly, the likely cause is that you do not have the JAVA_HOME environment variable set, or
the value of this environment variable is incorrect. To set
environment variables in Windows, use the System control panel’s
Advanced tab. JAVA_HOME should
point to the directory in which you have Java installed.

Figure 1-1. Extracted JRuby binary build

Figure 1-2. Command-line jirb

Figure 1-3. jirb GUI

You can also test JRuby from the command line by using the
-e (evaluate) option:

C:\java\jruby-1.1\bin\jruby -e "puts 'Hello World'"

To avoid having to retype the full path to JRuby’s bin directory, add it to the PATH environment variable by opening the
System control panel and clicking on the Advanced tab. On the Advanced tab,
click the Environment Variables button. This will bring up the
Environment Variables dialog, seen in Figure 1-4. Using the New and Edit
buttons for System variables, add a JRUBY_HOME environment variable and also
prepend the value %JRUBY_HOME%\bin to the PATH environment variable. You could also
simply prepend the full path to the bin directory to PATH, but using a separate environment
variable makes upgrading a bit easier.

Figure 1-4. Windows Environment Variables

Once you have configured the environment variables, click OK.
These changes will only be reflected in newly opened windows
(something to keep in mind if you have any command-line windows
open). After adding the bin
directory to your PATH, you can
then simply run the test shown previously by executing:

jruby -e "puts 'Hello World'"

Linux and Mac OS X

The JRuby website makes binary releases available in both ZIP
and TGZ file formats. Although most Linux distributions and OS X
include utilities for extracting both types of files, TGZ files are
preferable because files extracted from them include permission
settings, something that is not the case with ZIP files.

Note

The JPackage Project at http://www.jpackage.org has a release available in
RPM format. At the time of this writing, JPackage did not have the
latest JRuby version available, but that may not be the case when
you’re reading this.

If you have root privileges on the system where you want JRuby
installed, you should install JRuby based on whatever standards
already exist. This could mean installing JRuby in /usr/local/jruby, /usr/share/jruby, or /opt/jruby, among other options. Based on
OS X conventions, Mac users should install in /opt/local/jruby or /usr/local/jruby. If you do not have root
privileges, then you likely need to install it inside your home
directory, such as ~/jruby. By
default, the JRuby releases extract to a directory containing the
version number, so we’ll simply create a symbolic link between
~/jruby and ~/jruby-1.1. This will facilitate
upgrades later:

$ cd ~
$ tar -xzf jruby-bin-1.1.tar.gz
$ ln -s jruby-1.1 jruby

Set JRUBY_HOME to the
installation directory and add JRuby’s bin directory to the PATH environment variable; add lines to
the ~/.profile similar to those
in Example 1-4.

Warning

See Also

Managing Packages with RubyGems

Problem

You want to install Ruby on Rails or other Ruby packages for use
with JRuby.

Solution

Use the RubyGems support built into JRuby. Once JRuby has been
installed, you can immediately start using RubyGems to manage Ruby
packages by running the gem
script included in JRuby’s bin
directory. To install a package, run:

$ gem install packagename

For example, to install the Ruby on Rails web framework,
use:

$ gem install rails

Discussion

RubyGems is the standard package management and distribution
system for Ruby packages. There are thousands of packages, referred to
as gems, available through the default RubyGems
repository at http://gems.rubyforge.org.
Although some gems are specific to the C Ruby implementation or JRuby,
most are compatible with any Ruby implementation.

Common RubyGems commands include install, query, update, uninstall, and rdoc. The full list can be output by using
the help command:

$ gem help commands
GEM commands are:
build Build a gem from a gemspec
cert Manage RubyGems certificates and signing settings
check Check installed gems
cleanup Clean up old versions of installed gems in the local
repository
contents Display the contents of the installed gems
dependency Show the dependencies of an installed gem
environment Display information about the RubyGems environment
fetch Download a gem and place it in the current directory
generate_index Generates the index files for a gem server directory
help Provide help on the 'gem' command
install Install a gem into the local repository
list Display all gems whose name starts with STRING
lock Generate a lockdown list of gems
mirror Mirror a gem repository
outdated Display all gems that need updates
pristine Restores installed gems to pristine condition from files
located in the gem cache
query Query gem information in local or remote repositories
rdoc Generates RDoc for pre-installed gems
search Display all gems whose name contains STRING
server Documentation and gem repository HTTP server
sources Manage the sources and cache file RubyGems uses to search
for gems
specification Display gem specification (in yaml)
uninstall Uninstall gems from the local repository
unpack Unpack an installed gem to the current directory
update Update the named gems (or all installed gems) in the local
repository
which Find the location of a library
For help on a particular command, use 'gem help COMMAND'.
Commands may be abbreviated, so long as they are unambiguous.
e.g., 'gem i rake' is short for 'gem install rake'.

See Also

Using Both Ruby and JRuby

Problem

You have Ruby and JRuby installed on the same computer and want
to ensure that a Ruby script is processed by the correct
interpreter.

Solution

Use the -S command-line
argument for the ruby and
jruby executables. For example,
RubyGems is traditionally invoked with a command like:

gem install rails

Instead, use:

$ jruby –S gem install rails

or:

$ ruby –S gem install rails

Discussion

Popular Ruby packages such as Rake, Ruby on Rails, and RubyGems
include their own executable Ruby scripts that most guides, both
online and print, instruct you to invoke directly. Whether these
scripts run with Ruby or JRuby depends on how you’ve configured the
PATH environment variable, which
platform you use, and what package is involved. Because there are so
many variables, this recipe prescribes using a single, consistent
method, passing the script name through the -S command-line argument to either the
ruby or jruby executables.

The -S command-line option
instructs Ruby and JRuby to load a script file from the PATH. JRuby includes its own copies of the
Rake and RubyGems scripts in bin/rake and bin/gem, respectively, but they are
verbatim copies of the original scripts. As a result, it doesn’t
matter which version of the script you execute, only the
interpreter with which you execute it.

This advice is particularly significant in the context of the
RubyGems script, gem. To create a new Rails application, you could run
either:

$ ruby –S rails sampleapp

or:

$ jruby –S rails sampleapp

and see the same result. However, running:

$ ruby –S gem install rails

and:

$ jruby –S gem install rails

will install the Rails gem in two different locations. You can
see this by passing environment to the gem script:

Discussion

Whereas some RubyGems are implemented entirely in Ruby, many are
implemented in a combination of Ruby and C (or, in a growing number of
cases, Ruby and Java). Pure-Ruby gems can be installed using either
JRuby or C Ruby. However, those implemented in a mixture can only be
installed using a compatible interpreter. The list of supported
platforms for each interpreter can be seen in the output of gem environment. Because the RubyGems
runtime knows this list of supported platforms, it is possible to mix
gems supporting different platforms in the same directory; the runtime
will select the appropriate libraries.

Referencing Java Classes from Ruby

Problem

You want to write Ruby code that uses one or more Java
classes.

Solution

First, you need to tell JRuby that you will be referencing Java
classes from your Ruby code. Do this by including an include declaration at the top of your Ruby
file:

include Java

The syntax for referencing a specific Java class depends on the
package in which the class resides. For packages starting with
java, javax, org, and com, you can simply reference the fully qualified class name
or use an import statement, as
shown in Example 1-5.

Note

The include_class function
can also handle classes in packages starting with java, javax, org, and com if you don’t want to switch back and
forth.

The include_class function
can also be used to create aliases in cases where a Java class name
conflicts with a Ruby class name. To do this, pass a block to the
function. Example 1-7
aliases the Java String class as
JString so that it does not
conflict with Ruby’s String
class.

Discussion

JRuby makes referencing Java classes relatively natural from the
perspective of a Java developer. For the most commonly used packages,
you can use import just as you
would in Java code.

When calling methods on a Java class, JRuby handles some type
conversion for you—instances of basic Ruby classes such as FixNum, Float, and String are converted to instances of the
corresponding Java classes when passed to Java objects. JRuby includes
implementations of the java.util.List and java.util.Map interfaces for handling Ruby
Array and Hash objects. Ruby Array objects can also be coerced into Java
Array objects by calling the
to_java method. Example 1-10 includes a combination of
Java and Ruby code, which demonstrates this functionality.

Converting a Ruby Array into a Java Array

Problem

You need to pass a Ruby array to a method that accepts a Java
array of a specific type.

Solution

Call the Ruby array’s to_java
method with an argument specifying the component type of the array.
For example, creating an array of javax.xml.transform.stream.StreamSource
objects would be done like this:

# Call a transforming Java API. This method would have been declared
# with this signature:
# public String transform(StreamSource[] sources)
p transformer.transform([cnn,mtv].to_java(StreamSource))

Primitives, as well as java.lang.String, have Ruby symbols assigned
to them. For example, to create
an array of int primitives:

[1,2,3,4,5,6,7,8,9,10].to_java(:int)

Discussion

This JRuby feature is critical for accessing Java APIs. For
example, calling a method through Java Management Extensions (JMX)
involves passing two arrays to the invoke() method of javax.management.MBeanServer, one of
Object instances, storing the
method parameters, and one of String instances, storing the method
signature. To call invoke() from
JRuby, you would do something like this:

Discussion

Although this is an extremely useful feature of JRuby, it should
be used with caution, especially if you use absolute paths that are
platform- and installation-specific. Relative paths can seem like a
better solution, but are actually more limiting, as they are evaluated
from the current working directory, not the script’s directory. Yet
all is not lost.

An interesting aspect of this feature of JRuby is that the JAR
file is added to the classpath dynamically, while the application is
running. This allows you to use Ruby’s string interpolation
functionality to create absolute paths. Example 1-12 includes a method
that creates a path to a JAR file in a local Maven
repository.[3]

Example 1-12. Creating a JAR file path dynamically

# Set the HOME environment variable if USERPROFILE is set
ENV['HOME'] = ENV['USERPROFILE'] if (ENV['USERPROFILE'])
def require_from_maven(group,artifact,version)
maven_path = "#{group}/#{artifact}/#{version}/#{artifact}-#{version}.jar"
require "#{ENV['HOME']}/.m2/repository/#{maven_path}"
end

Application code could use require to include this script and then use
the require_from_maven method to
reference a specific JAR file:

Discussion

The fact that the same syntax is used to extend both Java and
Ruby classes is an important design feature of JRuby, as it furthers
the seamless integration between the two languages.

Warning

One notable exception to this recipe is classes that use Java
5 generics. Currently, these cannot be subclassed with Ruby
classes.

Abstract Java classes can also be extended by Ruby classes.
Examples 1-14 and 1-15 show an example of an abstract Java
class and a concrete Ruby class that extends the former. The hello() method, declared abstract in the
Java class, is implemented in the Ruby class.

Implementing a Java Interface in Ruby

Problem

To use a Java API, you need to create a Ruby class that
implements a Java interface.

Solution

Create your class with method names that match the names in the
Java interface. As of version 1.1, JRuby runtime supports the use of
duck typing for implementing Java interfaces. Duck typing, seen in many
dynamic languages, including Ruby, means that the type of an object is
determined based on the methods implemented by the object. Example 1-16 shows this
technique in action as a new Java thread by passing the constructor an object that implements
the java.lang.Runnable interface.
The HelloThread class contains a
zero-argument run method that
corresponds to the method defined in java.lang.Runnable. JRuby requires no
additional type information in the HelloThread class to instantiate the
Thread object.

Example 1-16. Ruby implementation of a Java interface

include Java
class HelloThread
def run
puts 'hello world'
end
end
java.lang.Thread.new(HelloThread.new).start

Discussion

There are few situations when duck typing isn’t sufficient and
you’ll need to provide additional type information to the interpreter.
One case is when a duck-typed JRuby object is passed as an argument to
an overloaded Java method. Without additional Java type information,
the JRuby interpreter doesn’t definitively know which method to
execute. The solution is to use Ruby’s include statement to assign an explicit Java
interface to a Ruby class. This provides the JRuby interpreter with enough
information about the object to execute the correct method. In Example 1-17, the HelloThread class is assigned the Runnable interface. As a result, JRuby calls
the desired exec() method and
runnable is output to the
console.

Because Ruby scripts implicitly create a top-level class, it is
not even necessary to define a new class to implement a Java
interface. This functionality, seen in Example 1-18, can be
especially useful when prototyping and testing.

Ruby modules are a natural fit to help implement Java
interfaces. In some ways they resemble abstract Java classes, but Ruby
modules are different in that a class may include many modules. Example 1-19 shows the use of
a module to implement a Java interface and the reuse of this
module.

Example 1-19. Implementing a Java interface with a module

include Java
module RunModule
def run
1.upto(10) { |i| puts "You're number #{i}" }
end
end
class HelloThread
include RunModule
end
java.lang.Thread.new(HelloThread.new).start

JRuby allows you to create an instance of the interface by using
the impl method that’s dynamically
attached to all Java interfaces. The method accepts a block as an
argument that is executed for every function call in the interface.
The block defines two arguments: the name of the method in the
interface that initiated the block’s execution, and a variable input
parameter to accommodate the method arguments. Example 1-20 uses the impl method to define the sorting behavior
for a Java Comparator.

Another interesting technique of working with an interface is to
use a Ruby block as the input to a method where you would normally use
a single-method Java interface. The Ruby block style can be used with
nonoverloaded methods that expect to be called with a single argument
that is a Java interface. When a block is passed to such a method, the
JRuby runtime attempts to generate a proxy object that implements the
interface. Overloaded and multiple methods make this process ambiguous
and unworkable. Example 1-21 illustrates how
this feature can make the Java Swing development significantly more
concise.

A Ruby Proc object can also
be passed once it is transformed into a Ruby block using the & operator.

Note

Java interfaces that define a single method are sometimes
referred to as single abstract method types,
abbreviated as SAM types. All of the proposals for adding closures/blocks
to Java 7 attempt to make implementation of these types
significantly simpler and closer to what JRuby provides.

See Also

Opening Java Classes with JRuby

Problem

You want to add methods to a Java class.

Solution

Import the Java class so that the class can be referenced, and
add methods as you would to any Ruby class.

Discussion

In Ruby, class definitions are never finalized; new methods can
be added at any time. This is perhaps one of the most significant
differences between Java and Ruby. In Java, class definitions are
tightly bound to filenames and directory structures. The complete
definition of the Java class java.util.HashMap will be found in a file
named /java/util/HashMap.class.
In Ruby, no such relationship exists and classes can be defined across
multiple source files. With JRuby, it’s possible to apply this
language feature to Java classes. Example 1-22 shows a simple example of
enhancing the java.util.HashMap
class with a method named is?.

As you can see in this example, within the new method we can
call methods defined by the original Java class. Once this code is
executed, JRuby instances of the HashMap class, including those
already created, will have this new method. This even
applies to instances of the class created by Java code. Examples 1-23 and 1-24 contain a Java class that creates a
HashMap object and Ruby code that
opens the HashMap class and
exercises the new method.

However, any added methods are only visible to the JRuby
runtime. If you were to pass an instance of this modified HashMap class to Java code, the new methods
would not be available.

JRuby also includes a utility method called extend_proxy that allows you to add new
methods to all implementations of a particular interface. Example 1-24 could be rewritten to use this functionality so
as to work with any implementation of java.util.Map. This can be seen in Example 1-25.

Example 1-25. Using extend_proxy to open all implementations of an
interface

See Also

Setting Up Eclipse for JRuby Development

Problem

You use the Eclipse Integrated Development Environment (IDE) for
Ruby development and want to run Ruby code easily with the JRuby
interpreter.

Solution

When using the Ruby Development Tools (RDT) plugin, create a new
Ruby VM definition that is pointed at your JRuby installation location
and whose type is set to JRuby VM.
When using the Dynamic Language Toolkit (DLTK) plugin, create a new
Ruby interpreter definition that references the JRuby launch script:
bin\jruby.bat (for Windows) or
bin/jruby (for Linux and Mac OS
X) from your JRuby installation.

Discussion

Both RDT and DLTK can be configured to work with multiple Ruby
interpreters. RDT has a specific setting available for the JRuby
interpreter, whereas DLTK simply treats JRuby as a generic Ruby
interpreter.

RDT

RDT, available from http://rubyeclipse.sourceforge.net, supports
configuration of Ruby interpreters based on the installation
directory. To add JRuby as an interpreter, open the Preferences
dialog and locate the Installed Interpreters page. Click the Add
button to open the Add RubyVM dialog (seen in Figure 1-5). In this dialog, select JRuby VM
as the RubyVM type and select the JRuby installation directory as
the RubyVM home directory. You can also override the display name
with something more user-friendly. Once you’re satisfied with the
settings, click OK.

Figure 1-5. RDT Add RubyVM dialog

DLTK

The Dynamic Language Toolkit project, hosted at http://www.eclipse.org/dltk, is a broad project
sponsored by the Eclipse Foundation to provide general support for
dynamic languages in the
Eclipse development environment. Currently, support is available
through the DLKT project for Ruby, TCL, and Python. The DLTK Ruby
plugin does not make a distinction between a standard Ruby
interpreter and the JRuby interpreter. Just as when configuring RDT,
open the Preferences dialog and locate the Interpreters page. Click the Add
button to open the “Add interpreter” dialog, seen in Figure 1-6. Select the bin\jruby.bat (for Windows) or bin/jruby (for Linux and Mac OS X) as the
interpreter executable. As with RDT, you can change the interpreter
name to something more user-friendly. Finally, click OK to add the
interpreter.

Figure 1-6. DLTK “Add interpreter” dialog

Running JRuby as a Java application

Although both RDT and DLTK can easily interface with the JRuby
interpreter because they are both designed for Ruby development, you
are not able to manage the classpath used by the Java Virtual
Machine inside which JRuby is running. This is a problem when referencing Java classes
located in external JAR files. Since the JRuby interpreter is simply
a Java class, it can be run as such within Eclipse. To do this, open
the Run dialog by selecting “Open Run Dialog...” from the Run menu.
Select Java Application and click the New button to create a new
launch configuration. For the Main class, enter org.jruby.Main. In the Arguments tab, put
the path to the Ruby file you want to run in the Program arguments
section (along with any other application-specific arguments). The VM arguments should
include the jruby.base, jruby.home, and jruby.lib system properties. Set jruby.base and jruby.home to the JRuby installation
directory and jruby.lib to the
JRuby lib directory for the
last one. Eclipse has an expression language available to this
dialog that allows you to reference the JRUBY_HOME environment variable while
setting these properties with this value:

Finally, in the Classpath tab, add bsf.jar and jruby.jar from JRuby’s lib directory and any other JAR files
needed by your code. Then, click the Run button to execute.

Eclipse also supports expressions that prompt the user for
input. You can use this functionality to make the launch
configuration more reusable. You can prompt for a file, which opens
the operating system’s standard file selection dialog, with:

${file_prompt:Ruby Script Name}

To prompt specifically for a file within the workspace,
use:

${resource_loc:${string_prompt:Ruby Script Name}}

In this case, the user is prompted for a location within the
Eclipse workspace that is then converted into a filesystem path. You
can see these expressions in use in Figure 1-7.

Figure 1-7. Generic JRuby launch configuration

Running this configuration opens a dialog, seen in Figure 1-8, where you can enter the
workspace path to the Ruby script you want to execute. On subsequent
executions, Eclipse automatically populates this dialog with the
last value entered.

Figure 1-8. Eclipse variable input dialog

Note that using this type of launch configuration doesn’t
require using RDT or DLTK, although those plugins would still
provide useful functionality, including code completion and RDoc
integration.

See Also

Setting Up NetBeans for JRuby Development

Problem

You want to develop Ruby applications with NetBeans.

Solution

Download NetBeans 6.5 from http://www.netbeans.org and run the installer. NetBeans
is available in a variety of bundles; both the Ruby and All bundles
include support for Ruby development. In addition to Ruby, the All
bundle includes support for Java, Web, Mobile, and C/C++, as well as
both Apache Tomcat and Sun GlassFish application servers.

If you are already using NetBeans 6.5, Ruby support can be
installed using the Plugins dialog, seen in Figure 1-9. This plugin adds
new NetBeans project types for Ruby and Rails, graphical debuggers for
Ruby and Rails, a Ruby Code Editor, and a RubyGems client.

Once the Ruby plugin has been installed, use the Ruby page in
the Ruby Platforms dialog seen in Figure 1-10 to manage the Ruby
runtimes used by your projects. Notice the options to add new runtimes
or modify an interpreter’s gem repository location and debug level. By
default, your Ruby project will use the JRuby runtime shipped with the
Plugin, but you can assign a specific Ruby Platform to your
application by using the project’s properties dialog.

Discussion

After several years of playing second fiddle to Eclipse, Sun has
recently made some significant investments in the NetBeans project,
and it shows—nowhere more so than in the Ruby plugin. The NetBeans
Ruby Code Editor includes syntax highlighting, code coloring,
refactoring support, and powerful code completion capabilities. The
code completion functionality can be seen in Figure 1-11. The editor displays a list
of possible methods in a small window, including built-in and
user-defined Ruby classes. Hitting the space bar at this point inserts
the complete name into the editor.

Figure 1-10. NetBeans Ruby Platform Manager dialog

Figure 1-11. NetBeans Ruby code completion

You can also change the editor’s font and highlighting colors or
change the key bindings to match your personal preferences.
Configuration is done in the Options dialog seen in Figure 1-12. Choose the Fonts
& Colors tab and select a Profile from the list. OS X Ruby
developers might be interested in a TextMate theme, Aloha (http://pages.huikau.com/AlohaTheme.nbm), for a more
familiar color palette and highlighting rules. The Keymap page has
bindings for Eclipse, Emacs, and older versions of NetBeans.

See Also

Platform Detection in a JRuby Application

Problem

You would like to detect the platform used by the Ruby runtime
and customize your code for a JRuby runtime environment.

Solution

You can detect whether your application is running in JRuby by
evaluating the JRUBY_VERSION
system variable. This value will always be defined in a JRuby
application but never in any other Ruby runtime. The generate_random_number method in Example 1-26 uses the random number generator
from the Java Math class in a JRuby
environment; otherwise, the application calls Ruby’s
rand method.

Discussion

The RUBY_PLATFORM variable
has information about the runtime environment and is set to java in JRuby. It was used with early
versions of JRuby for platform detection, but the JRUBY_VERSION variable was later added to
identify unequivocally that the code was running in JRuby and not
another Ruby interpreter written in Java. The new variable also opened
up the possibility for JRuby version-specific code.

[2] A fourth lead developer, Ola Bini, works for the influential
IT consulting company ThoughtWorks.

[3] This use of the Maven repository is naïve, as it assumes the
JAR file is already in the local repository. Buildr, a build
system for Java written in Ruby, includes support for downloading
JAR files from remote Maven repositories. More information about
Buildr can be found in Chapter 6.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training,
learning paths, books, interactive tutorials, and more.