Monday, October 05, 2009

What's the embedding API of JRuby 1.4.0RC1?

JRuby 1.4.0RC1 has been released on Oct. 2 and was a big release. JRuby had a lot of bug fixes and new features. Among them, JRuby Embed (aka Red Bridge) was there. The name, Red Bridge, means a bridge from Java to Ruby and, of course, the bridge has a color of ruby. However, many people would have thought, “What’s the new embedding API?” when they saw Tom’s announce. In this blog post, I ‘m going to answer such question so that people can have better understandings about Red Bridge.

Red Bridge is a Java API to run Ruby scripts in a Java program, and the project is hosted at http://kenai.com/projects/jruby-embed. Red Bridge has two layers, Embed Core and Core based implementations of scripting API. Currently, JSR223 (javax script: http://jcp.org/en/jsr/detail?id=223) and Jakarta BSF 2.4 (Bean Scripting Framework: http://jakarta.apache.org/bsf/) are implemented on top of Embed Core. Embed Core is totally different API from JRuby’s JavaEmbedUtils, which has similar but much fewer API compared to Embed Core. Embed Core has a lot of useful methods and features for embedders. Users of this new embedding API don’t need to use JavaEmbedUtils anymore. Besides, not like scripting APIs that are common to many languages, Embed Core is focused on leveraging JRuby’s power. For example, Embed Core allows users to configure Ruby runtime easily. For example, Embed Core’s parse method can have a JRuby friendly argument, InputStream, to read scripts from.

Red Bridge was originally my solo project I started in the last winter at Google Code to solve issues that Sun’s JSR223 JRuby engine reference implementation had. I was a contributor of JRuby engine at scripting.dev.java.net but felt reluctant to rewrite the it vastly since I’m not a Sun employee. Especially, the license of the reference implementation was a big issue to distribute with JRuby. JSR223 JRuby engine users wanted the implementation to be bundled in JRuby. So, I tried to get permission from Sun, and if possible, modify the license to fit into JRuby. But, I couldn’t get any answer from Sun at all. Other than the license issue, reference implementation’s bug-prone sharing global variable mechanism was a headache to me. That part was repeatedly affected by JRuby’s internal API changes, and grew to literally patchwork like ugly code. That global variables were only one type for sharing variables between Java and Ruby was also a problem. For JavaScript, PHP or maybe other languages, a variable name should be start with ‘$.” However, the name, $something, means not just a variable to Ruby but a globally referenced variable. Some people were eager to use another variable types to share. The sharing global variable of reference implementation also had a problem when JRuby engine was used on a multi-threaded environment such as a Servlet container (Java based web application server). The reference implementation might have set true to ThreadLocal option of Ruby runtime using a System property. However, relying on JVM wide system properties caused another problem especially on web application servers. A web application server might have multiple web applications (wars) on it and system property settings affect all of them.

In light of these issues Red Bridge has exactly the same license as JRuby and new mechanism for sharing variables, besides enables sharing global, local, and instance variables. Users can choose ThreadLocal model for context local values such as Ruby runtime, or sharing variables and other instances. Embed Core provides users methods to configure Ruby runtime. However, JSR223 and BSF engines still rely on JVM wide system property since those APIs haven’t defined such method. See Wiki, http://kenai.com/projects/jruby-embed/pages/Home, for details.

At kenai.com, you might find the project whose name is “Red Bridge.” When I moved my project to kenai.com right after I got the invitation from Charles Oliver Nutter, the name was Red Bridge, the same one at Google Code. A couple of weeks later, I talked with Charles and Thomas Enebo about Red Bridge. They liked Core part of two layers of Red Bridge and wanted to have just core layer bundled in JRuby. Following their choice, I started “JRuby Embed” project just for Embed Core. After that, JSR223 and BSF were added to the list to be bundled in JRuby, and Red Bridge was merged into JRuby Embed project. Merged into Red Bridge was definitely another choice. However, I chose JRuby Embed because people were interested in Embed Core part more than JSR 223 implementation and more members have been subscribed in JRuby Embed. Besides, the package name is org.jruby.embed, no redbridge in it. Since the name, “Red Bridge,” is easy to memorize and nice compared to banal name, “JRuby Embed,” I’ll keep using Red Bridge. While BSF implementation never had its own project ever. The implementation was added after JSR223 was merged in and took for a week or so.

Having JRuby 1.4.0RC1, users might be confusing JRuby’s JavaEmbedUtils and Red Bridge, and which one they should use. Definitely, new users should use Red Bridge since it is easy to use and powerful. (I’m working hard to update documents, so some of them are old. Sorry!) Right now, JavaEmbedUtils as well as other embed related interfaces are on a discussion to seek how they can be obsolete. API of JavaEmbedUtils and others have been used in many packages including JRuby Rack, so making them obsolete would be influential. Red Bridge will probably need to have bug fixes and improve its performance. Also API of Red Bridge probably needs to be reviewed and modified. I think it takes a time to eliminate JavaEmbedUtils.

Then, what will be next? I want to add a feature to run compiled Ruby scripts on Red Bridge. Currently, JIT and Force compiled modes are supported, but those are different from executing *.class files generated from *.rb. “Rails on Red Bridge” will be my exciting challenge. If people can write Struts’ action by Ruby using Red Bridge, it might be interesting. I don’t have a clear load map right now, but I want to keep going.

Have fun with Red Bridge!