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.

9/21/2007

Maven: Why does it have to be so hard?

Every project I start I try to use Maven. It seems like the right choice but I consistently fail. Every step is hard. It's not just that there are infrastructure hurdles, but the commands are hard, the POM is complex and nothing is easy.

This J bites.

Ok, enough whining. Maven is the right way to manage your build environment simply because it is the only tool that manages your dependencies. This is a simple concept.

We can argue that ant has sufficed for a long time and that is true. So, we can argue that the dependency complexities that we face are actually not that hard since we appear to be able to work it out without another tool, but wouldn't it be great if we could leverage the learning that others have already put into setting up the correct dependencies?

Well I am installing grails, an ant solution, and integrating CXF and Mule. I am facing continuous versioning problems with all the xml/soap/ws etc jars. I am sure that when I have solved this problem, I will promptly forget it and have to solve it all over again for the next project.

I would like to be able to capture the solution in a POM so that I could reuse it even if no one else does.

So, what is step one. Create a maven project. This is so hard. I can't believe they make us do this. No wonder this tool is taking so long to gain acceptance.

mvn archetype:create -DgroupId=com.company.project-DartifactId=project-name-DarchetypeArtifactId=maven-archetype-webapp


Yes, that is the command to create a project, and I didn't even specify all the other version options that they mention. All it does is create this:

./pom.xml
./src
./src/main
./src/main/resources
./src/main/webapp
./src/main/webapp/index.jsp
./src/main/webapp/WEB-INF
./src/main/webapp/WEB-INF/web.xml


It doesn't do much but it does allow us to enforce standards and, when we develope our own archetypes will improve project structure consistency accross the board. This is all good but why do I need to pass in system properties? Who ever heard of a command line interface that makes you declare system properties.

Perhaps it could prompt for the required fields like "grails create-app". Perhaps there should be a web page on the maven site that will help. I had to go through google to find it. Their quick start doesn't even talk about it.

I know, I know, I am whining. I could probably contribute to the project myself, it's open source and all that.

There is an Eclipse and NetBeans plugin that makes life a little easier.

There comees a point when we learn to love the new tool. I just pasted a glob of xml into my POM file because some CXF/Maven web page told me to, saved it, and the maven eclipse plugin promptly downloaded all the jars required to bring a CXF web service up and running. This took me an hour or so the first time. Maven just made my life easier.

...

And again I am dashed to the jagged rocks of the learning curve. It appears maven doesn't use the JAVA_HOME environment variable to determine the JDK version to use and it is defaulting to JDK 1.3 which is not even installed on my machine. I have annotations so it will not work anyway.

I suppose it makes sense because it is requiring explicit version declarations for all other jars so why not the rt.jar but it is not telling me how to specify it.

This brings up the odd balance in our lives of detail vs default. If I require everything specified I know my build will always be correct. If I allow default selections using JAVA_HOME for example, it may fail but will usually work.

This is why maven is so hard to deal with. Nothing is easy. Specify or die a bloody death and don't expect to block the gushin wound with documentation because even google is lost.

...

Ok, I found it, System Dependencies

...
Oh wait, that is wrong, doesn't work and I don't know what it does though it sounded so close. Infact, we want this Compiling-J2SE-5

Man that took another 30 minutes, I almost gave up on Maven again.

...
I might be back to loving maven again. Once you have run your "mvn package" to create your war file you can run "mvn tomcat:run" which will run tomcat in place from your generated war file. Now that is cool.

...
Well, while I can't expect maven to solve all my problems, since it's intent is to solve dependency problems I did have that expectation. Silly me.

The CXF xml glob that I pasted to get all the CXF jars and dependencies downloaded apparently missed the SAAJ jars. I expect I will have to find and add these to my project file manually.

I am starting to feel as though I might be starting to understand Maven, even if it isn't doing what I want.