Tuesday, December 20, 2005

The Daily WTF

A co-worker just sent me this URL. I had a good chuckle looking at some of the code posted on this website so I figured I'd post it here for posterity. There's an RSS feed too so you can keep up to date with the latest WTFs.

Sunday, December 18, 2005

RadRails

I decided I would try downloading the latest milestone version of Eclipse 3.2M4 and set up an IDE without all the Java development tools and just the RDT (Ruby Development Tools) that would start up faster and let me do some Rails development with less clutter. Then somehow I stumbled upon the RadRails Eclipse plugin (gotta love surfing the web). So far it seems really quite good. I can run the WEBrick server, view my PostgreSQL database, hit the web application all within Eclipse! And it also gives me a colour coded RHTML editor and better code completion than RDT. I even just subscribed to their Podcast. I haven't used it extensively yet but so far I'm quite impressed.

Thursday, December 15, 2005

Rails 1.0

Well I obviously haven't been using my Mac for a couple days (where all my Ruby RSS feeds live) because I missed the 1.0 release of Ruby on Rails. I just went to the new flashy Ruby on Rails page and checked out one of their videos about creating a flickr front end. Holy moly! It may be an old video for all I know, but that is one very cool demo. Mmmm, AJAX and Ruby on Rails good!

Tuesday, December 13, 2005

Revolution

I was just listening to the Beatles' Revolution... Very appropriate lyrics for software development don't you think?
You say you want a revolution
Well, you know
We all want to change the world
You tell me that it's evolution
Well, you know
We all want to change the world

But when you talk about destruction
Don't you know that you can count me out
Don't you know it's gonna be all right (3x)

You say you got a real solution
Well, you know
We'd all love to see the plan
You ask me for a contribution
Well, you know
We're doing what we can

[...]

Monday, December 12, 2005

Buying Mac Software

With the popularity of the iPod, the fortunes for the Mac have been looking brighter too and with that, more retailers are carrying Macs. In Calgary, BestBuy and London Drugs are recognizable chains that carry the Mac. So with that in mind, I went shopping for a game for my son for Christmas. Well it wasn't a terribly pleasant experience. While the shelves are loaded with software for Windows PCs, Mac software is far more difficult to come by. BestBuy was the worst. They had NOTHING. London Drugs faired a little better but only had a few titles like "Mac OS X Tiger". I went to these stores first because their locations are more convenient to my place of work.

But in the end I went to WestWorld Computers on Centre Street in Calgary and was greeted with a recently rennovated showroom. There was lots of hardware and software on display and some knowledgable salesmen walking around. I immediately found what I was looking for and made my purchase. My lesson? Forget the big box stores and go for the focussed reseller.

PS: iPods are very hot Christmas items. People were buying them at all three locations.

Thursday, December 08, 2005

RoR & Foos together at last

Even as my spare time dwindles with the responsibilities of hosting the family Christmas celebrations at our house this year, I still try to find the time to continue my Ruby on Rails education. In 2005 I looked at a lot of technologies but RoR is one of the first to actually have me interested enough to do more than just read a book. Let me explain...

At work we have a foosball ladder which consists of a white board and a dry erase pen. While refreshingly low tech I thought "here's a problem just waiting to be automated with software!". Okay it doesn't really need software but it's a complex enough problem for me to get my feet wet with Rails. I unabashedly looked at the ladder options already on the web and (ahem) borrowed some of their ideas. I need to store information about players, teams, the ladders themselves, matches and the games in those matches and then I can go onto bells and whistles like enabling online challenge negotiations, the ability to mark a players status, and showing player/team stats.

So already I have several tables in a PostgreSQL database with a variety of relationships between them and I'm slowly figuring out what I can do with RoR's ORM tool ActiveRecord. So far I've been pretty happy with the support for optimistic locking, one-to-one (belongs_to & has_one), one-to-many (has_many), and many-to-many (has_and_belongs_to_many) relationships, dynamic finders, and transaction support.

I especially like being able to just play around in Ruby. I can mess with the tables, add and remove columns, change names, etc and then quickly see my changes take shape in my Ruby object model by running a simple Ruby script to create some objects and save them to the database. And no requirement to compile, or generate ORM XML mapping files has me feeling quite empowered.

Wednesday, December 07, 2005

Testing

I came in to work this morning only to listen to a QA lead and a senior developer discuss the almighty importance of tests (specifically unit tests). "They are the specifications, blah, blah, blah". But you know what I didn't hear, the importance of the actual software itself! Agile-development, test-first, test-driven, whatever-process-comes-next are all well and good but don't get so damn attached to it that you don't focus on what's really important, the software. Don't get me wrong, tests are important but they come a distant second to the system under development.

Thursday, December 01, 2005

Work's a drag

A few Pragmatic Programmer tips are:
  1. Provide Options, Don't Make Lame Excuses
    Instead of excuses, provide options. Don't say it can't be done; explain what can be done.
  2. Don't Live with Broken Windows
    Fix bad designs, wrong decisions, and poor code when you see them.
  3. Be a Catalyst for Change
    You can't force change on people. Instead, show them how the future might be and help them participate in creating it.
  4. Remember the Big Picture
    Don't get so engrossed in the details that you forget to check what's happening around you.
And I try to live by that... But with so many developers heading in different directions trying to prove how smart they are, I feel like I'm riding in an out-of-control freight car. The momentum is too huge to overcome by myself.

During some informal polling among other developers I get a pretty divere set of opinions. Some agree with me (but not on the same remedies), others are apathetic, and others feel that everything is just fine. So naturally I don't feel that comfortable pulling the handbrake. I just hope there isn't a sudden stop and a loud bang associated with this ride.

I guess there's a reason they call it "work".
Remarkable developers use remarkable technologies to do remarkable things.
[...]
If you don't have passion for software development you will not become a remarkable software developer, period.
- Chad Fowler

Tornado Foosball


We got a new foosball table at work about a week ago, a Tornado Whirlwind. Now I can fully indulge my addiction to this fun but difficult-to-explain-to-your-wife game. The Tornado tables are very solidly built and are designed for a controlled game. So while we still have some slaptastic players whose style of play is better suited to the "speed-ball" rules, most are coming around to trying to intentionally score a goal rather than just smacking it as hard as you can and hoping something good happens.

Digital Cameras

iPhoto on the Mac was first released in January, 2002 and nearly four years later I've finally joined the party by buying the Canon PowerShot SD450 digital camera. I learned that size is a pretty big consideration when buying digital devices and generally the smaller the better. The less of a hindrance it is to take with you, the more likely you are to use it. That's certainly been my experience with my iPod shuffle. I sometimes wish I had the features and storage of the larger model but the size is perfect. The feature I like best about my new camera is its ability to rotate the image according to orientation of the camera when I'm playing back existing shots. Very cool!

Monday, November 21, 2005

Genealogy

What started out as an innocent school project for my daughter has turned into a full time project for me! What was a simple family tree has now turned into a genealogical expedition of epic proportions... well okay maybe not... But I have discovered some interesting facts:
  • my grandmother on my father's side came from Scotland
  • my great Grandfather on my father's side was a candy maker in Germany
  • my great grandparents on my mother's side came from England
My cousin (once removed) in Los Angeles (who I met over the internet) was a great help for getting me started with information about my mother's side of the family. My aunt in Saskatchewan has been great for my Dad's side of the family. I've never felt terribly close to either side of my family but a few phone calls and e-mails is changing my perception. What a friendly, helpful bunch of people!

Finally my software of choice has been a little Java application called GenealogyJ or GenJ for short. Having never touched a commercial tool that does this stuff I'm pretty impressed with GenJ. There's a nice little graphical viewer and lots of reports. The best part is that it stores all it's data in a UTF-8 encoded text file (in the standard Gedcom format) that's easily read in any text editor. That's pretty important to me so that my information will always be accessible even if GenJ should go the way of the Dodo.

For those of you who've been into this stuff for years and have some pointers, send me an e-mail or post a comment...

Wednesday, November 02, 2005

Chasing simplicity in programming

A new article on c|net discusses the new phenom "Ruby on Rails". Quotes from the article:
Like Java did a decade ago, Ruby on Rails is getting developers excited by making them more productive

The vision of Ruby on Rails, or RoR, is to combine the speed and ease-of-use of scripting language PHP with the "clean," structured approach of Java

Java Enterprise Edition software is a "complex monstrosity" that's hard to learn

Research company Burton Group recommends that corporate customers consider Ruby on Rails for new Web development projects

We took a pretty radical stand: Stored procedures and all things that make your database clever are evil

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! ;-)

Sunday, September 25, 2005

On JSF, Struts, & Spring Part Deux

After a Saturday of messing around with Spring, JSF, & Hibernate I have a nice little application that does nothing more than retrieve an object from my local PostgreSQL database and display the value in a web page. While the end result isn't very exciting there is a whole symphony of integration going on under the covers.

Hibernate and Spring

I first created a couple business domain classes that use the latest and greatest Hibernate/EJB3 Java 5 annotations to describe how they map to database entities. This is currently supported in Hibernate 3.1 beta 3 so I didn't really expect to be able to use this stuff once I got to integrating it with Spring. I assumed I'd have to either write Hibernate mappings in XML or maybe integrate XDoclet to generate the mappings. Well to my surprise Spring has org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean!! So Spring was good to go! All I had to do was declare the sessionFactory and the transactionManager that I wanted in applicationContext.xml. I still haven't figured out a way to get it to autodiscover the annotated business model so I had to manually list the two classes but that wasn't too big of a problem.

I then moved on to creating a subclass of Spring's HibernateDaoSupport class and configuring it in applicationContext.xml where I learned about the declarative transaction management features of Spring. In this XML file I was able to wire together the DAO, the Hibernate sessionFactory, the transactionManager and indicate which DAO methods require a transaction. This simplified the code in the DAO by injecting the necessary Hibernate Session and Transactions at runtime. But this comes at the cost of using a HibernateDaoSupport method called getHibernateTemplate() whose returned object basically delegates to the injected Hibernate session and turns Hibernate exceptions into unchecked exceptions. This also has the unfortunate side effect of burying the native Hibernate API. I don't really care for that idea too much but it's a tradeoff for not having to manage session and transaction resources manually.

So I then created a little JUnit test, used the FileSystemXmlApplicationContext to start up Spring and then used the context to get the configured DAO from Spring and called a method. Everything worked as expected.

Spring and JSF

Next it came time to integrate JSF. This became a little more time consuming. First of all I needed to figure out how to initialize all the Spring stuff within a web application which in turn initializes all the Hibernate stuff. It was actually fairly simple. I only had to configure a listener in the web.xml file for org.springframework.web.context.ContextLoaderListener. Also by using context-param in web.xml I was able to tell this ContextLoaderListener instance where to find my spring applicationContext.xml files.

Secondly, JSF has its own Dependency Injection framework for configuring backing beans that have request, session or application scope and it was unclear to me how to integrate the two dependency injection frameworks i.e., If my DAO and Facade/Service classes are configured with Spring how would I go about injecting these instances into a JSF backing bean? Well as it turns out I can't. Not yet anyway. There is a little project appropriately enough named "jsf-spring" that aims to transparently aggregate these two frameworks. It's in beta. But Spring has a supporting class called FacesContextUtils which allows me to fetch an instance of WebApplicationContext (with the current FacesContext as a parameter). I can then use that Spring context object to fetch the DAO (or more typically a facade class) to do the work I need. Given all this dependency injection stuff this manual fetching of context objects and service objects seems like a very odd hack and is more like calling a singleton getInstance method. But it works and I was able to tie the business layer to the presentation layer.

Summary

So there you go, a display-only Spring/Hibernate/JSF application. It was a good lesson in making all the pieces work together. In the end I look at all this plumbing and I'm a bit surprised how simple and difficult it was to get everything going. The Spring stuff is well documented on the web and was easy to get going with Hibernate. But answers to my questions about adding JSF to the mix were a little harder to come by. I suspect the future holds a stronger integration for Spring and JSF (perhaps you can just use Spring as a replacement for the JSF injection framework) and I can see Java 5 annotations becoming more prevalent in Spring so that you don't have to write all that XML. Annotations work great for Hibernate so I don't see why they wouldn't work well for Spring too.

Saturday, September 24, 2005

On JSF, Struts, & Spring

I started a new contract yesterday and got a bit of a taste of what to expect in the coming months. We're building web-based Java applications and the typical J2EE MVC, Facade, DAO, & (evil) DTO patterns are in full effect.

I'm fortunate enough to get to continue to use Hibernate for ORM which is very cool. I still think Hibernate and object relational mapping in general is a very good thing. The biggest "problem" I see is that it looks like people are opting to use the "TopLink" way of doing things by using Criteria objects instead of HQL. What are they thinking? Why anyone would choose to use a non expressive bunch of Java code to write a query is beyond me. HQL is way better and one of the reason I like Hibernate so much better than TopLink. I e-mailed my supervisor about this one and we'll see what kind of response I get.

On the web framework front, we're using JSF (MyFaces specifically) instead of the defacto standard Struts. While fundamentally I don't have anything against Java Server Faces (it does have some nice features) I have to wonder why they made the decision to use it. David Geary (co-author of the book "Core Java Server Faces") once gave a talk at our local Java User Group meeting once and said something to the effect that "JSF was a standardized Struts that IDE vendors could rally around to create JSP visual editing tools". Part of that goal was to compete with ASP.NET. Coding up JSP pages is a bit mundane and who wouldn't rather have a tool write that junk for you? Well apparently the people where I'm working made that decision! It's still all hand-coded. So now we're using a framework nobody understands and I suspect productivity is lower. Where's the logic in that?

MyFaces seems very similar to Struts so conceptually it's easy to grasp but it's the details and the peculiarities of how things work that slow you down. It also seems to be at a higher level abstraction from the lower level request/response and the HTML it generates (the theory is that you can generate something other than HTML). But I think I prefer Tapestry's idea of staying close to HTML and only injecting the dynamic content. Tapestry allows you to use any HTML editing tool and HTML is well understood. JSF on the other hand is this parallel universe of tags that look a bit like HTML but can only be edited in a text editor or a JSF visual editing tool and at the moment there doesn't seem to be any tools that play nice with the MyFaces implementation. Secondly, staying close to HTML allows you to take advantage of advances in HTML like XHTML and AJAX. JSF, like ASP.NET, gives you a component model that will likely adapt to support advances in the underlying technology but there will always be a time lag. Perhaps the other minor benefits will outweigh the losses. We'll see... Right now it looks like change for the sake of change.

They also bought into the whole Spring IoC (a.k.a., Dependency Injection) idea. At first glance this seems like a good idea. You design to interfaces in an attempt to hide implementation details. Theoretically it should enable unit testing and allow us to switch between POJOs, Web Services and EJBs with greater ease. Of course it comes at a cost of greater complexity for questionable gain. For example if you create a DAO interface and then only ever create one implementation of that interface what have you gained? And then you have all the XML gunk to wire everything together. Theoretically, a meta data approach to wiring stuff together is better but not having experienced it before I'm a bit skeptical. The fortunate part about Spring is that they seem to understand that they need to play nice in a bigger community and support all the major Java frameworks out there so integration looks to be pretty straightforward.

My feelings are a bit mixed... Sometimes I believe that the dynamic, competitive, multi-vendor Java community is more vibrant than the MS .NET community and that the variety of tools is our attempt to find the most effective method for developing software. But sometimes I believe that we're all just chasing the next trend and running around in circles and I envy the single voice (Borg like as it may be) leading MS development. Anyway, I have some things to learn and I'll withold my final judgement until I've been using JSF and Spring for awhile. Maybe there are some pleasant surprises to come.

Friday, September 09, 2005

Open Surfin Safari

People seem to give Apple a lot of flak for being a proprietary software company and while it'd be ridiculous to argue the fact that Apple is to a large degree closed source, what most don't realize is that they are a very active user of and contributor to open source projects. The kernel of the OS is based on FreeBSD and the source code is available for download at Apple's OpenDarwin website. It's been like that since the first release of Mac OS X.

Secondly Apple's Webkit, their HTML engine used in the Safari web browser, is based on KHTML from KDE, the desktop environment for Linux. The source code for Webkit is also available for downloading from the OpenDarwin website. And as a matter of fact I followed the instructions in this article to get the source code from the CVS repository, compile it and run the latest code. Very cool. It's even the first (and currently the only) browser to pass the ACID2 test which tests a browser's support of web standards (try that with IE).

So yes Apple is proprietary in many respects but they understand when it makes sense to be part of the open source community.

Tuesday, September 06, 2005

Lube, Rods, Scoring, oh my!


I was told by a couple of people who read my blog that it's too "boring" so I figured I'd spice it up a bit and talk about lubing your rod. All your partners will oooOOOOooo and aaaaAAAAAaaaa...

Get your mind out of the gutter...

I'm talking about foosball again! LOL. In addition to the new men on our foos table I had enough money left over from our "foos-aid" office collection to buy a can of 3-in-1 silicone spray lubricant from Canadian Tire for the foosball table rods. What a difference maintaining your uh "equipment" can do for you.

Friday, August 26, 2005

Training and Coaching

I just found an old article that I co-wrote back in 1997 for Computing Canada. The article was really a reader's digest version of a report I wrote for an application audit (a really intensive code review after-the-fact). It was a PowerBuilder app and the article makes reference to some PB-specific technology but reading it again 8 years later I'm surprised to realize that so many of the same things apply to the way we build apps today.

Too often, I see relatively junior programmers unleashed on software development projects with little or no guidance or leadership. As a matter of fact, I've probably spent two thirds of the last year rewriting year-old software that was created by junior resources with no training and no concern for best practices. I can see why companies are lured into using resources like this. They're relatively cheap, they're pretty keen, they work long hours and they really crank it out. But if they don't know what they're doing you end up supporting the old adage "there's not enough time to fix it now, but there's always time to rewrite it later".

The biggest thing that junior software developers don't do, is separate concerns. UI, business logic and data access get all tangled into one big incoherent mess. I stress that there must be some cohesion in your domain model. Generally speaking the closer you get to the users the more your code is exposed to change. In other words, the UI is going to change. Count on it. As you go up through the layers things change less and less. By the time you get to your domain model and the relational model that allows it to be persisted, Things are very stable and any change you must make to them has serious repercussions on the rest of the app. Therefore get that stuff right. You can be forgiven for cheating a bit when you get to the UI but at least build the backend stuff as well as you can. And feel free to use some junior resources, but for crying out loud, lead them.

Luxury Foosball


I recently took up a collection to replace a couple of foosball men on our Harvard foosball table at work. If you've ever seen one of these tables you know that the original men and the replacements are pretty boring looking. So a few folks around the office had some fun photoshopping, combining the heads of people with men on a rod. Well it appears for a mere $73,000 you too can get a table with tiny little replicas of friends and family.

Monday, August 22, 2005

Target: Adobe

Microsoft is making some moves that look quite threatening to Adobe. Microsoft is building applications to replace Photoshop (PSD) , Acrobat (PDF), and now Flash (SWF). Microsoft's calling it's Adobe-killers Acrylic, Metro, and Sparkle. A little more of that embrace, extend, and extinguish we all love? Maybe.

By the way, with the new Core Graphics, Core Image, and Core Video frameworks in Apple's Mac OS X, I suspect that Apple has laid the foundation for a similar move if they think it's necessary. But Adobe got its start with Apple, and Apple in turn uses PDF everywhere in Mac OS X so I think Apple contributing to Adobe's demise is a much less likely outcome.

Monday, August 15, 2005

Interviewing

In my current position I'm the lead Java developer because I have the most experience and know as much as, and maybe even a little bit more than, the rest of the people on the team. Part of my strategy to keep my skills sharp, is the routine investigation of other languages and tools. Most recently those languages have been C# and ObjectiveC (and their related frameworks, .NET and Cocoa respectively). Apparently my boss took note of my new knowledge and a few days ago she asked me to conduct technical interviews for a "senior" Microsoft .NET developer.

I was a bit anxious about the request because I don't consider myself a .NET expert. But I approached these interviews the way I've approached all the Java developer interviews in the past. I try to cover a broad range of topics (e.g., Relational Databases, OO, Patterns, Object Relational Mapping, Unit Testing, HTML, insert programming language here , etc.) and just substituted the Java questions for C#/.NET questions. What surprised me is the quality (or the lack thereof) of the people I've interviewed. Maybe I should be looking for a .NET job? ;-)

Wednesday, August 10, 2005

EJB3 Presentation

It seems like EJB3 information is coming fast and furious now. The Server Side is hosting a new EJB3 presentation recorded at the Belgium Java Users Group. One of the speakers is an Oracle Toplink developer. It gives a very good overview of the EntityManager API that I was talking about the other day. Check it out.

Virtual Globetrotter

Google Maps has obviously inspired some people to check out the world from a whole new perspective. Check out the Eiffel Tower or the Great Pyramids. And when you're through with that go check out Sightseeing with Google Satellite Maps or Google Sightseeing. Be careful, just like the real thing, sightseeing this way can waste a lot of time.

Monday, August 08, 2005

EJB3 EntityManager

Since my first post about Entity EJBs with Hibernate, the Hibernate team put out a new beta implementation of javax.persistence.EntityManager. So I wondered what exactly it would take to jettison all the hibernate imports from my class. Well it turned out to be pretty simple. First I substituted the hibernate.cfg.xml file for a META-INF/persistence.xml file that looks like this:

<entity-manager>
<name>manager1</name>
<properties>
<property
name="hibernate.connection.driver_class"
value="org.postgresql.Driver"/>
<property
name="hibernate.connection.url"
value="jdbc:postgresql://127.0.0.1:5432/myDatabase"/>
<property
name="hibernate.connection.username"
value="darcy"/>
<property
name="hibernate.connection.password"
value="darcy"/>
<property
name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect"/>
</properties>
</entity-manager>

The interesting thing about this is that it autodiscovers the annotated classes. No longer do I have to individually list each persistent class. Secondly, I changed my main method to look like this:

public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("manager1");

EntityManager em = emf.createEntityManager();
try{
Brand b = (Brand)em.createQuery("select b from Brand as b")
.setMaxResults(1)
.getSingleResult();
System.out.println(b.getName());
}finally{
em.close();
}
}

You can see that this code is very similar to the Hibernate code that I posted earlier. Obviously the class names and some of the methods are different (like getSingleResult() instead of uniqueResult()) but at first glance it looks like getting started is pretty easy. It'll be interesting to see some of the differences between Session and EntityManager.

Tiger Development

After installing Mac OS X Tiger, and restoring applications and user data, my next job was to install development tools.

Java

On the Java side: I'm a bit perplexed why Apple doesn't ship their Java 5 implementation with Tiger. As far back as I can remember they've always shipped the latest and greatest. But this time I had to download. No big deal, but it's hidden on their website. I expected to be able to go to connect.apple.com (their developer website) click on "Downloads>Java" and it would be there. But no, only the Java 5 docs are there. Instead I had to go to the general Mac OS X website and go to the downloads section in there and search for it.

Anyway, that was only a minor annoyance. I was able to download it and install it without any trouble. My next problem was that Java 5 wasn't made the default VM. So I had a little more googling to do before I discovered a couple symlink changes would make everything happy. In the end I have all my Java apps and IDEs (i.e., Eclipse) working with the new Java 5 VM and all is well a week later.

Cocoa

Next thing was a move to XCode 2.1. I downloaded it and installed it without any issues (there was a nice big link on the Apple's developer connect website). I was able to open all my Cocoa projects, recompile and run without issue. So then it was time to move onto seeing what's new in Cocoa in Mac OS X. There's quite a bit, but the one that instantly attracted me was the visualization tools in XCode.

I've always been a big fan of modelling tools and the diagrams they create. I always find it easier to express ideas in a picture and it's always easier to look at a diagram rather than gobs of source code to figure out what someone else was thinking. Well apparently Apple feels the same way. XCode now gives you the ability to generate class diagrams from your source code (Java, Objective-C or C++). And these diagrams aren't static either. As you change things in code the diagrams reflect those changes. Fortunately, they look and behave like UML class diagrams so the symbols are pretty familiar.

Apple also uses this new diagram facility in something they call CoreData. Essentially you create an entity relationship diagram that describes the data that your application maintains and then at runtime, the core data framework will use this metedata to store and retrieve user data in an XML file or a SQLite database. Couple this with the Cocoa Bindings framework, which allows you to bind object properties to UI widgets, and you have some great facilities for building data-centric applications. Now that the persistence and UI parts of the application are taken care of by the Cocoa frameworks you are left to concentrate on the business logic. The big limitation in CoreData right now is that it's XML and SQLLite only. That means if you want to create a multiuser application with an enterprise database server you're out of luck. Secondly, even if it did allow you to go against an Oracle or Sybase server I don't think the tools are really designed for fine grained control over the object relational mapping or the queries that are generated. But I don't want to diminish the productivity of this framework in addressing the the single user data persistence problem. If I was developing a desktop Mac OS X application, I'd be all over this. Here's a nice little tutorial that you may find interesting.

There is also a nifty little feature that allows you to drag and drop an entity from the diagram into a window in Interface Builder and generate a default UI. Apple says you can use this feature to quickly create a starting point for your application or to quickly generate an application to exercise your data model. I was impressed that I could create a fully functioning application that maintained data with no code in just a few minutes!

Monday, August 01, 2005

Tiger!

Well I took the leap and bought Mac OS X 10.4 Tiger today. I also followed the recommendations on the web (kinda of a herd mentality) and erased the hard drive and reinstalled "fresh". That second internal SATA hard drive definitely came in handy for backing up applications and the stuff in everyone's accounts. A few hours later I have everything back to normal (I think). My first impressions is that the Dashboard is pretty cute but I'm not sure how useful (although the calculator came in handy once already). Spotlight is definitely nice (and fast too). Searching for anything across the disk is pretty wicked! Well it's late, and time for bed. I'll post info about the ugly stuff once I come across it. ;-)

Friday, July 29, 2005

EJB3

With the use of Java 5's new metadata support and Hibernate 3's early annotation tools I decided to see what it would take to make an EJB3 Entity Bean. Well it's quite a bit simpler than Entity EJBs used to be and I don't need a big nasty EJB container either! It's just a plain old Java object (POJO). And as you can see in the main method's source code, I can still use the same Hibernate code that I'm familiar with.

@Entity(access=AccessType.FIELD)
@Table(name="my_brand", schema="ds")
public class Brand {
@Id(generate=GeneratorType.NONE)
@Column(name="brand_code")
private String id;

@Column(name="brand_name")
private String name;

/**
* @param args
*/
public static void main(String[] args) {
Configuration cfg = new AnnotationConfiguration()
.configure();
SessionFactory factory = cfg.buildSessionFactory();

Session session = factory.openSession();
try{
Brand b = (Brand)session.createQuery(
"select b from Brand as b")
.setMaxResults(1)
.uniqueResult();
System.out.println(b.getName());
}finally{
session.close();
}
}
//getters and setters
}

Tuesday, July 26, 2005

Discovery

I vividly remember watching the first space shuttle flight on April 12, 1981. I diligently cut out the newspaper story about Columbia's maiden voyage. It was an exciting time. Today over the internet, 24 years later, I was able to watch NASA's return to flight with the launch of Discovery. Call me nostalgic but it was inspiring today as it was then...

Halo

I remember watching the 1999 MacWorld keynote webcast where Steve Jobs introduced Bungie Studios. They demoed a new game called Halo on a G3 Mac. It was Bungie's followup first-person-shooter to their other Mac-only hits, Marathon and Myth. After Microsoft's purchase of Bungie (to make Halo an XBox exclusive), the enormous Halo 2 sequel, and six years, they finally came full circle and released a Mac demo that I can download and play. It may not be as revolutionary as it would have been in 1999 but it's still a good game.

Thursday, July 21, 2005

Bundles

Last night I upgraded my versions of Firefox and Thunderbird on Mac OS X. And then at work I did the same thing on Windows XP. The installation went pretty smoothly on both so maybe to most users the differences wouldn't be that significant but for someone like me who cares about little things like this, it showcased what I think is a pretty big features of Mac OS X, Bundles.

From Apple's developer documentation:
A feature integral to Mac OS X software distribution is the bundle mechanism. Bundles encapsulate related resources in a hierarchical file structure but present those resources to the user as a single entity. Programmatic interfaces make it easy to find resources inside a bundle. These same interfaces form a significant part of the Mac OS X internationalization strategy.

Basically it's a folder that looks like a file. It's a very simple but extremely effective method of hiding the details from the user. Most of the time, when you install an application in OS X you open a disk image and drag the application icon, the bundle, to some location on your hard drive. Then you double click it to run it. If you don't like where you put it then you drag it somewhere else. If you decide the app sucks you throw it (the one thing) in the trash. You don't use an installer or uninstaller.

On Windows on the other hand, it's never that simple. You almost always run an installer and then god knows what happens. While it's true that some Mac apps require an installer, especially if they need access to protected areas on the disk, it's the exception rather than the rule.

Like I said at the beginning, maybe most people wouldn't think this is a big deal but there is something quite satisfying about the installation/deinstallation process on a Mac. It's simple and obvious and you know what happened.

Tuesday, July 19, 2005

Dave Thomas on TSS

Dave Thomas is one of the two pragmatic programmers. The Server Side posted a transcripted video interview with him. Lots of great stuff discussing the differences between:
  • Test Driven Development and Test First Development
  • Agile and Extreme Programming
  • Strong Typing and Dynamic Typing
It's hard to argue with what he has to say. Definitely worth a listen/read.

Thursday, July 14, 2005

Cocoa

When I originally created this blog I named it after Apple's Frameworks for creating Mac applications, "Cocoa". At the time, I was working my way through Aaron Hillegass's book Cocoa Programming for Mac OS X. Since Apple gives away its development tools for free with their OS I had previously played around with it. But for one reason or another I found myself leaving OS X development and instead investigating technologies more closely related to Java (the language I use at work). I also recently spent a couple months looking at C# and .NET. But finally I'm back to looking at Cocoa and think I'm ready to compare Cocoa to Java and C#. Like my C# review so many months ago (February 2005) I'll try to comment on the things that make Cocoa different from Java.

But first of all, some history. Cocoa development is done in a language called Objective C (objc for short). It was invented in 1983 by Brad Cox at Stepstone. It is described as a thin layer on top of C so unsurprisingly, anything you can do in C you can do in Objective C. The so called "thin layer" adds Smalltalk-like syntax to add object-oriented features. Objective-C uses the open-source GCC (GNU Compiler Collection) and so people can program in Objective C on any platform. I've even written a small command line program on Windows just to prove that it can be done.

Secondly, Mac OS X's (and Cocoa's) heritage is NextStep. After Steve Jobs left Apple he founded NeXT computer in 1985 and in many ways created a computer that was ahead of its time. Part of that vision, often overshadowed by the media's attention to the hardware, was the object oriented application development environment called NextStep, based on Objective-C. This set of libraries (or frameworks) was ported to several platforms (Intel, PA-RISC, SPARC, etc.) during its lifetime and became known as OpenStep in a deal with Sun MicroSystems. When Apple eventually bought Next in 1996, the NextStep frameworks became known as Cocoa. To this day the classes in the framework all begin with the abbreviation NS. Interestingly, part of Next's work in the early 90's to make NextStep portable (specifically to Intel) is what is enabling Apple to switch the Macintosh's processor from PowerPC to Intel with such little trouble.

Namespaces and File structure
  • By convention, the interface is placed in a header file (*.h) and the implementation is placed in a file with the "m" extension (*.m). This violates the spirit of the DRY principle (Don't Repeat Yourself) because the method names are now in two places. But on the upside the class's logical public interface is easily communicated through the header file. It also gives you a way of protecting your source code while still allowing third parties to use your frameworks. Java and C# both suffer from being easily decompiled.
  • There are no namespaces in ObjC. Instead a naming convention suggests using an abbreviation at the beginning of each class name (e.g., all the Apple class names begin with "NS").
Misc
  • Like Java and all other C-based languages other than C#, Cocoa uses camelCase instead of PascalCase.
  • ObjC frequently uses the at-symbol (i.e., @) to differentiate ObjC functionality from standard C functionality.
  • Object references look like C pointers. (see next bullet point)
  • NSString is one of the most commonly used classes in Cocoa. Like Java, it stores immutable Unicode strings. Use the @-symbol in front of a C string to create an NSString instance. (e.g., NSString *name = @"Cocoa";)
  • C's printf String formatting functionality is included with NSString's factory method stringWithFormat:. The NSLog() function for printing to console also supports printf-type functionality. (BTW: Java finally got around to supporting this with Java SE 5.)
  • Like C#, ObjC uses a colon (:) for subclassing instead of Java's extends keyword
  • ObjC also uses the colon (:) for implementing an interface instead of Java's implements keyword.
  • Class methods are denoted with the plus-symbol (+) instead of Java's static keyword.
  • Instance methods are denoted with the minus-symbol (-).
  • Visibility identifiers are nearly the same as Java's except they use an @-symbol in front (i.e., @public, @protected, @private). And like Java, the default is @protected when it's not explicitly defined. The biggest difference is that methods are always public. Private-like methods are created by excluding them from the class's @interface.
  • Exception handling is the same in ObjC as in Java with the keywords @try, @catch, @finally, @throw except exceptions are not part of the method signature (like C#). Exceptions were new in Mac OS X 10.3 (Panther) so I doubt that they are utilized all that frequently.
  • Like Java, ObjC uses an #import keyword to include references to the classes that it uses.
  • Like Java, the Cocoa framework is a singly rooted class hierarchy starting with NSObject.
  • An interface in Java is known as a protocol in ObjC
  • instead of Java's instanceof, NSObject has several methods for accomplishing similar functionality, isKindOfClass:, isMemberOfClass:, conformsToProtocol:
Method Syntax
  • ObjC methods define labels for each parameter. For example, an instance method for a Person class might look like this:
    • - (Person *)initWithFirstName:(NSString *)first Last:(NSString *)last;
    • This method returns a Person instance and takes two NSString parameters.
    • The first parameter is described by "initWithFirstName:".
    • The second parameter has the label "Last:".
    • The full method name is: "-initWithFirstName:Last:"
  • Using Smalltalk-like messaging syntax you would cause this method to be invoked with something like this:
    • [person initWithFirstName:@"Bob" Last:@"Builder"];
    • More generically [object methodName:param1 Label2:param2];
    • The nice thing about this calling syntax is that it's easy to tell from the calling side what each parameter is for whereas in traditional C, Java, and C# you need some documentation to help out.
    • Like Java, each method call is dynamically looked up and invoked.
  • ObjC's object oriented features are based on Smalltalk. As a result, the idea of invoking an object's method is better phrased as "sending a message to an object". In ObjC it is completely valid to send a message to an object that cannot respond to it and you will receive no error. This stands in stark contrast to Java's strong type checking at compile time. When coming from a Java background this seems strangely odd, but as you become accustomed to this dynamic behavior you soon begin to recognize its power.
  • There is a special ObjC type called id that is a pointer to an object of any class. By judicious use of id and ObjC's dynamic message mechanism you can avoid a lot of typecasting that is so prevalent in Java code. Naturally you can (and should) use the variables and parameters of the types you are expecting but in some cases where the type cannot be known ahead of time the id type is very valuable and produces succinct easy to understand code.
Memory Management
  • To create an instance of an object use alloc (e.g., [Person alloc];)
  • ObjC's constructors are responsible for initializing instance variables. The default constructor is init. Constructors that take parameters use init as a prefix.
  • Typically alloc and init are called together (e.g., [[Person alloc] init];
  • ObjC does not include any kind of automatic memory management. There is no garbage collector. Instead Cocoa uses reference counting. You use the instance methods retain and release to increment and decrement the reference count. When the count reaches zero the object is freed.
  • The alloc method automatically increments the reference count by one.
  • ObjC's destructor is dealloc. It is responsible for releasing instance variables that point to objects.
  • There is a second instance method that you can use to express your intention to release an object called autorelease.
    • GUI Cocoa application automatically instantiate NSAutoReleasePool.
    • It is this object that becomes responsible for actually releasing your object at some point in the future.
    • This autorelease mechanism allows you to return new objects from a method and is frequently employed by class factory methods (e.g., [NSString stringWithString:@"This will create an autoreleased copy"];)
    • If the calling method does not retain the returned object then it will be automatically released.
    • It is the event loop in a GUI application that creates and destroys release pools.
  • In practice this memory management scheme is more error-prone than languages with garbage collection and requires diligence to implement properly. However, memory releases happen relatively frequently and the application's memory footprint is more predictable and manageable.
Inheritance
  • Use super to refer to superclass methods or variables.
  • Use self to refer to the instance's method or variables.
  • Constructors should call the super constructor first. (e.g., -(Person *) init{if (self = [super init]){/*initialize variables*/} return self;}
  • Destructors should call the super dealloc last (e.g., -(void)dealloc{/*free instance variables*/[super dealloc];}
Properties
  • ObjC is similar to Java in using accessor and mutator methods to get and set private instance variables. The only difference is that the get methods are named the same as the instance variable.
  • I prefer C#'s and Delphi's ability to declare properties as first-class citizens. I believe it makes the code easier to read.
  • Java didn't include operator overloading because it typically gets abused in practice. ObjC doesn't include it either but having seen C#'s and Ruby's implementations I think if used properly it could make code more readable (I say "could" because I haven't used either extensively and hesitate to say with certainty)
Selectors
  • When using Java's Swing components (a.k.a., GUI Controls) you typically register an event listener with each component to be informed when the user interacts with it (e.g., clicks on a button). Because each listener must conform to a specific interface you end up creating a lot of anonymous inner classes. The code's intention is lost in the overly-verbose mechanics. Even if the IDE is generating this stuff for you, it's still ugly.
  • ObjC's selector specifies the signature of a message and is not bound to any particular class.
  • Create one using @selector( selectorName )
  • Or use NSSelectorFromString(@"selectorName:") to create one from a string.
  • You can programatically invoke a selector using one of the performSelector:, performSelector:withObject: variants in NSObject.
  • InerfaceBuilder, the tool for creating user interfaces for Cocoa applications, uses selectors in the target/action paradigm to graphically wire visual controls to methods that look like - (IBAction) methodName:(id)sender; with absolutely no code.
Collections
  • Cocoa has NSArray, NSSet, and NSDictionary and their mutable counterparts, NSMutableArray, NSMutableSet, and NSMutableDictionary which are functionaly similiar to Java's List, Set, and Map interfaces and various implementations.
  • Cocoa uses NSEnumerator to traverse a collection's members which is similar to Java Iterator.
  • Cocoa doesn't have any of the syntactic sugar of Java or C#, such as Java's enhanced for loop but because of ObjC's dynamic messaging infrastructure the need for typecasting isn't nearly as onerous so perhaps it's not needed.
Categories
  • An interesting feature of ObjC called categories, is its ability to dynamically add methods to existing classes even if you don't have the source code for those classes. Now when you think "Why didn't they add a method that does blah blah blah", you can just add it yourself!
  • mixins provide a similar feature in Ruby.
  • NSObject also has a method called poseAsClass: which allows a subclass to stand in for its superclass. This subclass can override superclass methods and add new methods.
Summary

ObjC has no garbage collector and doesn't generate bytecode which are two pretty big features of Java and C# but regardless it has just about everything that those other languages have plus more. It is a good solid object oriented time-tested application framework and unlike Microsoft with its .NET framework, Apple "eats its own dogfood". It uses Cocoa extensively to build its applications (e.g., GarageBand, iPhoto, iCal, iChat, Mail, etc). I've been fairly happy with the toolset although I wish refactoring support was available in XCode (which is also at least partially built with Cocoa). Next step is to go into building a "real" application, stay tuned...

Tuesday, July 12, 2005

Airshow accident in Moose Jaw

My family and I attended the Saskatchewan Air Show in Moose Jaw, Saskatchewan on Sunday. We were treated to some spectacular aerobatic maneuvers. A couple of American F15s opened the show and then the SkyHawks, a Canadian Forces parachute team, took over with some great demonstrations. We were then treated to the Canadian CF-18 and the American A-10. Then there was a civilian act known as the "Masters of Disaster". The group consisted of three bi-planes (one jet assisted) and a jet powered truck. They each performed individually and were very impressive. Then in a finale all three planes got together for a mock dog fight.

But unfortunately on this day something went terribly wrong when two of the planes collided in mid air. Both pilots died. The entire crowd of 10-20,000 people were shocked. There was some initial confusion about what actually happened. Many thought the explosions were part of the show.

My wife and I discussed the incident with our kids who may be a bit too young to understand what they witnessed. We made sure that they understood the difference between the explosion they saw and the kinds of things they may see in a movie and that families lost fathers and brothers that day. Those men were experts in their business and knew the risks they were taking. I only wish that it would have ended like all the shows they had performed in the past...

Tuesday, June 28, 2005

Podcasting

Apple finally got onboard with podcasting by delivering a simple (and free) way to subscribe to podcasts via iTunes. Just go to the iTunes Music Store and select the podcasts that you're interested in, wait for the MP3 download, and start listening. The selection isn't huge at the moment but it does cover a wide variety. I subscribed to the "CBC Radio 3" podcast and the decidedly more adult "Dawn and Drew show". After you have the files, you can sync with your iPod and listen to them on the road and unlike radio you can skip, pause etc. Very cool. You can of course listen to podcasts with any MP3 player but Apple, in typical fashion, makes this really simple to use.

Friday, June 17, 2005

GIMP, BSD, Linux and Mac OS X

Let's start by talking about GIMP, the GNU Image Manipulation Program. I've used a few other graphics tools in the past including Adobe Photoshop (LE edition) and Paint Shop Pro and the height of awfulness, Windows'Paint brush. So I can say from this position of authority (not) that the GIMP is pretty good. It runs on Mac, Windows and Linux equally well. It supports layers, each with independent opacity values to dynamically composite an image. Text is treated as an object that can be easily changed. Bezier paths can be used for creating smooth paths and image selections. And I think the whole thing is scriptable (via Scheme) but I haven't gotten into that.

So the GIMP is pretty cool but what I recently discovered is that it's related to Mono... When I was messing around with Mono's implementation of WinForms (the C#.NET way to create Windows applications) I found myself using Fink to download and compile the source code for GNOME. Apparently Mono's WinForm implementation is tied to GTK+ and GNOME uses GTK+ as its base widget set which in turn is an offshoot of the GIMP project. (Starting to talk in circles here).

Now when I think about GNOME I think about Linux, but here I am running the GNOME desktop on my Mac. What's up with that? What exactly is Linux anyway? Well apparently what many people tend to call Linux (like a Red Hat distribution for example) isn't really just Linux. Linux is the kernel and the rest, the compilers, the bash shell, the command line applications, GIMP, and the GNOME desktop, are part of the GNU project. In fact, the GNU project was started in 1984 and Linus Torvalds didn't start work on Linux until 1991. The GNU project was working on a kernel too but Linus got there first. The Free Software Foundation even prefers people more accurately call it GNU/Linux with the GNU in front because they (quite accurately) are the major contributors.

So now I'm thinking well what the heck? How does BSD (Berkeley Software Distribution Unix), the base for Mac OS X, fit into all this. Well today's FreeBSD (from which OS X most heavily borrows), OpenBSD, and NetBSD distributions are descendants of the original AT&T Unix of 1970s. At some point in 1990s the BSD project attempted to free itself of AT&T copyright entanglements with replacements for all original AT&T Unix code. It was at this point that BSD came under legal scrutiny. It was under this legal ambiguity that Linux was created and prospered. In 1995 everything was squared away and BSD became truly free. And that's how we come to have two competing Unix-like open-source kernels. And it's probably because NeXT came before Linux that Mac OS X uses BSD.

Now if you throw out the kernel issue then I'm left with the impression that Mac OS X (sans Quartz, Cocoa, and all the other good Apple layers that sit on top) is more like GNU/Linux than I originally thought. Apple bundles a lot of the same GNU project stuff (like the compilers, the bash shell, the command line applications, etc). I'm even of the impression that because OpenStep ran on a host of other Operating Systems that if Apple were so inclined they could even put the Mac OS on top of Linux if they wanted. Ahhh Unix... I feel like such a newbie sometimes ;-)

Next time maybe I'll talk about all these crazy open source licenses: BSD, Apache, Copyleft/GPL, etc... Ahhh maybe not... ;-)

Thursday, June 16, 2005

.NET Disillusionment

Messing around with C# and ASP.NET has been pretty boring so far. Apparently my boss really meant:
do you want to do take over another developer's project which is really just the installation and configuration of the Microsoft Web Portal Starter Kit?
instead of:
how would you like to do some cool C# stuff for fun?
But as a diligent, "pragmatic" coder I familiarized myself with the code and data model (damn ugly), created a nant build script (which is almost exactly like Ant BTW), cleaned up the ASPX and CSS and checked the whole mess into CVS. Ho-hum.

So now that I've been using Visual Studio 2003 for awhile I have some not so nice thoughts about it. It has some okay graphical tools for working with XML and XSD but I'm not really thrilled with the junk HTML it spits out. It really should be creating XHTML and use CSS where possible. Even Nvu does that! And how about some integration to a source control tool other than VSS for crying out loud? And don't get me started on the code editor. Maybe I'm just accustomed to Eclipse now but I sure hope Visual Studio 2005 is a lot better than this (Anders thinks so).

And today Visual Studio decided to start hanging on me. All I'm trying to do is pin the toolbox panel. That's it! I can just hear all the MS-loving developers crying out "just reinstall!". And normally I might. But unlike an Eclipse installation which involves deleting a directory, downloading a new version and unzipping, I get the feeling that a VS/.NET installation is just a bit more involved and not likely to succeed.

Finally, my mono experiment came to a grinding halt. My Nant script required a bit of tweaking to get the application to compile (needed references to the core .NET assemblies for some reason) but it just won't run in XSP (the mono ASPX server). I keep getting a null pointer reference exception but without the ability to debug while running in the Mono runtime, I decided it's just not worth the effort. Maybe Java's not so bad afterall...

Monday, June 06, 2005

Mac on Intel

Well that one was a difficult rumour to believe. I've been pretty happy with my dual-processor 2GHz G5 since I bought it about 20 months ago. It's a well engineered machine with lots of memory headroom, a fast front-side bus, a decent graphics card, etc... and with Apple optimizing its OS for the past few years, things have even gotten faster than when I first bought my machine. So why switch?

Well apparently Jobs made the announcement that Apple will begin shipping Macs with Intel processors next year.

On the one hand I'm a bit disappointed that Apple will lose some of its distinctiveness. Will it just be a pretty box with the same guts as everyone else?

On the other hand, I'm happy that Apple will no longer have to try and prove that it's machines are as fast or faster than everybody else's. As long as it uses the latest and greatest from Intel, people can finally put that argument away (for the most part). Instead they'll have to focus on what counts, the user experience. That was my reason for buying Macs anyway.

Finally, as a developer, I'm very interested in being able to run Windows applications at full speed on a Mac once in awhile. Being able to do .NET development with MS tools if needed would give me the ultimate flexibility without sacrificing my ability to run the Mac OS and Mac applications for the majority of my computing needs... Maybe it's not such a bad thing... We'll just have to see how this whole thing works out.

Thursday, June 02, 2005

ASP.NET and Mono

I recently started on an ASP.NET C# application at work. But since I'm a Mac guy at home I didn't have IIS to play with. Fortunately The folks at the mono project have a little ASP.NET web server called XSP. Unfortunately it doesn't come in the Mono distribution but with a simple download (and a make) I'm in business. It runs and the sample pages seem to work. I have no idea how robust it is nor how compliant it is but for now I'm happy that it just works!

Tuesday, May 31, 2005

Computers, Robotics and Foosball

What a fantastic combination. I'm surprised I didn't try to come up with that one myself ;-) Apparently I'm too late, the University of Freiburg's (German city of about 200,000) Computer Science Department has developed KiRo, the table soccer robot:
KiRo is a completely autonomous table soccer playing robot: using a camera it perceives the playing field and, dependend upon the current game situation, it decides how the rods under its control should be moved.
Even better is that they commercialized it under the name StarKick. Now if you have a broadband connection go check out some video of what it's like to go up against a robotic foosball opponent. ;-)

Thursday, May 26, 2005

Quicktime 7, H.264 and HDTV

Although H.264 was originally going to be one of those gotta-have-it features offered in the latest version of Mac OS X Tiger, Apple decided to give it away with Quicktime 7. Currently it's only available for Macs and not Windows ("Quicktime 7 for Windows Coming Soon") so you need a Mac to see it but it's worth checking out.

I still have an antenna in my attic for viewing over-the-air broadcasts (a.k.a., peasant-vision) so I'll be the first to admit that I'm a bit quality-picture challenged. But expectations aside, when I downloaded a couple of samples from Apple's HD Gallery I was very very impressed! The 1080p version of the Batman Begins trailer is just huge! My crappy VGA monitor can't even display that resolution (1920 x 816)!

So what's next from Apple? Well it's difficult (if not impossible) to predict. Apple was late to the whole MP3 thing when they introduced iTunes. They weren't the first with a portable hard drive based MP3 player, the iPod, and they weren't the first with an online music store either but look where they are now. They dominate. Microsoft has a Windows XP Media Center and both they and Sony with their next generation game boxes are vying for a spot in the living room. But Apple has the technology, the ingenuity and the ability to make products that resonate with consumers so I'd expect to see something from them that not only embraces the Mac and iLife (as digital hub) but goes beyond to make digital video simple and approachable to the masses.

[Update: I found this blog where the author goes into quite abit more depth. He sounds way more upbeat than me!]

Tweaking log4j

Despite the inclusion of logging APIs into the JDK since 1.4, I still continue to use log4j for my logging needs. Generally I'll also use the commons logging API on top of log4j so that if I should ever change my mind and want to use the "built-in" logging facilities it will be easy.

My recent foray into production deployment highlighted one of the problems with my standard configuation. I have the typical log4j.properties file in the root of my source directory, and log4j is quite happy to find it there. The problem is that it eventually gets buried inside a JAR (Java ARchive) which is inside a WAR (Web Archive) when I build my application and therefore it's not very easy to change the logging parameters once my application is deployed. Specifically, the location of the generated log files is now essentially hard coded, which sucks for deployment.

Fortunately there's a way out of this. If you specify the location of a log4j.properties file in a Java system property called log4j.configuration, log4j will use that file instead of the one buried in your classpath. The only trick is to specify the location as a URL:

java -Dlog4j.configuration=file:/e:/log4j.properties ...

If you're using a Windows Service for starting an instance of Tomcat you can add a system property to the registry value found in HKEY_LOCAL_MACHINE/SOFTWARE/Apache Software Foundation/Procrun 2.0/Node1/Paramaeters/Java/Options where Node1 in my example is the name of your instance of Tomcat.

Secondly, if you're want to define the location relative to a Tomcat installation you can use a dynamic location like this within your log4j.properties file:

log4j.rootLogger=error, R

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.base}/logs/MyApp.log
log4j.appender.R.MaxFileSize=200KB
log4j.appender.R.MaxBackupIndex=2
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}] %5p (%F:%L) - %m%n

Notice the ${catalina.base} expression. The nice thing about this in a clustered environment like I described yesterday is that you can use the same log4j.properties file for all the instances of Tomcat and can change the configuration for all of them all at once.

Wednesday, May 25, 2005

Tomcat and IIS

I've been busy lately deploying my latest Java web application to production. It's been a bit of an adventure since I don't usually get to play the deployer role. Fortunately I already had my Ant script building the WAR (Web ARchive) file so I was only working on deploying to Tomcat 5.5.9. The twist is that I was deploying to four instances of Tomcat on two physical Windows 2003 servers fronted by the latest version of IIS.

The only reason IIS is involved at all is so that I could use the JK 1.2 Tomcat Connector to do the load balancing. This connector works as an ISAPI Filter and intercepts requests to my appliction (based on the URI) and forwards them on to an instance of Tomcat running my application. The connector does a weighted round robin load balancing and ensures that a request that is tied to a particular session on a particular Tomcat instance (from a previous request) is directed back to that same Tomcat instance.

But perhaps I'm a bit ahead of myself. Let's back up to the Tomcat installations. The first thing I wanted to accomplish was the sharing of the Tomcat JAR files among the various instances of Tomcat. By doing that, I know all Tomcat instances are running the same version and upgradable in one shot. The steps were:
  1. Unzip jakarta-tomcat-5.5.9.zip
  2. Rename jakarta-tomcat-5.5.9 to tomcat for simpler upgrading in the future (if only Windows had symbolic links)
  3. Create a directory called tomcat-cluster-node1 that looks something like this (the files in the subdirectories were copied from the standard Tomcat installation):


/tomcat (renamed from jakarta-tomcat-5.5.9)
/tomcat-cluster-node1 (The subirectories' files are copied from the tomcat
installation.)
/bin (contains service.bat)
/conf (contains catalina.policy, catalina.properties, context.xml,
server.xml, tomcat-users.xml, web.xml)
/Catalina
/localhost (contains manager.xml, host-manager.xml, myapp.xml)
/logs (empty)
/temp (empty)
/webapps (empty)
/work (empty)

Because this installation is on a Windows server I decided to follow the adage "When in Rome, do as the Romans do" and make my Tomcat instances run as Windows Services. Fortunately Tomcat is ready to go with a Tomcat5.exe and a batch script to create the registry entries call Service.bat. The only changes I had to make to the batch file were a few lines at the top to set some environment variables:

set CATALINA_BASE=E:\tomcat-cluster-node1
set CATALINA_HOME=E:\tomcat
set JAVA_HOME=E:\jdk1.5.0_03

then I ran "Service.bat install Node1" and I now have a service that I can easily start and stop. You may want to change the service to "Automatic" to ensure that it gets restarted in the event of a server restart.

Now back to the Tomcat connector installation. I like keeping the redirector stuff separate from the tomcat installation so I created a directory called /tomcat-iis-connector that contains the following files:

isapi_redirect.dll (downloaded from the jakarta site)
isapi_redirect.reg (see below)
uriworkermap.properties (start with a copy from the tomcat/conf directory)
workers.properties (ditto)

The reg file contains some registry entries that the DLL uses at runtime to find your configuration information. Mine looks like this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0]
"extension_uri"="/jakarta/isapi_redirect.dll"
"log_file"="e:\\tomcat-cluster-node1\\logs\\isapi.log"
"log_level"="error"
"worker_file"="e:\\tomcat-iis-connector\\workers.properties"
"worker_mount_file"="e:\\tomcat-iis-connector\\uriworkermap.properties"

Now you have to actually tell IIS about the redirector DLL (notice the /jakarta/ prefix in the extension_uri entry in the reg file. This becomes important in a moment)
  1. Open IIS Manager and create a new Web Site.
  2. Create a virtual directory called "jakarta". This name must be the same as the prefix from the extension_uri value in the registry, and it must be executable.
  3. Go to the "ISAPI Filters" tab of your website's properties dialog and add a filter that points to the isapi_redirect.dll
  4. In the "Web Sites" properties dialog's Service tab select the "Run WWW service in IIS5.0 isolation mode" checkbox.
  5. Disable session state for your website (Properties dialog->Home Directory tab-> Configuration...->Options tab). Just let Tomcat handle your session timeouts.

Now all you have to do is configure your workers.properties file. Mine looks like this:

workers.tomcat_home=E:\tomcat
workers.java_home=E:\jdk1.5.0_03

ps=
worker.node1.port=8009
worker.node1.host=localhost
worker.node1.type=ajp13
worker.node1.cachesize=10
worker.node1.cache_timeout=600
worker.node1.socket_keepalive=1
worker.node1.recycle_timeout=300

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=node1
worker.loadbalancer.sticky_session=1

worker.list=loadbalancer

And then in the cluster-tomcat-node1/conf/server.xml make sure you identify the server with the same name you used when defining the worker in workers.properties, in this case "node1". Without this the "sticky sessions" won't work.

<engine name="Catalina" defaulthost="localhost" jvmroute="node1">

At this point I've only described the installation of a single Tomcat instance, but in reality I have four tomcat instances. So you can imagine more tomcat-cluster-node directories and a few more entries in workers.properties and the addition of those worker names to worker.loadbalancer.balanced_workers:

worker.loadbalancer.balanced_workers=node1, node2, node3, node4

Next you must define the URIs that should get redirected from IIS to Tomcat in the uriworkermap.properties file. Mine looks like this (of course you'll need to change the value of "mycontext" to the context of your app:

/mycontext/*.jsp=loadbalancer
/mycontext/*.do=loadbalancer
/mycontext/*.exe=loadbalancer
/mycontext/*.jpg=loadbalancer
/mycontext/*.gif=loadbalancer
/mycontext/*.png=loadbalancer
/mycontext/*.css=loadbalancer
/mycontext/*.js=loadbalancer
/mycontext/*.jpeg=loadbalancer
/mycontext/*=loadbalancer

Normally, I would like IIS to serve all my static content but I use struts tags to specify the location of images and the JSTL c:url tag to dynamically generate URLs. These tags rewrite the URL and not only include the name of the context (which is configurable at deployment time) but also include the jsessionid in the URL when not using cookies. Unfortunately IIS can't figure out what to do with the jsessionid so your pages come back without CSS or images. Not only do they look pretty awful but if you use js files some functionality may not even work. So I just map everything to Tomcat. On the plus side, deployment is simpler with the single WAR file.

Finally restart IIS and hope everything works! :-)

Monday, May 09, 2005

Updating my Resumé

I recently decided to update my resumé and decided that instead of using a proprietary document format that I would use HTML. If you think about it, a resumé is a great document for HTML. There's no need for an index, foot notes or a table of contents and the elements that remain aren't very complicated either. You have a couple levels of headers, some bulleted lists, and maybe a paragraph or two.

My initial step was to take my RTF document and dump it in a WYSIWYG editor. I used Nvu. I kept everything plain vanilla (no fancy fonts, font styles or colours) and basically edited away. When I was done, I had a factually correct document. The HTML was pristine and wasn't mucked up with a bunch of tags describing appearance. But on the other hand it was an incredibly boring looking resumé. No one was going to give me any extra marks for style.

So I decided I'd spice things up with some CSS. I ditched the WYSIWYG editor and broke out my favourite code editor, jEdit. The first step was to make everything XHTML compliant. I put in the correct doctype, made everything lowercase, closed every tag, and put quotes around all attributes. Then once that was passing the W3C XHTML validator I added a style section to the header and started editing. (Normally I'd use an external CSS and link to it from my HTML but I figured I'd probably be e-mailing my resumé to people and didn't want them to have to worry about multiple files)

The one thing that I wanted to avoid was adding structure to my document just so that I could lay things out (i.e., I didn't want to add tables all over the place just for the sake of layout). Secondly, I wanted the document to still render properly if someone decided to turn off stylesheets entirely within their browser. So I introduced several div elements as containers so that I could style and position blocks of content. My document is pretty hierarchical so this was actually pretty simple and wasn't really breaking my rule about adding tags for layout. As I worked I needed to read a bit more about CSS topics I had only briefly touched on in the past (specifically, float, relative and absolute positioning). I also had to decide on some colours and fonts but I just used some of my favourite sites as templates for those choices.

In the end I have an XHTML/CSS standards-compliant document that looks good in Firefox, Mozilla, Camino, Internet Explorer, and Safari. The content and the visual appearance code is nicely separated, even if they are in the same document, and it serves as a nice little showcase for my appreciation for standards and my ability to apply them to a web application.

I got my first callback. Was it the content or the styling? Maybe a bit of both. ;-)

[Update: I forgot to mention that the Firefox "Web Developer" extension is a great tool for graphically viewing outlines around the structural element of your HTML document and for seeing what would happen if CSS, graphics, or other browser functionality were disabled]