Rails vs. Grails vs. Helma: The JVM Web Framework Smackdown, Part 1

Before the advent of Ruby on Rails, many Web developers worked with Perl or vanilla PHP. Perl’s legacy dated back to the earliest dynamic Web sites. In heady days, the “Perl Mongers” were active proponents and evangelists, and the community nurtured and maintained a vast repository of contributed code. PHP was simple to learn, a snap to deploy and host on virtually any platform, and thus quickly earned a devout following. Indeed, both languages grew popular because it was easy to start an application. However, as Perl and PHP applications grew, developers inevitably became tangled in a mess of code.

Other developers eschewed scripting languages and opted for more heavyweight Web frameworks, especially those written in Java. Applications written in Java were bullet-proof and backed by a rich set of libraries, but were far from perfect, too. Java frameworks exacted a high price, miring developers in the pits of XML hell. While the Java frameworks scaled well, the initial inertia left many Java web developers jealous of the rapid, early progress Perl and PHP developers enjoyed.

Ruby on Rails, to a large degree, delivered the best of both worlds. Rails featured a well-thought out organization that guided developers toward a clean MVC design, and through a philosophy of Convention over configuration, developing new applications was only marginally more difficult than with straight PHP. Web developers, it seemed, could finally have it both ways.

But the story does not end with the advent of Rails. More and more sites began to use Rails, but as several endeavors became successful, developers also ran into new challenges. Twitter gained notoriety when the company moved part of its architecture to Scala. And, despite the benefits of Rails, many developers have begun to miss the wealth of libraries and tools commonly found with Java.

Fortunately, several Java frameworks now combine ease and robustness. Relying on JVM scripting languages and the Rails philosophy of convention over configuration, these new frameworks provide the flexibility of Rails and the enterprise-worthy support of Java. This article compares three of the most promising modern Java frameworks: JRuby on Rails (JRoR); Grails, powered by Groovy; and Helma, with Rhino JavaScript.

The Sample Application: PenguinMusic

To test JRoR, Grails, and Helma, let’s build a music site from scratch with each framework. The sample site, PenguinMusic (shown), allows users to browse songs ordered by popularity, view details about an artist and album, and leave comments if logged in to the application. The application also handles user registration.

While this sample application does not take advantage of all the bells and whistles each framework offers, it does focus on a core subset of features that virtually every website must provide, including database interaction, user authentication, and form handling. The sample code also looks at automated testing and site administration to some extent. However, no attempt is made to build facilities for Ajax or address performance. Not every site needs Ajax support, and all these frameworks have at least adequate performance for the bulk of Web applications. The focus here is the ease of launching a new application.

Each of the three frameworks ships with an embedded databases, but odds are MySQL is your choice for a production database, so that’s what’s demonstrated here. However, since all the candidate frameworks rely on JDBC, you can interact with just about any major database engine.

If you would lke to follow along, you can download the source code for each implementation. Additionally, there are some helpful scripts to load test data for each of the database setups.

JRuby on Rails: The Classic, Now Playing at Your Local JVM

If you want the benefit of a Ruby on Rails-like framework for the JVM, one obvious option is, well, Ruby on Rails. The JRuby team has been focused on Rails from the beginning, and with JRuby 1.0, the team finally achieved full Rails compatibility. Performance was terrible initially, but the developers have done a great deal of work since and more recent versions are quite fast.

The source code for the JRuby on Rails implementation of PenginMusic can be downloaded here.

Getting Started with Rails, the JRuby Way

Installing JRuby on Rails is only a little more complicated than installing traditional Rails. You must download Gems and install it with JRuby and install the requisite libraries. The command to use is:

$ jruby -S gem install mongrel activerecord-jdbcmysql-adapter rails

Running jruby -S rails jrorPM -d mysql creates a new application named jrorPM based on MySQL. After the initial code generation, your first task is to edit config/database.yml to match your database configuration. In particular, you must specify jdbcmysql as the adapter.

development:adapter: jdbcmysql
encoding: utf8
reconnect:falsedatabase: jrorPM_development
pool:5username: root
password:socket: /tmp/mysql.sock
# Warning: The database defined as "test" will be erased and# re-generated from your development database when you run "rake".# Do not set this db to the same as development or production.test:adapter: jdbcmysql
encoding: utf8
reconnect:falsedatabase: jrorPM_test
pool:5username: root
password:socket: /tmp/mysql.sock
production:adapter: jdbcmysql
encoding: utf8
reconnect:falsedatabase: jrorPM_production
pool:5username: root
password:socket: /tmp/mysql.sock

Once the database has been configured, jruby -S rake db:create:all initializes the database, and jruby script/server starts the application.

Rails Models and Migrations

One of the hallmarks of Rails implementations is that the structure of the data model lives solely in the database. This avoids any repetition of logic, a core tenet of Rails’s Don’t Repeat Yourself (DRY) philosophy. However, most of the validation logic lives in the Ruby models. As a result, one must switch between the database table and the Ruby class to get a complete picture of the model. However, this is a relatively minor hindrance, as the strong connection between the database and the model class is one of Rails’s greatest strengths.

Once upon a time, Rails developers used SQL to create models, but the practice has gradually fallen out of favor. Today, developers are encouraged to use migrations instead. Migrations are Ruby scripts that create or update a database schema. A migration is also database-independent and is fairly straightforward to use. Migrations also offer an important advantage: versioning. Historically, tying a database version to a code version has been problematic. Migrations offer a solution.

However, migrations can also be brittle. If there is a problem in any of the migration scripts, the database can become stuck in an unusable state, forcing you to resort to SQL to fix the problem anyway. Migrations also are noticeably lacking in features. For instance, foreign key constraints are not available without a plugin.

SQL does provide fine-grained control and is an option with Rails, although you may be heckled by some Rails fanatics if you choose to use it. Here, let’s stick with migrations since they are the more conventional approach.

The Rails generate script creates new models and other components from the command line. Specify model as the first argument if you just want to create the required model class. More often than not, though, you’ll want to specify scaffold instead to generate a model and complementary administrative pages to create, edit, and delete records. The second argument to generate is your model name, and the remaining arguments are name:type pairs, one pair per field. (You can actually omit all of the fields and manually edit the migration script yourself if you prefer.)

Although you can use this migration as-is, let’s modify the code to improve the database representation. Let’s make album_id and name required fields and let’s assign a default value for num_downloads. This requires changes to three lines:

As a final step, the models must be tied together. This is done through the has_one, has_many, belongs_to, and the concisely named has_and_belongs_to_many functions.
As an example, here is the model class for Album:

My programmer is trying to convince me to move to .net from PHP.
I have always disliked the idea because of the expenses. But he’s
tryiong none the less. I’ve been using WordPress on various websites for about a year and
am anxious about switching to another platform. I have heard excellent things about blogengine.net.
Is there a way I can transfer all my wordpress content into it?
Any help would be greatly appreciated!

Admiring the dedication you put into your blog and detailed information you provide.
It’s awesome to come across a blog every once in a while
that isn’t the same unwanted rehashed information. Great read!
I’ve bookmarked your site and I’m including
your RSS feeds to my Google account.

I’m really enjoying the theme/design of your weblog. Do you ever run into any
internet browser compatibility problems? A handful of my blog readers have complained
about my site not operating correctly in Explorer but looks great in Chrome.
Do you have any ideas to help fix this issue?

“obviously like your web site but you need to check the spelling on quite a few of your posts. Many of them are rife with spelling problems and I in finding it very bothersome to tell the truth on the other hand I will definitely come back again.”

Advertiser Disclosure:
Some of the products that appear on this site are from companies from which QuinStreet receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. QuinStreet does not include all companies or all types of products available in the marketplace.