9/23/2007

JRuby Rails Project Day One, Lessons Learned

I blogged a while ago that Ruby was the way to go for the best language experience for the future. To that end I am starting to build a new site using Ruby on Rails and focusing on JRuby so that I can deploy it to my existing Tomcat hosting service.

The site is going to present a new company Sewing Seeds of Literacy which is a venture my wife is embarking on to help supply books to under privileged children. I was hired as the technical help.

Background over.

I started by using the NetBeans V6 IDE and its Ruby Rails integration. This is a major step forward in IDE Ruby support and integrates with JRuby easily.

So, right click, New Project, Ruby Rails Application, and you have your first Rails runtime on top of JRuby. This is really nice.

Initial setup over.

The first problem is the database access. The JRuby environment requires JDBC access. The database.yml setup is the same but there is an ActiveRecordJDBC gem that needs to be installed to manage the connection from ActiveRecord ORM library to the JDBC drivers.

This is all detailed on the Headius site.

Then these JDBC drivers need to be available on the classpath. I am going in with MySQL so I needed to add the mysql-connector-java-5.0.4-bin.jar to the classpath.

Unfortunately there are some competing configuration issues going on here.

1) I had downloaded and installed my own JRuby environment and NetBeans comes with its own. This causes problems because each environment installs its own gems. You can set the environment that NetBeans will use in

Tools->Options->Miscelanious->Ruby


2) I had my own c-ruby environment and my path specified jruby/bin before ruby/bin but the JRuby "rake" command is unix only so I was inadvertently running the c-ruby rake command expecting it to manage my migration properly but it couldn't find the JDBC gem.

Anyway, after much googling, Foo had the answer. You need to create a "jrake.bat" in your JRuby bin directory that looks like this:
@echo off
jruby -S rake %*


Now you can jrake in your jruby environment and rake in your c-ruby environment. There are references to "jake" here and there but nothing concrete.

3) Now that we are running the right commands we need to add the appropriate jar. There are a couple of ways to do this

o Create the CLASSPATH environment variable and point it to your jar.
o Copy your jar into the JRUBY_HOME/lib dir.

One thing that does NOT appear to work is adding the jar to the Netbeans project classpath.

I chose to copy to JRUBY_HOME/lib for the time being but I don't like this as a long term solution since it means each environment I deploy to needs some extra installation work. Ideally, the jars would be deployed with my war file so they are made available to the containers classpath automatically.

JDBC Jar configuration over.

Right click, generate, controller, simple. Right click, generate, model, no sweat. Right click, generate, migration, done.

These are basic Rails concepts that work just as well in a JRuby environment. They make application development very easy.

mysqladmin create MYDB_development
jrake db:migrate


Database creation over.

Now I have a model and a model test but I can't run them because there is no database. Yes, we just finished using our cool new migrations to create a database but that was the development database which is the default RAILS_ENV. We need the test database created from the same migrations. This is not so easy. In fact it is really hard. None of the books talk about it, all the migrations help pages just talk about the default development case. We are going to have to run our migration in test regularly and eventually in production as well so there has to be a solution.

Along comes a new plugin called Migrate Test DB Rake Plugin . This is a rails plugin that performs a database schema create on the test database before rails tests are run. This means that when you execute "jrake test" it will create the schema first. This is not effective when running Test::Unit in NetBeans.

So, I don't see that this is a good solution. As a side effect of testing I am able to create a test database schema. Still doesn't solve the production database situation but that is a little way off.

Model create over.

Oh, now I find the best documentation, on the JRuby Wiki. This entry talks about the "goldspike" plugin which adds lots of java'esk features to rake like creating a war and how to declare the mysql jar as a dependency.

2 comments:

Tor Norbye said...

Hi there,
this is Tor Norbye and I work on the NetBeans Ruby support.

A lot of the steps you're describing -shouldn't be necessary (although it's possible some of this went in after the beta1 cutoff).

Specifically,
(1) we already prebundle ActiveRecord-JDBC with the NetBeans distribution, so JDBC should be working out of the box if you check the "JDBC" checkbox in the New Rails Project wizard. (If you don't have one there, I guess this is in a daily build and not NB6).

The latest version of active record jdbc lets you work with a standard database.yml file. In particular, you don't need JDBC syntax there - the standard MySQL format should work for JDBC with MySQL.

(2) We also bundle Goldspike; that's what the second checkbox on the create wizard is for (something about War deployment).

If this isn't working in the bits you have, try grabbing a kit from
http://deadlock.netbeans.org/hudson/job/ruby/

We're still going to make a couple of changes to this, to make it easier to configure JDBC for other databases than the ones listed in the dropdown.

Edward Sumerfield said...

JavaPosse Rocks. Nuff said.

While it is nice that IDE's do everything for us we must consider the release cycles that we are coupling.

1) Your bundling of these packages into your NetBeans JRuby deployment only solves the single JRuby installation.

I actually already have a JRuby deployment so I can not use yours. This will pay dividends when I want to upgrade my JRuby installation and will not care about where NetBeans is of where it stores it's JRuby version.

If a couple of people on my team download different versions of NetBeans how am I to be sure that the JRuby interpreter is the same? The only way is to issolate the interpreter version from the IDE so that all team members can share.

2) I am afraid Rails fails on this front badly. Run "rails xxx" and the world is copied into your project. These environments should be isolated with clean interfaces to ensure that version cycling has limited impact.

Not knowing how its implemented this may be the reason I had problems. I did not check the check boxes you mentioned on the project create dialog. Since these are implemented using plugins instead of isolated build processes I didn't get all this extra junk copied into my project and didn't have a way to configure these features in later on.

The good and bad of automation. Isolating release cycle concerns from product concerns from which interpreter to use would make these environments much easier to manage.

For me, having to go through and understand all the junk I need to get it working is beneficial. Perhaps goldspike should be a standard part of the JRuby deployment instead of a plugin in my product.

Great work on NetBeans and thanks for your comments.