The upcoming, and now recent, release of JRuby 1.0, along with some conversations with various friends has left me thinking a lot recently about how to integrate a Java project with a Ruby (on Rails) project. If you have an existing domain model written in Java then the reasons you might want to do this become obvious. Rails is designed using the MVC architecture, and if you can get it talking to your java domain model, then the M is already written for, you just have to write the views and controllers. Views especially can be painful in Java.
The standard answer for integartion between languages is currently web services: Write a simple XML wrapper round the Java domain objects allowing methods to be called on them, then use that API from within your Rails models. It doesn’t really matter if you use SOAP, REST or your own “standard” (although REST lends itself nicely to having a toXML() and a setXML() method on your java classes and using ActiveResource to GET and SET instances).
However, XML has never been a major contender for speed, and the chances are that your API isn’t designed to minimize the number of calls you make. So you have to pay that overhead more often than you need to. Of course you could add a remote facade, but now things are maybe starting to get more complex than you need…
JRuby provides a much more integrated way of solving the problem. It works like this: JRuby lets you import Java classes into your Rails code. Your controllers do not need to know (or care) that they are not Rails models. They can just find a new User instance, set the password on it, and move on to the next one.
Of course, I’m not suggesting that it’s that simple. Rails expects the models to be ActiveRecord instances. You are likely to suffer from code expecting to find an ActiveRecord method, like User.find and it not being there. I imagine the solution to this would be a library that loads all of your Java classes, and then changes them (as Ruby can do that) to add methods normaly provided by ActiveRecord. You can add the validation methods, then you can add the persistence methods like save, and find. How you do this is going to be dependent on how your Java persistence is done (ok, I’m assuming your Java code has a persistence model – I probably should have mentioned that earlier). If you have used the DAO pattern, the find method could instance a DAO object, load an instance though it, and return that. If you don’t use DAOs, then you map the methods to whatever you do use.
Finally you need to wrap all your code up into a library that runs when rails starts, automatically loads all your java classes, and decorates them. Hey presto, your old legacy Java domain model has a new lease of life as a trendy Rails application. If anyone has the time to write this library, let me know – I would love to have a play with it.
Unlike the rest of the Rails system, this integration won’t be solved by convention over configuration. Potentially it could be, but I think there are just too many different designs; different persistence models and different ways of locating your domain model out there…