Java and JRuby working together

Collection of issues and solutions I encountered when using JRuby. Further information can be found in the JRuby wiki.

Importing Java classes into JRuby

To prevent overwriting of other classes you should consider to put Java classes into a separate name space. A namespace is just a Ruby module.

module Java
include_class 'java.util.ArrayList'
include_class 'de.laliluna.Foo'
end

Now you can use the Java classes like

list = Java::ArrayList.new

Hint: If you don't include a java class, you can always use it by adding Java:: and the full package name.

list = Java::JavaUtil::ArrayList.new

Java enumeration / enum

public class ShopOrder {
  public enum Status {
    OPEN, CANCELLED, DELIVERED
  }
}

Getting a Java enum from a Ruby symbol

def getJavaEnum symbol = :open
  Java::ShopOrder::Status.value_of(status.to_s.upcase)
 end

java.util.List, java.util.ArrayList

To use a java.util.List I found it easiest to convert it to a Ruby structure, i.e. an array.

The following code shows how to remove duplicate entries from a List. You can run the code in jirb (this is Jruby console, just type jirb in a terminal to start it)

list = Java::JavaUtil::ArrayList.new
  list.add 1
  list.add 2
  list.add 1

Instead of add you can use the more Ruby like

list << 4

Print the list

list
  => #

Convert it to a Ruby array and remove duplicated entries

list.to_a.uniq
=> [1, 2]

Exception handling

When calling Java code from JRuby, you will get Java exceptions wrapped in a NativeException.

The following code shows how to catch the exception and to extract the wrapped exception.

begin
buffer = @accountService.download(session[:username], Integer(item_pk))
rescue NativeException => e
if (e.cause.kind_of?(Java::JavaLang::SecurityException))
flashError 'You can't download other peoples stuff'
redirect R(self, :index)
end
end