I'm doing an experiment, developing an enterprise application in Java and Ruby in parallel, trying to evaluate whether Ruby is enterprise ready, or Java must still remain my weapon of choice.
Thursday, November 30, 2006
I regret to report that I came across my first hurdle with Rails today.
The idea was to quickly finish prototyping my web services (see previous post), so that I could give the client application team a WSDL they can already work with. However, when I took a good look at the WSDL file, I realized that it’s RPC/encoded, rather than the standard today – Document/literal.
That’s bad practice: first of all, this style isn’t WS-I compliant, and second, performance tends to degrade much faster.
I started looking for the way to configure AWS to work doc/lit style, and soon found out that there isn’t one – it’s just not supported at the moment.
Now, since I intend to use doc/lit with my Java system, this issue violates my success criterion #1 – my Rails and Java applications won’t be interchangeable; I can’t do with Rails anything that I can do with Java.
Worse, I’m going to have to integrate with some 3rd party products, and the plan was to do that via their SOAP API. Since they probably use doc/lit, that being the enterprise standard (WS-I compatibility and all), it’s likely that I won’t have a fast way to do that with Ruby.
I realize that for the broad Ruby and Rails community this isn’t much of an issue; most web apps are better off using REST rather than SOAP, and other popular services on the web expose their APIs via SOAP with the RPC/encoded style (Google search).
Nevertheless, from an enterprise development point of view, the lack of doc/lit support is a major drawback.
So, some possible solutions I came up with:
1. Code this myself.
I could try to add doc/lit support to soap4r – solve my problem and make a nice contribution to the community. The main problem with this approach, with regards to my experiment specifically, is that the whole idea was to see if Rails is enterprise-ready, and a better alternative than Java for enterprise development. If I need to invest a lot of time now to implement something that’s already available in Java, that defeats the purpose. Of course, if I did implement and outsource that functionality, then I solved the issue for future generations
2. Look for libraries other than soap4r/AWS.
Ruby-Amazon could be a good candidate since Amazon’s Alexa Web Search service, which ruby-amazon apparently supports definitely uses doc/lit. The don’t use soap4r, so I might be able to use their code for the basic SOAP support.
I’ll probably try a combination of the two – use the ruby-amazon to speed up my own implementation of a more generic SOAP stack that supports doc/lit. Haven’t decided yet. It’s going to take some more research (and free time).
Wednesday, November 29, 2006
This week we finally began to do some real work. I focused on designing the services I need to expose to the client application, and figured that it could be a great chance to try Rails out as a platform for rapid prototyping.
The original plan was to write Java code first, Ruby second, but since I’m pretty comfortable with Rails by now, I figured that I should experiment with the other way around as well.
That proved to be a good experience: building a basic relational data model and coding a large number of naïve services that manipulate it took roughly one day’s work, including learning ActiveRecord beyond the basics. On top of that, the Ruby code comes out compact and neat. The ease and agility of the process makes it exceptionally adequate for prototyping when you have a very general idea of what the end result should look like. I felt free to code something, test, then change my mind and change the code over and over again.
The crux of the matter, I think, is that the process involved zero configuration, i.e. XMLs and annotations, and the whole change-build-deploy-test process gets shortened significantly. With the latter, it’s not just the time involved – it’s also the annoyance of waiting for the build and deploy tasks to finish – at this point it takes long enough to be annoying, but too short to go read some blog posts while I wait.
Next, I’ll code the same stuff in Java and report on the comparable experience.
Monday, November 20, 2006
So, why am I doing this?
I’ve been using Java for nine years now. I never used it exclusively – I wrote lots of code with C, C++ and
Anyway, not long ago I finally took the plunge and learned Python (this Paul Graham article was the catalyst – after all, I like to program, and I wasn’t satisfied with the languages I already knew). Soon enough I was asking myself what took me so long. I fell in love (Noa - don’t worry, not the way I love you). After the initial crush passed, I decided to look at Ruby as well. I liked it even better. I became convinced that Java’s days are numbered. The question’s not if, it’s when (and with Rails the latter question may have been answered already).
Obviously, I began evangelizing dynamic languages around the office, with some success (i.e. getting some Java programmers to play with Python or Ruby in their spare time).
Around that time I started writing the spec for this new project. However, when I suggested that we try something other than Java, I quickly learned that management would never buy it. To paraphrase the IBM maxim: nobody ever got fired for using Java…
What I realized soon enough was that I don’t stand a fighting chance with Ruby as long as I can’t show that it’s already been used successfully in serious projects in serious enterprises. Unfortunately, I couldn’t find any references. I decided to be that reference for others, and here we are…
Thursday, November 16, 2006
The first iteration in our project is over, and so is the first part of my experiment. The result: Ruby (Rails actually) wins by knockout!
I’ll start with the summary, in case you don’t want to read through the whole story:
It took me roughly 1 day to implement with Ruby on Rails what took me roughly a week of coding (net) in Java with Spring/Hibernate/Axis.
Actually, that’s not entirely true – the rails version has more functionality since I got the scaffold html CRUD interface for free!
It would have taken less than an hour had I known how to program Ruby…
Is this a knockout or what???
And now for the whole story:
In the past week I spent one day learning Ruby basics (just reading through the pickaxe book), and another half-day learning Rails (reading through to chapter 7 in the Pragmatic Bookshelf’s Rails books). At this point I felt that I’m ready to start.
It took me 20 minutes to get up and running with a scaffold web interface for my single DB table. Of these 20 minutes, 15 were due to the fact that I had to make some schema changes – rename some columns to conform to Rails defaults.
Next, I had to put a SOAP interface on my application. I read through Web Services on Rails, and soon thereafter my application had SOAP services that return 1 record, and all records from the DB table. That took maybe another hour, including learning how to write and run unit tests.
At that point I tried to add a service that adds a new record. That’s where I got stuck, since it turned out that you can’t pass an ActiveRecord::Base descendant as a parameter to an ActionWebService. The docs tell you to use an ActionWebService::Struct object, but I really didn’t feel like writing code that copies properties from my ActiveRecord to the Struct by name – what if I changed my schema and ran generate scaffold again? That meant I had to use reflection. In other words, I finally had to learn some more Ruby…
That was yesterday. It was getting late, and I had a date with some friends to watch football, so I had to go. Today I had a very long meeting that lasted through the morning, so I only went back to the problem after lunch. It took me another two hours to finish the work.
In the next post I’ll try to analyze how come the Java version took me so much longer. We have to keep in mind that this has been a very basic exercise so far. What I built is hardly an enterprise application, and Java definitely stands a good chance to come out on top in the next rounds. We’ll see.
In any case, I learned that there’s real substance behind the Rails hype.
Wednesday, November 08, 2006
It’s been roughly 2.5 weeks since the beginning of the project’s first iteration, and it’s time for a little progress report.
The objectives of this first iteration are rather simple: set up the entire stack and see it in action. On the server side that means a single database table, entity bean, DAO, business logic and a few web services. Those services provide basic RUD functionality for objects in the DB table. The client app needs to show that it can use those services.
I’m pretty much done with the Java code for this iteration.
I’m using Spring and Hibernate, both of which I never used before. They were pretty fast to learn.
My DB is MySQL for now – I’ll need to port to MS-SQL and Oracle. Hopefully that’ll work smoothly with Hibernate.
For the web services I’m using Axis 1.4, which I don’t like much, and is giving me some troubles. I might evaluate some alternatives later on.
I haven’t started coding the Ruby system yet. So far I spent roughly two days learning the language and the Rails framework.
My job now is to develop a Rails application that works with the same DB on the back end, and exposes services that conform to the same WSDL on the front end.
My missions for the next week and a half are:
- help the client team with the code that consumes my services.
- plan the next iteration.
- and most important – write some Ruby code.
Sunday, November 05, 2006
In order to determine in the future whether this experiment has been a success I should set success criteria up front. I gave it some thought, and here’s what I came up with:
I should be able to use either the Java application or the Ruby one interchangeably, without any apparent impact. I could test this by setting up two servers, working with the same database and other systems, and have clients working with either one. If they don’t notice the change (barring performance issues, that’s another test), then Ruby passes.
This is the most important test – if Ruby passes it means that anything you can do in Java for an enterprise application, you can do in Ruby just as well.
The Ruby application’s performance should be at least comparable to Java’s. By comparable I mean that if the Java app is twice as fast, that’s still OK. If it’s 10 times as fast, then we got a problem.
I expect my Ruby coding to be very rapid. It will have to be – I’ll probably have to invest at least three weeks out of the four weeks per iteration to the Java stuff. That leaves just one week out of four or less for Ruby – or longer hours at the office for me. Now, since I’m going to code in Java first and anything you write the second time takes much less, that doesn’t mean that my Ruby productivity needs to be three times faster than Java; probably just twice as fast.
If that works, then it’s going to be an important selling point for Ruby for the enterprise – good coders don’t come cheap. Twice the productivity is a huge gain.
Also, since I’ve lots of experience with Java and practically none with Ruby, that would mean that you could teach Ruby to your Java developers and get them to be productive with it extremely fast.
This is a catchall term for all the stuff I can’t really measure scientifically – code elegance for me means readability, total lines of code, whether or not you need ugly XML files, etc. Obviously, Ruby wins this hands down as far as I’m concerned. I never considered Java to be an elegant language.
So, why is this important? Because these are the things that make coding fun; these are the reasons I’m really conducting this experiment – I want to ditch Java, but I need to supply some proof to the organization that it’s a good idea to do so.5. Scalability and Maintainability (not testable for now):
Clearly, an enterprise application needs to scale well. It must also be easy to maintain, by generations of programmers. Unfortunately, my little experiment here will test neither.
Thursday, November 02, 2006
We work in four-week long iterations, each of which has some pre-defined deliverables.
In each iteration, I’m going to write the Java code first, then implement the same features with Ruby.
It may make better sense to code in Ruby first, since it’s supposedly better for rapid prototyping. However, my deliverable as far as my employer’s concerned is the Java app. In other words, I have deadlines for the Java code. My Ruby deadlines are self-imposed, and thus can be postponed indefinitely :)
Nevertheless, my plan is to stick to the four-week iteration deadlines in both environments, i.e. finish the Java code before time, then do the same in Ruby by the end of the iteration.
This isn’t going to be easy. From my boss’ point of view, my Ruby experiment is no excuse for failure to deliver the main (Java) solution on time and in good quality. From my wife’s point of view, it’s no excuse for failure to get out of the office before . In short, Ruby better be as fast to code with as its proponents claim…