Last Updates | Login      

Ruby Programming with Mentawai (total integration with JRuby)

Starting on version 1.13 Mentawai fully supports JRuby. You are able to write your actions in Ruby (or your whole application) or you can call any Ruby code from your Mentawai web application.

To support plain Ruby, all you need to do is copy the jruby.jar file inside the /WEB-INF/lib directory of your Mentawai web application. However, if you plan to use RubyGems and the Ruby Native Libraries (like 'date' for example) you will need to install JRuby in the machine running your Tomcat web server. To install JRuby is very easy. Follow the steps below:

Download the zip file with the JRuby installation from here: (Ex:

Extract everything inside your root directory (or any directory)

Set the environment variable JRUBY_HOME. (Ex: JRUBY_HOME=c:\jruby-1.1.1)

Set the environment variable JRUBY_OPTS to -rubygems so that you don't need to require 'rubygems' in your code.

Change your PATH environment variable to include %JRUBY_HOME\bin so that you can call the jruby script from anywhere in your shell.

If you did the above steps correctly, you should be able to play with jruby in your shell. Check the examplew below:

Now let's check an example of how to run Ruby inside your Mentawai web application. (download Mentawai 1.13 here if you need to)

All your ruby code must be placed inside the /WEB-INF/ruby/ directory of your web application. Mentawai loads (do the require) any Ruby file from this directory plus it will reload any modified file pretty much like a JSP.

An action written in Ruby: /WEB-INF/ruby/action_test.rb

A Java Action calling Ruby code: /WEB-INF/src/org/hello/action/

Ruby code which is called by the Java action above: /WEB-INF/ruby/users_test.rb


Below we have a simple tutorial for the features of the Mentawai integration with JRuby

Simple API to call ruby methods on any Ruby object from Java
JRubyWrapper for making ruby method calls even easier
Support method chaining. Ex: "methods.sort.grep"
Auto-reload any ruby file from the loadpath
Load any ruby file from the classpath with the loadFromClasspath method
Get a singleton instance of the JRubyInterpreter anywhere in your code with the JRubyInterpreter.getInstance() method
Support all JRuby environment variables and provide defaults for them. Ex: JRUBY_OPTS for -rubygems and -Ku , JRUBY_SHELL, JRUBY_SCRIPT, JRUBY_LIB and JRUBY_HOME.
Windows and Linux support

The file foo.rb anywhere in your loadpath (Ruby equivalent of Java's classpath)

OBS: Don't forget to change this file to see how it will be automatically reloaded by JRubyInterpreter.

Plug and play with JRubyInterpreter:

Using the JRubyWrapper:

Using Scala with Mentawai

Because Scala code is compiled into Java bytecode, you can code your web application using Scala instead of Java.

Below is an example of a Mentawai action coded in Scala:

Compile this Scala class with the following command line:

This will create a file HelloScala.class inside the org\mentablank\action directory. Now you can use this class as any other Java class. Just remember to put the scala-library.jar inside the your WEB-INF/lib directory.

Let's use the javap program, that comes with Scala, to inspect our Scala class from the point-of-view of a Java program:

This will give you some hints about the Java class, but nothing can be better than a decompilation using JAD (Java Decompiler):

Enjoy using Scala with Mentawai!

Some Scala resources:

Setting up a connection pool

Mentawai comes out-of-the-box with support for C3P0 and DBCP connection pools. All you need is two lines:

In the

Then inside your actions you just do:

You don't even have to worry about returning the connection to the pool. The ConnectionFilter will make sure that happen for you.

You can also create a C3P0ConnectionHandler the same way to use the C3P0 connection pool instead. Just make sure the pool and the JDBC jars are in your WEB-INF/lib directory.

Setting up a cache cluster

Mentawai uses JGroups (the best Java cluster solution?) to implement a distributed cache. This can be useful when you have many web servers in load balance and you want to accomplish seamless fail-over.

That's it! Just make sure the objects you place in the cache are serializable and all instances of your cache running in different machines will share the same data.

The default cache implementation is LRU (Least Resource Usage), so the least accessed entry will be removed when the cache gets full. You can also uso a FIFOCache (first in, first out, in other words, the oldest entry will be removed) like that:

If you are bringing a new web server into the load balance pool, keep in mind that it will first have to get all the entries from the cluster before it can start operating. This can take some time if the cache is too big.

Another option is to use the SynchronizedCache which just synchronizes new entries with the other nodes and does not have the startup overhead.

Creating your own display tags

Let's say for example that you want a tag that will print the number of friends of an user. If he has only one friend, the word "friend" will be in the singular form. If he has more than one friend, then the word is "friends". And if he has no friends at all, then you will print a friendly message saying nobody likes him (or just something like "You have no friends!").

Notice that because you extended from PrintTag, you have access to the following protected instance variables:

Now to use your tag, you need a TLD file. This is a Servlet API requirement and there's nothing we can do about this file, so save the XML below in a file inside the /WEB-INF/tld directory, for example taglib.tld:

Now in your JSP page, you can do this: