Thursday, March 27, 2008

Calling Ruby script from Java code using javax.script package and JRuby

Thi is my first post, so it will be very simple.

I am facing a new work challenge where I was promoted to be a technical leader of a development team. The project has begun, but we are just developing some POCs to call some Ruby scripts from a Java code and use the results to perform some functionalities.
My knowledge about Ruby is nothing, but I am studying, and as I did not start to develop some code using Java 6, I decided to implement something using the javax.script classes to see if it really works (just kidding).
Why do I use JRuby? I am using JRuby because I wanted to receive a Java collection from the Ruby script and I wanted to call a method that receives parameters, so I did as you can see in the code below.

I created a method, in this case, in a Servlet that uses the ScriptEngineManager to call a method (def) in the test.rb script. The class path must contains the Ruby script path to find the script and execute the "getTreeSet" method (def).

Follows the Ruby script using JRuby:

def getTreeSet(name)
require 'java'
include_class 'java.util.TreeSet'
set = TreeSet.new
set.add "name"
return set
end

And now the Java code:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

TreeSet set = null;

ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("rb");
InputStream is = ClassLoader.getSystemResourceAsStream("teste.rb");
Reader reader = new InputStreamReader(is);
try {
scriptEngine.eval(reader);
Invocable invocableEngine = (Invocable)scriptEngine;
if (invocableEngine != null) {
set = (TreeSet)invocableEngine.invokeFunction("
getTreeSet", "Calling Ruby using javax.script is cool!");
}

request.setAttribute("result", set );

RequestDispatcher view = request.getRequestDispatcher("/result.jsp");
view.forward(request, response);

} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}

That's it. Unfortunately I didn't know if I can use Java 6 yet in the project development. :-(

Want to know more about Java and Ruby? Access: Sun Ruby Developer Center

2 comments:

jackob said...

I recently came across your blog and have been reading along. I thought I would leave my first comment.
I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
Thank YOu
Python Perl Development

Roger Pack said...

See also http://kenai.com/projects/jruby/pages/CallingJavaFromJRuby