JRuby Bridge Tutorial - Things to do on the Ruby side

Include Java

If a Ruby script wants to use names (typically class names, for creating instances of the class) from the Java world, you need to announce this with

# Ruby
include Java

It doesn't harm to get into the habit to placing this line at the beginning of every JRuby file.

Making a Java class available

In a similar way to using require or require_relative to get your Ruby classes known to your application, you use java_import to get a Java class name known to your application. For example, we want to create inside our asahi.rb an instance of the Java class HE, which is defined in the Java package hostenv. To do this, we need to write

# Ruby
java_import 'hostenv.HE'

This arranges, that the name HE is used on the Ruby side and can be used without mentioning the package name, similar to a Java import of the form

import hostenv.HE; // Java

For example, the Java class HE has a constructor with the following signature:

// Java
public class HE {
  public HE(Integer j) { ... }

An object of this class can be instantiated on the Ruby side by

  HE.new(45) # Ruby

Naming Java classes

Note that in the above Ruby code, it was not necessary to explicitly invoke the constructor for the (Java-)type java.lang.Integer. For common types, like numbers and strings, JRuby converts them "under the hood". However, you can invoke the constructor such standard classes explicitly, and you have to do it for non-standard classes anyway.

As mentioned above, you can do a java_import but there is also another way:

Let a Java class HolyMoses be defined in package foo.bar.baz. You create an instance of this class from within your Ruby code by

  Java::FooBarBaz::HolyMoses.new('Master of Disaster') # Ruby

Note that Java and Java::FooBarBaz are Ruby modules, and FooBarBaz is created by intercapping the (nested= Java package name foo.bar.baz. In other words: While in Java, package bar belongs to package foo, there is no corresponding relationship within the Ruby module universe. All Java packages, no matter how deeply nested, live flat under the Ruby module Java.

For those classes which are defined below the packages java, javax, javafx, org, and com, a simpler way to denote them is available. For example, to explicitly refer to the Java String class, that is java.lang.String, you can simply write java.lang.String instead of Java::JavaLang::String.

Note that in Ruby, java (lower case!) is a method of class Object. This method gets added when we execute the command include Java.

In our example application, the Asahi method aJavaString demonstrates both ways to refer to the same Java String class:

# Ruby
class Asahi
  def aJavaString
    java.lang.String.new('I was born as a Java string').concat(Java::JavaLang::String.new('!!!!'))

Of course, in the case of strings, you would normally not instantiate a Java string, but work with Ruby strings all the time, and let the conversion to and from Java strings do automatically by the JRuby runtime, when the data crosses the Red Bridge.

As a side note, you can see that concat is used to catenate the two Java strings, not +, as we would do in Java. The Java '+'-operator is not a Java method, but syntactic sugar, provided by the Java compiler and hence not available as a method. Adding this operator to the Ruby side could be done by

# Ruby
class java::lang::String
  alias :+ :concat

but it's not worth doing it, because occasions to operate on the Ruby side with Java strings will likely be rare.