Latest Posts

Archives [+]

Scripting a Java Content Repository with JRuby

Given a) the current interest in dynamic languages and b) the comments after the last post I would like to show how easy it is to use a Java Content Repository from JRuby.

First, download and install JRuby. Make sure you got it right by executing

jruby -v

from the command line.

Also download the Jackrabbit jars and put them on the classpath. An easy way to do this is to copy them into JRuby's lib directory.

Now, let's access our Jackrabbit repository through Ruby code. I have taken the examples Hop 1 and Hop 2 from the Jackrabbit introduction and translated the Java code straight into Ruby:

require 'java'
include_class('java.lang.String') {|package,name| "J#{name}" }
include_class 'javax.jcr.Repository'
include_class 'javax.jcr.SimpleCredentials'
include_class 'org.apache.jackrabbit.core.TransientRepository'

repository = TransientRepository.new
session = repository.login(SimpleCredentials.new("admin", JString.new("admin").toCharArray))
name = repository.getDescriptor(Repository::REP_NAME_DESC);
user = session.getUserID
puts "logged in as " + user + " in " + name

root = session.getRootNode
hello = root.addNode("hello")
world = hello.addNode("world")
world.setProperty("message", "Hello, World!")
session.save

node = root.getNode("hello/world")
puts node.getPath
puts node.getProperty("message").getString

root.getNode("hello").remove
session.save
session.logout

Save this as a file jcrTest.rb and execute

jruby jcrTest.rb

You should get something like:

C:\>jruby testJava.rb
log4j:WARN No appenders could be found for logger (org.apache.jackrabbit.core.TransientRepository).
log4j:WARN Please initialize the log4j system properly.
logged in as admin in Jackrabbit
/hello/world
Hello, World!

Don't worry about the log4j warnings (or fix them according to the Jackrabbit introduction mentioned above). The important bit is that the script gets a repository session, writes some content and deletes it again.

The code is really just a one-by-one translation of the Jackrabbit samples so see the original page for explanations. In case you are confused about the JString import in the second line: this is to avoid the name clash of Ruby strings and Java strings. For further information have a look at Ola Bini's intro to JRuby.

We can also use JRuby for something more interesting: an interactice JCR console. Ruby (and JRuby) have the console irb (and jirb) that dynamically executes ruby code. A session where a JCR is connected to and written into could look like this:

C:\>\dev-tools\jruby-1.0.3\bin\jirb
irb(main):004:0> repository = TransientRepository.new
=> #<Java::OrgApacheJackrabbitCore...
irb(main):005:0> session = repository.login(SimpleCredentials.new("admin", JString.new("admin").toCharArray))
log4j:WARN No appenders could be found for logger (org.apache.jackrabbit.core.TransientRepository).
log4j:WARN Please initialize the log4j system properly.
=> #<Java::OrgApacheJackrabbitCore...;
irb(main):006:0> user = session.getUserID
=> "admin"
irb(main):007:0> root = session.getRootNode
=> #<Java::OrgApacheJackrabbitCore...
irb(main):008:0> hello = root.addNode("hello")
=> #<Java::OrgApacheJackrabbitCore...
irb(main):009:0> world = hello.addNode("world")
=> #<Java::OrgApacheJackrabbitCore...
irb(main):010:0> world.setProperty("message", "Hello, World!")
=> #<Java::OrgApacheJackrabbitCore...
irb(main):011:0> session.save
=> nil
irb(main):012:0> session.logout
=> nil
irb(main):013:0>exit

(For better legibility I have shortened some of jirb's output and set the input lines to bold.)