Thursday, October 27, 2005

Hibernate & Ruby


In my previous project I was using the latest and greatest version of Hibernate and was happily employing the Hibernate Eclipse plugin for writing my HQL queries before embedding them in my application. But my current project uses an older version of Hibernate (2.1.x) so the Eclipse plugin is out of the question. Fortunately I can remember back to when I used the forerunner of the Eclipse plugin, a little program that was called Hibern8IDE. It later became part of the Hibernate extension tools and was then thankfully renamed "Hibernate Console". Fortunately it's still available for download from hibernate.org.

Now the only problem is that this project also uses Spring which informs Hibernate about the XDoclet-generated mapping files at runtime in a decidedly non-hibernate fashion. What I needed was to create a good old fashioned hibernate.cfg.xml which contains references to each *.hbm.xml file. But I wanted to script the generation of this file so that I wouldn't have to manually maintain the file as the collection of *.hbm.xml changes over time. So I turned to my new friend Ruby. The top and bottom part of this script use "here docs" to generate the boiler plate static XML. But then right in the middle I got this:


`find . -name '*.hbm.xml' -print`.each { |f|
f.gsub!(/.*(com\/company.*?)\n/, '\1')
puts "<mapping resource=\"#{f}\"/>"
}


The first line executes the Unix find command, and then begins an iterator over each line of that command's results. Then within the block I use a simple regex within the String's substitution method to get the Java package and file name. Then finally I print out an XML element whose resource attribute contains the name of the *.hbm.xml file. That's a lot of stuff in only four lines of code! Ruby is very expressive. Now I must emphasize the value of a good editor to color code something like that so a person can make sense of it. I definitely recommend the RDT plugin for Eclipse.

Thursday, October 20, 2005

Right & Wrong

Back in August I commented on Microsoft's aggressive moves against Adobe. I also mentioned that Apple could also make a move with it's new Core Image technology built into OS X. But at the time I didn't think it was all that likely. Well I was right that they could but I was wrong because they did.

Apparently Apple wants a piece of that image processing market. They just introduced Aperture. And although they're going to some pains to say it's complementary to Photoshop, I think it's definitely a competitor.

Apple really is becoming quite a software powerhouse... Fortunately for most software companies, they can feel secure that the only software they produce that isn't Macintosh-only is iTunes and Quicktime. But then again once somebody (like me for example) gets a taste of Mac, all that Microsoft stuff just feels like rubbish. With all the Apple stores around the U.S. with their little built in theaters, the brand new Quad PowerMacs will show this stuff off very well.

Tuesday, October 18, 2005

HD Movie Trailers

Check out the new Movie Trailers page at Apple. A fair number of them are in HD. Normally I have to scale a video several times to fit my entire screen. These trailers fill my screen without any scaling at all.

Saturday, October 15, 2005

Ruby, Ruby, Ruby, Ruby

Remember when Steve Ballmer went all schizo and jumped around like a big Gorilla shouting "developers, developers, developers, developers"? Well I think I'm starting to get infected by a similar disease. I'm not a complete raving lunatic just yet but I'm really starting to dig Ruby. ;-)

After madly writing endless lines of Java code for the past three weeks that does next to nothing (see my previous rant) I'm elated to see that there are others in the world who believe less code is better.

To demonstrate, here are the steps you can take to create a dynamically generated page with Ruby on Rails.

1. > rails ./demo
2. > cd demo
3. > mv public/index.html public/index.html.old
4. > script/generate controller people list
5. modify config/routes.rb and add the line map.connect '', :controller => 'people', :action => 'list'
6. modify app/controllers/people_controller.rb (see listing below)
7. modify app/views/people/list.rhtml (see listing below)
8. > script/server
9. browse to localhost:3000
10. voila!

A couple of important points to notice is that Rails embraces the MVC design pattern. Model and Controller classes are separate while the View is off in its own place. The view is an .rhtml file because it's basically HTML with Ruby embedded within it. While those who've been doing JSP development may scoff at the mere idea of embedding "code" within a page and believe that custom tags is the only way to go, I have to admit that after doing JSF for a few weeks I actually like this a whole lot better. Remembering that Ruby is a 'scripting' language and that Rails uses Controller classes (like "code-behind") may help people get over their prejudice. Finally here a few links I've found very valuable during the last week:

What Is Ruby on Rails
Rolling With Ruby on Rails
Rolling with Ruby on Rails, Part 2
Ruby On Rails Documentation
why's poignant guide to Ruby
Rails Academy (videos)

app/controllers/people_controller.rb
class PeopleController < ApplicationController
def list
@names=['Yukihiro Matsumoto', 'David Heinemeier Hansson']
end
end

app/views/people/list.rhtml
<html>
<head>
<title>This is my first Ruby page</title>
<link rel="stylesheet" type="text/css"
href="stylesheets/mystyle.css" />
</head>
<body>
<h1>Ruby/Rails People List</h1>
<table>
<% @names.each do |name| %>
<tr><td><%= name %></td></tr>
<% end %>
</table>
</body>
</html>

Saturday, October 08, 2005

Ruby On Rails


I discovered a new version of the Ruby Development Tools (RDT) plugin for Eclipse yesterday. I hadn't used it in quite awhile, so I downloaded this new version, installed it and was quite pleasantly surprised. I opened an old project I had laying around and rediscovered the simplicity of Ruby. I wrote a Test::Unit subclass and ran it in the RDT test runner. Very nice. Just like running JUnit tests in Eclipse.

So I decided this is cool, lets try this Ruby on Rails thing that I keep reading about. Mac OS X Tiger comes installed with Ruby 1.8.2, the Apache web server and SQLite, so I was more than half way there to getting setup. I followed this little tutorial to install RubyGems, a packaging system for Ruby libraries and tools. After that, installing rails (i.e., "sudo gem install rails") and creating a little sample application was a breeze. My only hiccup was fixing a permissions problem with my sample app (i.e., the public, db, and logs files needed to be readable and writable by apache).

Setting up a rails app involves generating a bunch of files so I can't claim to know what's really going on under the covers, but it's a very cool thing to be able to edit data through a web UI so quickly. Rails has impressed me so far. Now I just need to build something of my own and decide for myself if all these Ruby/Rails productivity claims hold water.

Tuesday, October 04, 2005

LINQ

A friend of mine just sent me a video link to a interview with Anders Hejlsberg talking about LINQ (Language INtegrated Query). Take Java's Hibernate ORM (object relational mapping), mix in contextual type inference and then throw in homogenous query syntax (that has a close resemblance to SQL) across relational databases, XML data and in-memory objects and you get an idea of what LINQ is all about. It sounds very ambitious (and it is) but Anders does a great demo. The comments section on the board makes it sound revolutionary but if you've been playing in the ORM space for any amount of time it seems like a very natural evolutionary step. But I didn't see the "type inference" stuff coming. That's brilliant. Makes the query stuff much more powerful.

Sunday, October 02, 2005

Seam

After yesterday's rant about layers upon layers of code and XML based dependency injection I found Norman Richard's blog about a new web framework called Seam from JBoss. Apparently Gavin King, the guy who brought us Hibernate, is involved in this as well. That's a very good sign. From what I've read it looks like this might be just what I'm looking for. It's brand new and will undoubtedly have rough spots and missing functionality, but it really does seem to be headed in the right direction.

Saturday, October 01, 2005

6 days later

I've been in my new job for six days now and thought I'd post my thoughts about what I've done so far. The short answer is "not much". It's actually pretty amazing to me how little is done to prepare for a new person. And I'm not even talking about this specific company, it's a general problem. Even the most glaringly obvious things like getting ids and passwords for databases, version control systems and even permissions on file servers are almost never set up when I go to a new job. Sometimes the environment is responsive to new requests, other times... not so much.

Secondly, when being inserted into a team of people already madly coding away, nobody has the time to give you the lay of the land. So I spent at least a couple days looking a existing code to figure out what I need to do to make my code fit in with everything else. It all seems highly inefficient and a waste of my time and their money. Maybe when you consider just one developer, it may not seem like much but multiply a week of time for every new developer who walks through the door then it's easy to see a pretty big opportunity to save. Do the math with let's say 20 developers and you soon start to think "I could probably build a lot of stuff in 20 weeks".

Anyway, I did manage to build a single web page this past week. But what really impressed me was the number of files I needed to create/edit to enable this one page. I created:
  1. a domain object with Hibernate XDoclet annotations
  2. a DAO interface
  3. a Hibernate DAO implementation
  4. a DAO unit test
  5. a Service/Facade interface
  6. a Service implementation
  7. a Service unit test
  8. a JSF backing bean and a JSP page.
I edited:
  1. an application resources properties file (despite the fact localization is not a requirement)
  2. two Spring XML files
  3. a JSF config XML file and
  4. added some XML to the tiles definition file.
Phew! That's fourteen resources and I chose to expose my domain objects to my presentation layer instead of using the DTO pattern which would have increased my resource count by one more! The unfortunate side effect of all this stuff is that I find myself constantly navigating around all these files and fighting the typo-prone XML. I'm starting to question if all this layering and scoffolding is really buying me anything.

In my last job, where I made the decisions about architecture and technologies, I had:
  1. XDoclet annotated domain objects (which included named queries)
  2. NO DAOs (I felt that the Hibernate abstraction and named queries were a sufficient data access layer)
  3. Service Objects (typically singletons with explicitly coded session and transaction management)
  4. XDoclet annotated Struts Action/Form objects + JSPs
  5. the typical smattering of JUnit test classes.
In retrospect it seems so extraordinarily straightforward: One class for my domain layer, Hibernate annotations in the same file for my data access layer, one class for my service layer and typically two classes for my presentation layer and absolutely no XML. When I needed to internationalize my GUI I also had at least one or two resource bundles (*.properties files). But compare 7-8 files against 14 or 15 and you can see that complexity has grown significantly.

Having worked with a variety of people over the years I know there are those who believe that elegance is expressed with simplicity. Look at E=mc² for example. And then there are those who love to wallow in complexity. I love simple, efficient, elegant designs. I'm not sure I've found that here... Not yet anyway. Maybe I'll come to love it over time (my fingers are crossed).

Finally, let me comment on a couple of my statements in earlier posts:
  1. There is a simpler way to integrate Spring and JSF so that you can inject Spring configured beans into JSF managed beans. Using Spring's org.springframework.web.jsf.DelegatingVariableResolver configured within your faces config makes it all transparent. Yay! It may not be as good as using only one dependency injection framework but it's a good runner up.
  2. Secondly, you can integrate tiles into JSF by configuring org.apache.myfaces.application.jsp.JspTilesViewHandlerImpl in your faces config file.
  3. Finally, I read Spring's documentation a little more closely and it appears you can use HibernateTemplate's execute method to call whatever Hibernate code you want. So I can now feel free to use that lovely Hibernate API all I want! ;-)