Archive for February, 2007

Martin Fowler, live in Melbourne

Monday, February 26th, 2007

Last Friday I attended a packed breakfast seminar to hear Martin Fowler speak. The event was put on by Enterprise Java Australia. After filling the original venue, it was moved to Melbourne Town Hall. All up there must have been around 300 people who dragged themselves out of bed early to eat bad food, drink bad coffee, and sit in uncomfortable chairs for 2 hours to hear Martin speak.

Disclaimer - the following is all based on my early morning, caffeine-deprived memory of the talk. Any resemblance to actual events or persons alive or dead is purely co-incidental

The event was titled “Software Design in the 21st Century”. Martin started by explaining that this was an intentionally vague title that would let him talk on whatever he felt like on the day.

Java’s Progress for the last 10 years

The talk opened with Martin talking about how far Java has brought us over the last 10 years (in spite of any short comings, which were discussed next…). Both in terms of the language and platform, and in terms of the greater community.

  • Don’t have to worry about memory management and related bugs anymore
  • Dynamic open source community, especially when compared to .NET land
  • Test driven development has been embraced
  • Solid platform to develop on - as in the actual Java VM

Java’s Weaknesses

Martin then did a round up of the audience to get the perception of pain points in Java, (and added a few of his own).

  • J2EE in general, EJB in particular
  • J2ME. Tired of "Starting Java…" on mobile phones for little added functionality
  • Unnecessary XML overload - configuration files, data transfer
  • Date/Calendar API
  • Lack of any currency support considering how many financial applications are written in Java
  • Lack of advanced features like closures
  • Applets
  • J++ fiasco and resulting souring of Sun/Microsoft relations hurting Java in the browser.
  • Swing
  • Multi-threading. Or rather the fact that "Only 5 people in the world actually understand concurrency" and "A license should be required before developers are allowed to create new threads"

Java’s near future

Martin said he didn’t claim to be a futurist, and preferred just to talk about recent and current trends and only look at the near term. This was the bulk of the talk, and was the most interesting section.

  • Java as a language will decrease in importance, while the Java VM as a platform will increase as it becomes more common for other languages to run on it (eg JRuby). Applications will only write the core code in Java, and use more productive languages for the implementation layers where most development time is spent.
  • Concurrency will become more of an issue on the desktop as multi-core systems become more common. This will be less of an issue for backend server development as developers are already used to developing logically segmented, shared-nothing systems to increase thoughput anyway. Languages like Erlang running on the VM may help with this
  • Java frameworks with the Rails philosophy of narrowly defined scope and high productivity will emerge as developers tire of the complexity and overhead of general purpose, complex frameworks such as Spring and J2EE

All up an interesting talk. Nothing ground breaking, but most of it fitted with my thinking on Java’s direction - especially the discussion of Rails type frameworks, which is exactly what I was getting at in my last post on JRuby Can Save Swing.

I expected Martin to be American for some reason, he’s actually English.

JRuby can save Swing

Thursday, February 15th, 2007

Swing is hard. Needlessly so. With the advent of scripting support on the JVM, why not wrap a light and elegant Ruby layer around Swing? Why keep coding Swing at it’s lowest API level using a heavy-weight language like Java?

I’ve always maintained Swing is a nice framework. It’s just that it’s too low level and Java is a lousy language for programming it in. It’s already possible to code Swing in Ruby by using JRuby. You get some of the Ruby niceness (such as easier method calls, some dynamic typing, and blocks), but you still end up fighting against listeners, layout managers, look-and-feels, event-threads etc before long. Suns trademark API over-engineering casts a long shadow, even into Ruby land.

The Swing API itself is very flexible and powerful, but at a low level. It’s powerful in the same way that a coil of wire and a bunch of tools is a flexible and powerful way to configure the electricals in your house. It’s just that sometimes you only want to plug a few things in and flick a switch to watch a DVD.

So what specifically are the problems?

Swing’s issues

Joshua Marinacci’s blog post Swing has failed. What can we do? from 2003 covers this issue nicely. Joshua points out these flaws which I’d agree with 100%. Nothing much has changed in the years since, except maybe that Swing looks somewhat better now and resembles native apps much more closely.

  • "Swing apps are slow to build."
  • "Swing layout managers suck."
  • "Swing apps are hard to maintain."
  • "Swing is too powerful."
  • "No native features."
  • "Swing apps have a bad history."

What needs to be done?

Joshua’s ideas on what needs to be done to fix Swing are interesting.

(there are more points he makes, but I’m just including the relevant ones)

  • "A structured way of building Swing apps. Something like Struts where each concern (aspect?) has it’s own special place to be stored and manipulated. How do you organize your layout, workflow, validation, intz’ed text, and hooks to the BL? Should you subclass to make frames or use factory code? We need a set of best practices and then a framework to implement them."
  • "A standard cross-tool representation of a GUI that is not Java code. Something that can be moved in and out of different IDEs and build tools. Probably an XML representation or maybe serialized Swing objects."
  • "An intermediate API. Maybe we need a simpler API on top of Swing? A new set of wrapper components which hide a lot of the complexity. Hell, half of the work could be done by just conditionally hiding 3/4 of the API from the Javadocs."

I particularly like the idea of a structured way of building Swing apps. At the moment it’s a free-for-all. Some developers have come up with nice individual patterns for maintaining order, others implement spaghetti, most start out well, but degrade into entropy. This even applies individual screens in some apps! - I’ve seen 6000 line long, single-class monstrosities for a single window! One of Rails main strengths is it’s “Convention over Configuration” approach for separating out and structuring an application. There is no reason why this can’t apply to a Rich Client.

My Ideal Swing/Ruby framework features

So… what would this look like?

  • Structured application layout. Works for Rails. Nuff said.
  • Proper decoupling of model from view. Probably using Martin Fowler’s Presentation Model pattern, or similar.
  • Automatic binding of model to view without glue code. (this makes the last point much easier to implement.) Ruby is perfect for this. You should be able to write something like name_field.bind_to song, :title and be done with it. Ruby should do it’s thing and set up listeners automatically - Even if the model class wasn’t designed with listeners when it was coded.
  • View logic code separated from layout markup. View components and interaction (enable this button with this tooltip etc) should be coded in Ruby. Layout should be stored in a YAML file or similar (please no more XML…). Layout via coding is far too hard for most people to use effectively. Minimize the pain and let the framework take care of the grunt work. We definitely DO NOT want anymore GridBag boilerplate code…
  • Application lifecycle support. Related to having a structured application layout. Provide session support, long lived models etc, and handle startup/shutdown.
  • Minimize the amount of code. You already get this for free by using Ruby, but removing the fluff from Swing is a must. Too much code to achieve too little. It should be possible to scaffold something basic like Rails does, then tweak it if it needs to do more. DRY is part of this, but that just seems like basic common sense for any kind of development in any language.
  • Minimize complexity. Related to minimizing code. Making it easy to use a proper pattern like Presentation Model and removing a lot of the spaghetti listener code by using bindings will help a lot.
  • Testable. It’s really hard to write automated tests for GUIs. Libraries like JFC Unit make it easier, but it’s still pretty heavy going. I don’t know the answer to this one. GUIs always need at least some manual intervention to check the visual layout (a computer can’t tell if it doesn’t “flow” right). Maybe the framework could help by making it easy to substitue mock objects for testing the presentation model code.
  • Make the Right way of doing things the path of least resistance.. This one is important, and I think it is one of Swing’s big weaknesses. This is related to having a good structure, but it goes from there all the way down to how easy the APIs are to use. Rails makes it easy to create good designs and stick to them. Swing makes it hard - as evidenced by the plague of badly thought out Autonomous Views espoused by Sun’s Swing tutorials

Even a few of these points would make Swing much more productive and fun. I’ve made a few posts recently that are leading up to this. Over the next few posts I’ll start to experiment with a few more of the pieces to see how it all hangs together. Who knows, maybe I’ll actually get something usable at the end :)

Parallels RC2, Boot Camp, Windows XP, OS X - One Happy Family On My Mac

Tuesday, February 13th, 2007

I’ve been using Parallels for a while now to run Windows on my iMac. It’s good for day to day work type stuff. We write client/server software with a Windows client, and PL/SQL Developer is one of the best Oracle developer tools, but is Windows only. However, for more graphically intensive, interactive, networked applications its performance is a bit below par - by which I mean it doesn’t work.

Up until now I’ve had to scavenge around the office and camp some random, vacant low-spec PC when the after hours LAN sessions start. Its a little frustrating when my Mac box has enough grunt to run the games we play (mostly the ‘old but good’ titles from a few years back).

Enter Parallels RC2 (build 3150), with the nice feature of being able to run a Boot Camp Windows install in a virtual machine in OS X. After a couple of hours all the pieces are in place and living together like one big happy family - or at least one of those families with the weird distant relative with stability issues and poor hygiene that everyone awkwardly puts up with on occasions when they have to interact with them, but really can’t stand them (I’m looking at YOU Windows).

End result is that you’ve got a single Windows install, but with the option of booting it to either run natively via Boot Camp (with PC-level performance for Windows apps), or to run it as a VM via Parallels (can run alongside OS X in a window)

Install

The install was pretty straight forward. The Boot Camp docs explained the steps nicely. Once the Boot Camp install was done, its a simple matter to import it into Parallels. All up the install process only took a couple of hours - most of that was installing Windows.

The only trick is deciding whether to format the Windows partition with FAT32 (can see drive from OS X, 32GB limit), or NTFS (larger drive size, better disk usage). I ended up going with FAT32. Maybe I’ll change that latter, but it’s going to require deleting the partition with Boot Camp, recreating it, and reinstalling Windows

Weirdness

Sticking all these round pieces into square holes is handled pretty well by both Parallels and Boot Camp. They’ve both done an admirable job of making it as seamless as it is, however there are a few quirks along the way

  • Windows XP Activation. I had previously been running my copy of Windows XP in a pure Parallels VM. Reinstalling in boot camp was detected as totally different hardware by Windows, which then told me my key was invalid. Likewise when the install is imported into Parallels it is also detected as yet another change. This required a separate call to Microsoft to activate each configuration and a little bit of sweet talking to convince the operator that I’m not driving MS to bankruptcy by installing one copy twice. The magic words they want to hear are "I’m reinstalling Windows XP on the same PC", which is sort of true (if not quite the technical explanation). I was wondering if the same Windows install would complain about being activated twice with two different configs, but so far it seems OK.
  • Parallels doesn’t like windows formatted USB drives. Parallels was running fine for a couple of days, then when I came in the next week it refused to start windows, complaining that "More than one Windows partitions are found. This is not a standard Boot Camp configuration.". Huh? What had changed? I’d plugged in my iPod - which is Windows formatted. This confused Parallels. Unplugging the iPod and trying again worked fine. Once the Windows VM is running, it’s fine to plug the iPod back in. The same thing happened with an NTFS formatted external hard drive as well.

All up I’m pretty happy with the set up. Gave it a blast with some Quake 3 action last night and had a great time. Admittedly it’s a pretty old game, but it ran flawlessly with a great frame rate at highest detail. Now I just gotta get in some more practice to not get my butt handed to me by the guys in the office (I beat all the bots though :P )

Bombscared!

Friday, February 9th, 2007

A bit of excitement in the office today.

Had to evacuate from the 34th floor due to a bomb scare. We’re back in now, but no word on how the situation was resolved in the end. Took 30 minutes to get down the stairs at a snails pace. It’s easy to forget how high I work everyday when the express elevator gets me here in a few seconds. Glad it wasn’t actually anything urgently life threatening, or I could have been fried by now :P

The road outside was crawling with police, fire fighters, and bomb squad people. The first worrying sign was when I spotted a fire fighter with a big vest labelled “SCIENTIFIC OFFICER” - you don’t get those guys called out for the everyday office fire drills…

From the Herald Sun

Bomb scare in office tower

Matthew Schulz

February 09, 2007 11:58am

HUNDREDS of workers were evacuated from Melbourne’s Commonwealth Bank Centre after a suspicious device was found on the 22nd floor.

Police blocked off Bourke St in Melbourne amid the scare, which brought part of the city to a halt.

Bomb squad officers rushed to the Commonwealth Bank Centre office tower, after police were alerted to a suspicious package being found on the 22nd floor soon after 11am.

By 11.30am the order was given to evacuate the building.

Police initially believed the object could have been a home-made incendiary device, but the bomb squad declared the package safe by about 1.30pm.

Police spokesman Adam West said a section of the road between Queen and Elizabeth streets had been cordoned off, stopping all vehicle pedestrian and tram traffic heading west, as while six fire trucks and several ambulances descended on the scene.

The scare also caused major disruption to the 41-floor finance hub, the base for thousands of workers.

The Commonwealth Bank’s regional manager for Victoria and Tasmania Richard Porter said the bank occupied about a dozen floors of the building with more than 500 staff, and the scare had caused major disruptions to operations.

“It’s the main centre for us in the city, including a major bank branch as well as the state’s loan processing centre,” Mr Porter said.

Transparent Property Change Listeners in Ruby

Wednesday, February 7th, 2007

One of my side projects is a framework for building Swing apps using JRuby. I’ve always maintained that Swing is a nice framework - it’s just that Java is a lousy language for writing it in.

One of the areas that Swing is weak in, is binding components to the underlying model. For those unfamiliar with Swing, its designed with a nice way of loosely coupling the model to the GUI components. This is done using listeners - typically Property Change Listeners - which fire whenever the value of some property changes and can be coded to explicitly replicate the state from the model to the view or (vice versa).

…Which is really nice in theory, but in practice it’s not a clean or easy task. It’s usually done badly as there is so much glue code to write if you want a nice pure OO design (developers hate writing boiler plate code). There are Java frameworks like JGoodies Binding and the PropertyChangeSupport class built into the JDK that help out, but in typical Java style, these can get quite complicated, and still require you to carefully manage new Objects to make sure they are manually bound correctly. It usually just ends up being a burden in real life which no one follows properly. (For an example of how NOT to write Swing properly - see Sun’s own Swing tutorials…)

I figured it should be possible to do this in a more Rubyish way. Something that is smooth and easy to use, and provides the best practice as the path of least resistance. I googled a bit and found RubyBeans revisited by Olivier Ansaldi, which seems cool… but involves having to subclass your bean classes from a common base class - some thing I was wanting to avoid. Ideally, the bean classes should be pure and simple Ruby classes build with attr_accessor. (what you’d call a POJO if were in Java land - although this concept is so obvious in Ruby I haven’t even come across a name for it)

Here’s what I came up with:

class ListenerSupport

  public
  def self.listen_to(klass, *properties)
    setup(klass)
    properties.each do |p|
      klass.class_eval do

        alias_method "#{p}_orig=", "#{p}="

        define_method "#{p}=" do |value|
          old_value = send "#{p}"
          send "#{p}_orig=",value
          fire_property_changed p, old_value, value
        end
      end
    end
  end

  private
  def self.setup(klass)
    klass.class_eval do

      def fire_property_changed(prop,pre,post)
        return if pre == post
        @listeners[prop].each do |l|
          l.property_changed(self, prop, pre, post)
        end unless @listeners.nil?
      end

      def add_property_listener(prop,listener)
        @listeners ||= {}
        prop_listeners = @listeners.include?(prop) ? @listeners[prop] : []
        @listeners[prop] = prop_listeners
        prop_listeners << listener unless prop_listeners.include? listener
      end

    end
  end

end

The general idea is that the original class is modified so that all properties that are listened to have their accessor write methods intercepted, and any property change listeners are notified when that property changes.

Let’s walk through how it works:

  • A standard Ruby class with property accessors is created. e.g.
    class RubyBean
      attr_accessor :foo, :bar
    end
  • A call to ListenerSupport.listen_to is made to modify the class to allow properties to be listened to.
    ListenerSupport.listen_to RubyBean, :foo, :bar
  • listen_to adds methods add_property_listener and fire_property_changed to allow listeners to be added to RubyBean for specific properties.
  • listen_to then aliases the original methods foo= and bar= to foo_orig= and bar_orig=. New methods for foo= and bar= are defined that delegate the work to the original method, then call fire_property_changed to notify the listeners.
  • Listeners are called, and any custom action (such as GUI component binding) can be carried out.

An example of this in action

class BeanListener
  def property_changed(obj, property, old_value, new_value)
    puts "#{obj.to_s} updated property:#{property}. old:#{old_value}. new:#{new_value}"
  end
end

class RubyBean
  attr_accessor :foo, :bar
end

ListenerSupport.listen_to RubyBean, :foo, :bar

bean = RubyBean.new
bean.add_property_listener(:foo,BeanListener.new)
bean.add_property_listener(:bar,BeanListener.new)
bean.foo = foo1
bean.foo = foo2
bean.bar = bar1
bean.bar = bar2
bean.bar = bar2

Which outputs:

# updated property:foo. old:. new:foo1
# updated property:foo. old:foo1. new:foo2
# updated property:bar. old:. new:bar1
# updated property:bar. old:bar1. new:bar2

Which shows that the listener is being called each time the property changes :)

Although this doesn’t show any kind of GUI binding, it does show how easy it is to make ordinary Ruby classes (or even Javabeans in JRuby) behave as if they had property change support built in from the start. It’s an important piece of the design a smooth and easy GUI binding framework.

Update - Fixed code after feedback from Pit Capitain in comments - should have used class_eval rather than instance_eval to define new methods in setup()

Ruby / Oracle / Mac OS X pain

Monday, February 5th, 2007

Environment setup is one of the worst aspects of software development. You can get all hyped up about the latest and greatest technology and techniques, but at some point you’ve got to get your environment set up so you can use them. I’ve spent a good part of this afternoon trying to get Ruby to work with an Oracle database on my Mac OS X box.

Simple huh? Nope. Mostly just old fashioned pain.

A bit of googling initially pointed me to the ruby-oci8 project, which provides a Ruby library for Oracle. I happily download and started working through the install instructions which involves compiling the library. Fine - except for the compilation problems. Seems my Oracle Instant Client install isn’t quite complete.

Next step is a trip to Oracle’s website, which is an altogether separate exercise in frustration - after eventually reviving my developer login (with the help of mailinator and Borat), I stumbled around clicking through a “terms of use - sell your soul agreement” for every… single… page… I eventually find the download I’m after. Cool.

I try to compile ruby-oci8 again, but this time I come up against:

Oracle doesn't support intel mac.
 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/223854

There are three solutions:
1. Compile ruby as ppc binary.
2. Wait until Oracle releases mac intel binary.
3. Use a third-party ODBC driver and ruby-odbc instead.
    http://www.actualtechnologies.com/

By this time about 2 hours have gone by, and hair is being pulled out in clumps. Admittedly I would have known this if I’d just read the platform specific issues on the ruby-oci8 site.

By now it’s 6pm, and the evening round of CS is starting up. I’ll save this one for tomorrow. Maybe I’ll play around with ODBC, or possibly try using a JDBC driver and using JRuby instead.

The ironic part is that I’m just wanting to "quickly" mock up some code to test out something that will later be implemented properly in Java (oldschool, heavy Java). At this rate it probably would have been quicker to do something quick and nasty in Java and be done with it (which isn’t *that* bad with Eclipse). Lately though, I’m shuddering at the thought of file after file of needless case handling, redundant interfaces, xml config files, and over engineered Sun APIs - even for simple stuff. Environmental pain is probably the lesser of two evils in the long run.