Tuesday, May 13, 2008

My first JRuby contribution

I've reported lots of bugs before but this is the first time I submitted a fix back to an open source project.  The fix was to the JRuby-Extras ActiveRecord-JDBC project to allow you to do something like this for a Rails model class against Oracle:  

class Person
  set_table_name "department.people"
end

Accessing the database from someone other than the schema owner and therefore fully qualifying the table with schema is a rule I needed follow in order to deploy a webapp in my current IT department.  

I posted the original fix quite a while ago but nobody really took notice. Then Jesse Hu came along and made it better (and probably independently I might add) and also added a couple other fixes for things I hadn't noticed.  

But unfortunately neither one of us seemed to really know how to submit the fix so it got ignored for awhile.  Originally I created a patch and just pasted the text into the body of my comment.  Jesse attached the entire Java file.  A few days ago when Thomas Enebo asked for things we'd like to see fixed in the next release of JRuby I jumped at the chance.  After I got a hint about what to do from Charles Nutter, I got the latest version of the project from SVN, created a .patch file from Jesse's source, and then submitted it back to the JRuby-Extras Tracker and then finally back to JRuby's JIRA issue.

Today I got notice from Nick Sieger that it'll be in the next version.  Very cool.

Unfortunately I have to admit that I still a need a bit of work on my testing skills because I wasn't able to figure out where or how to insert some unit tests to prove that my fix worked.  Something to save for the next time. I'm just happy I can finally get rid of my custom version of this library.

Wednesday, April 30, 2008

Rails on Windows

I've been working on a Rails project at work for the last few weeks.  We've been targeting JRuby for deployment and therefore I've been working primarily in JRuby for development.  This week I thought it'd be nice to get running with the regular MRI with MySQL instead of Derby.  I installed cygwin and tried to get back to doing things at the command line (I've been using NetBeans)...  I was getting tired of the performance hit I was taking every time I ran a rake task or a generator or started up Mongrel.  I was under the impression that the MRI ran as well on Windows as it does on my Mac.  Not even close.  Performance still sucks and managing the differences between my JRuby installation and my cygwin hosted Ruby isn't much fun.  I'm about ready to bail and just go back to JRuby.  Now I know why people buy Macs to do Rails development.  It rocks.  Rails development on Windows on the other hand truly sucks.  Thank goodness JRuby and NetBeans are there to hand me a few niceties.  Otherwise I'm not sure I'd have the patience for it.

Sunday, March 09, 2008

The iPhone SDK

I don't own an iPhone and since I'm in Canada I can't even buy an iPhone from Apple even if I wanted to, but that hasn't tempered my enthusiasm for the new iPhone SDK.  Like so many thousands of others I downloaded the SDK as soon it was available, installed it, and then started coding away.  I'm sure more experienced Cocoa developers were able to quickly bang out something cool, but not me.  It took me a bit longer to get the mandatory "Hello World" running, but nonetheless, my previous Objective-C/Cocoa investigations definitely came in handy.  I think one of my mistakes was thinking that the videos Apple put up would help me.  IMHO, don't bother.  Go right for the developer documentation in XCode instead.

Alas, I can't really say that much about the SDK.  I clicked through one of those license agreements and I'm sure that there's something in there that forbids me from revealing anything too juicy.  But I think it suffices to say that I'm still enthusiastic about where this is going.  I think the iPhone (even though I don't have one yet) is a great bit of technology and once in the hands of people in the enterprise who suffer at the other craptaculous mobile devices out there, they'll definitely start demanding stuff.  And that's where I fit in.  I'm excited to see how this all evolves and hope I'm ahead of the curve at least momentarily. ;-)

Sunday, March 02, 2008

Javascripting with ExtJS

Back in the early days of my work in Java I adopted the typical Java developer's bias against Javascript. Whenever someone would mention Javascript I would cringe. Afterall, why would I choose Javascript when I had Java? But I always felt I was missing something.

So last year I decided to do something about it and integrated the Prototype Javascript library into my Struts application.  I quickly learned that I didn't hate Javascript but hated the inconsistencies in the browser DOMs and learned to properly direct my hate  (Internet Explorer, I'm looking at you!).  

Despite a couple hiccups, that project was really quite enlightening and I went on to expand my knowledge with a great series of videos at the YUI Theatre. Douglas Crockford has three series of videos that I highly recommend to anyone wanting to learn JS. He goes over the history of Javascript and plainly spells out Javascript's problems and strengths (e.g., it supports functions as first class objects with support for closure, hashes are all powerful, prototypical inheritance is different than classical inheritance but is quite workable, and be careful of the default global namespace).

So now armed with a proper understanding of the language, I started a building new web application in January and realized that there were requirement that would be best served by AJAX and some nice browser widgets.  In enters ExtJS. After a couple weeks writing a spike through Struts and ExtJS (still using Prototype underneath), I made the choice to adopt ExtJS as a the library for my application's user interface.  Two months later, I'm more than satisfied with the choice.  So are my users.  

In the end, I've shed a bias I really shouldn't have been harbouring, I embraced a "new" language and added the ability to better server my users.  I still won't choose Javascript for a lot of things but I'm much happier knowing that I can properly apply it as part of an overall solution.

Tuesday, November 20, 2007

JRuby and Hibernate

The beautiful thing about Rails on JRuby is that you have access to Java. Perhaps you have existing code you'd like to reuse or maybe there's some functionality in a Java library you'd like to use. Whatever the reason, it's good to know how to do it.

So today I created a new Rails app to demonstrate how to use Rails' controllers and views with some model classes from one of my earlier Java projects. My old app used the typical HibernateUtil singleton (section 1.2.5 of the Hibernate docs). I also liked the ActiveRecord pattern so my Java domain classes had some handy "find" methods. So in order to make this work in a Rails app, I installed the goldspike plugin:
script/plugin install http://jruby-extras.rubyforge.org/svn/trunk/rails-integration/plugins/goldspike

and then ran the rake task war:standalone:create

I copied the classes and lib directories from my old apps' WEB-INF directory to the WEB-INF directory in my Rails app and then generated a controller and modified it to look like this:
require 'java'
import 'com.example.domain.Person'
import 'com.example.util.HibernateUtil'

class PersonController < ApplicationController
def list
with_transaction do
@people = Person.find_all.to_a
@people.sort!{|p1, p2| p1.name.downcase <=> p2.name.downcase}
end
end

def with_transaction
begin
tx = HibernateUtil.session_factory.current_session.beginTransaction
yield
tx.commit
HibernateUtil.session_factory.current_session.close
rescue
tx.rollback
end
end
end

Finally, I added a list.rhtml template for the "list" action and voila! I have a Rails-ish app that uses Hibernate instead of ActiveRecord.

Saturday, November 03, 2007

Ruby Cocoa

RubyCocoa and the Scripting Bridge are two software development technologies bundled with Leopard. The app presented here demonstrate how to create a native Mac interface written in Ruby that communicates with iTunes via Applescript. It does nothing more than display the iTunes version number.
  1. Create a "Ruby-Cocoa Application" from the "New Project" dialog in XCode
  2. Add a "Ruby NSObject subclass" to the project called "ITunesController"
  3. Add an ib_outlet for a text field and an ib_action called "show_version" to the ITunesController ruby class.
  4. Generate an Objective-C header file that scripting bridge can use to communicate with iTunes. Use the two terminal command, sdef and sdp, within your project folder like this: "sdef /Applications/iTunes.app | sdp -fh --basename iTunes"
  5. Add the header file to your project.
  6. Add "ScriptingBridge.framework" to your project.
  7. Open "MainMenu.nib" in Interface Builder and add a button and a label to the Window. Also instantiate an NSObject subclass.
  8. Set the NSObject's class to "ITunesController". (You may need to select the "Read Class Files..." menu item to get ITunesController to show up as a valid option)
  9. Wire the button to your controller's "show_version" method and wire the controller's text_field outlet to the label.

Here's what my project looks like:


Here's what my Ruby "ITunesController" class looks like:

require 'osx/cocoa'

include OSX
class ITunesController < NSObject
ib_outlet :text_field
def show_version(sender)
iTunes = SBApplication.applicationWithBundleIdentifier:'com.apple.iTunes'
@text_field.setStringValue("iTunes version: #{iTunes.version}")
end
ib_action :show_version
end

Here's what the app looks like:


Now you should be able to run the project and get the iTunes version number displayed in your own application. Yeah, the end result is kind of lame but the journey was pretty cool. The interesting bits for me were:
  1. My Ruby class extends Cocoa's NSObject class.
  2. The class methods ib_outlet and ib_action are parts of the Ruby DSL for doing Cocoa development with Ruby.
  3. The RubyCocoa framework makes it really simple to swap out Objective-C for Ruby when doing Cocoa development.
  4. Everything else is the same. I still use XCode for my controllers and model and still use Interface Builder to graphically build my GUI and bind it to my code. The only difference is that I get to use Ruby and all of its beauty to get the job done.
  5. The downside is that I don't get anything too useful in the way of code completion while in XCode. Still might be worth it if you really dig Ruby.

Friday, November 02, 2007

Yahoo Address Book & Leopard

Leopard's new address book allows you to sync with your Yahoo! contacts.  It's not intuitive so here goes:
  1. Open the general tab of Leopard's Address Book preferences.
  2. Check "Synchronize with Yahoo!"
  3. Click on the Configure Button and enter your Yahoo! ID and Password
  4. Open iSync's Preferences (here's where it gets weird)
  5. Check "Show status in menu bar"
  6. Select "Sync Now" from the new menu bar icon on the right
  7. Enjoy!
Of course you should back up everything before you try this.  I've been using Yahoo! Mail for years so it's my most correct and complete contact list.  I'm glad I can now benefit from this in Leopard.  Now if Yahoo! would just be as good as Google and give me IMAP support for free or if Apple would give me a GMail Address Book Sync, I'd be able to use Apple's mail client most of the time.

Now that I think about it, it'd also be nice to have iCal sync up with either Yahoo's or Google's calendar too!


Sunday, October 28, 2007

Leopard Installed

It's my second day running with Leopard and just about everything has gone smoothly.  I installed it without too much trouble on my MacBook and my PowerMac G5.  I say not too much trouble because not everything was perfect.  

Twice since installing Leopard on my G5 it's not gone to sleep on demand.  Instead it goes into a coma and starts snoring.  By that I mean all the USB devices shut off, the video signal goes away but the computer doesn't quite sleep.  Instead, all the fans start to spin up. For anyone that's never heard a G5's fans go nuts... it's like a small jet engine.  The only recourse is a hard restart.  I installed the first Leopard update and it hasn't repeated this stunt but I'm keeping an eye on it just in case.

The second thing is that MySQL won't start.  I've read a few things on the Internet and it just doesn't look the MySQL project is ready for Leopard. They had bug reports before 10.5 shipped but decided to just wait until it went gold. I guess I'll just have to patiently wait for an update.  No biggie.  I'll just use the built-in SQLite instead.

The third thing that I wasn't prepared for was the retirement of Classic OS 9 support.  I don't personally use any OS 9 apps  but my kids used to play the occasional game.  Sorry Rolly McFly.  Your days are over.

The last thing that isn't too big of a problem but a big disappointment is that the Java 6 SDK is MIA.  I guess I never really saw official mention of it, but I really expected Java 6 to ship with Leopard.  C'mon Apple!  I was there when Steve Jobs and Avie Tevanian stood up at JavaOne and said they'd have the best Java implementation on any platform.  You're definitely letting me down on this one.

Now onto the good news.  Everything else just works!  Mail is cool.  Safari is blazingly fast.  Dropped network connections don't mean a frozen finder anymore. Quick Look is sweet.  And Ruby is built-in.  I just deleted my old custom Ruby installation and everything (other than MySQL) continues to work.  My IDEs function properly (Eclipse & NetBeans) and despite the lack of Java 6, Java 5 on my Mac is still noticeably faster than Java 5 on Windows at work.  I don't mind the translucent menu bar and Cover Flow in the finder is nice but mostly unnecessary for me.  

The biggest shock to the system was the developer tools.  I've built the occasional Mac app, and while I'm no wizard at it, I got along just fine thanks.  So naturally I wanted to try the Ruby/Cocoa integration.  Then I opened Interface Builder.  Yikes!  That certainly  got a major overhaul!  Looks better, but now I see that I need to spend some time trying to figure out what's what.

So if someone asks whether they should upgrade or not.  I'd definitely give it the thumbs up.  Just make sure you don't need classic and if you're a geek like me, be prepared for a little bit of adjustment to the changes under that spiffy new exterior.

Thursday, October 25, 2007

JRuby and Rails in the Enterprise

At work, management is finally getting the message about dynamic languages like Ruby and starting to recognize that frameworks like Rails may have productivity benefits.  We're actually going to look at doing a pilot project.  I like to think that I've had some influence in that but you never know...

Anyway, I would love to make this work but this is a Java shop through and through.  We can only deploy to a Java web container, specifically Weblogic 8.1 (the transition to Weblogic 10 is happening but it's months away).  I've used JRuby (works great BTW) and the JRuby extras to help me deploy an app to Tomcat, but I can't manage to get JRuby and Rails working in Weblogic 8.1.  Any ideas?

Secondly, Groovy and Grails is the other contender.  I like the idea behind Groovy and Grails but I can't help feel that it's a pale imitation of Ruby and Rails.  Anybody have enough experience to compare and share?

Finally, I'm not naive enough to think that this will cure all the ills of working in the "big enterprise".  When I think about all the things that bug me, the technology is probably the smallest thing that causes me pain.  But on the other hand, this would be a wonderful distraction. :-)

Leopard

I think it's fair to say that I could be characterized as a Mac "fanboy" from time to time.  I've been known to spout pro-Mac statements occasionally.  I take some unfounded pride in the fact that Apple's market cap is now bigger than IBM or Intel. And I love the fact that Apple just had yet another record quarter....

Perhaps it's just the validation of what I've felt in all the years that I've used a Mac, it's just plain better than Windows!  So now I sit here waiting for my pre-order of Mac OS X - Leopard to get to my house.  It's supposed to arrive tomorrow but the status already changed to "shipped".  To fill some of my waiting time I watched Apple's guided tour. I read some of the reviews (evolutionary not revolutionary) but I still can't help but be excited.  It's like a little bit of Christmas in October.

I'm sure I'll be underwhelmed a bit once the glow of a new OS has worn off but for awhile I'll revel in my fanboyism.  So if you too are a bit excited about the next Mac OS release, roll over to AppleInsider and feel free to take part in the unbridled Mac love fest and read some of the "Road to Mac OS X Leopard" series. Some of them are quite well written and will give you a good perspective of where Apple and NeXT have been and how the features in Leopard came to be.  Ignore the fact that some of the statements are a little too biased toward Apple and just enjoy the moment...

Thursday, September 27, 2007

Marching on...

I used to develop applications with PowerBuilder (PB) for about 8 years.  I started with PB 1.0.  In the beginning it was new and exciting.  Windows was new.  Client/Server was new and even object oriented development in a mainstream tool was relatively new (at least in the corporate software development scene).  But as technology progressed I began to see exciting things elsewhere.  At the time Delphi was the cool new product.  The speed, the beauty, the elegance... ahhh I was smitten.  But the other PB developers around me didn't see it.  I fought for Delphi and even did one or two project with it.  But unfortunately Delphi wouldn't become my mainstream development tool.  PB was entrenched and the developers around it protected it with a passion.  It was disappointing. 

Then Java came along.  To my eye Java shared a lot in common with Delphi.  I liked it too.  But still the PB developers around me couldn't seem to appreciate this new tool. In fact, a lot of them were actually pretty hostile to anything that might threaten the sacred cow that was PB.  Fortunately for me the hype of the Internet and the .COM boom turned Java into something people couldn't ignore.  And I decided to ride the wave and finally leave PowerBuilder behind.

Now another 8 years has gone by and I find myself in the middle of a community of Java developers who are extraordinarily similar to that crowd of PowerBuilder developers.  They only see Java.  They've built a career around it, they're entrenched and they protect it with a passion.  For me, I see the appeal of other languages and tools.  In particular Ruby is beautiful and Rails elegantly solves many of my Java web development headaches.  But many of the people around me don't see it and quite frankly I doubt that they've even looked.  And that's the disappointing thing.  They're just like the PB guys with the blinders on.  They're hostile to anything that isn't Java.

In my current group there seems to be a new love forming for GWT.  Personally, the Google Web Toolkit and its unmistakable Swing/AWT flavor of Web development just seems wrong.  It's definitely web development for Java developers and I can see why they like it, but to me it's an artificial abstraction that doesn't sit well with me. Ruby and Rails isn't perfect either, but even a couple years after I started looking at it I still think it's better than GWT.  Rails embraces the browser technology of HTML, CSS, and Javascript and makes it easy to work with.  GWT on the other hand, puts me behind a Java facade where I can pretend to be developing Swing and it will generate the HTML and Javascript for me.  Ick.  No thanks Google.

Anyway, my point is that I think I'm getting to another point in my career where I need to migrate to a new place with like-minded people.  I'm tired of trying to get others to see what I think is self-evident if only they'd look...

Friday, September 07, 2007

Java & Ruby HTTP Clients: Part 2

Several months ago I wrote an article about how to create an HTTP client in Java or Ruby. I included examples in both languages for getting by BASIC and FORM based authentication. I also showed you how to resubmit the value of an HTTP cookie that many websites use to store state.

What I didn't mention is that quite often web applications store state not in a cookie but within the HTML itself. In order for you to programmatically interact with the website, you'll need to get that data out of the HTML and put it in your next request.

Java

So the basic recipe is to to use HttpClient (the way I demonstrated last time) to get the raw HTML. Then feed that text into NekoHTML, an HTML parser. It can correct the various problems you see in old-school HTML, namely unbalanced tags, missing parent tags, and mismatched elements.

Neko returns a standard Document object, but personally, I don't care much for the standard XML API. Instead I prefer to use the simpler API of DOM4J. So the next step is to take the XML that NekoHTML provides and feed it into DOM4J so that I can use XPath expressions to find what I need.

Now the question becomes what data do you need to post. Well my answer is to simply look through the FORM you're trying to submit, and resubmit everything. Look for 'hidden' tags, input tags of type 'text', 'password', and 'select', gather the names and values of all those tags. Override the ones where you need to provide the information (like id and password for example) and then do the POST.

Ruby

The Ruby approach is exactly the same: get the raw HTML, parse it, use XPath to get the name-value pairs of the FORM elements, override some of the values, and resubmit. The only additional rubygem from my last article is hpricot. It provides the same functionality of NekoHTML and DOM4J in Java. The typical script might look like this:


require 'net/http'
require 'rubygems'
require 'hpricot'

res = Net::HTTP.new('myserver', 80)
# res.set_debug_output $stderr #uncomment this to get console debug info
res.start do |http|
#go to the first page
get = Net::HTTP::Get.new('/home.aspx')
response = http.request(get)

#collect the cookie information
cookies = ''
response.response['set-cookie'].split(';').each{|c|
cookies += c.split(/path=.*?,/).last.strip + ';'
}

#collect the existing form data
doc = Hpricot(response.body)
form_data = {}
['text', 'password', 'hidden'].each{|t|
elements = doc.search("//form[@name='loginForm']//input[@type='#{t}']")
elements.each{ |e|
form_data[e['name']] = e['value'].to_s
}
}

#override some of the values
form_data['username'] = 'my_username'
form_data['password'] = 'my_secret'

#login
post = Net::HTTP::Post.new('/login.aspx')
post.set_form_data(form_data)
post['Cookie'] = cookies
puts http.request(post)
end

In this case all I did was print out the resulting HTML. At the very least you'd probably do the hpricot thing one more time to retrieve the data in which you're interested.

Other

Finally one last gotcha... At least half the websites I've tried to scrape do something "interesting" with Javascript to set various form elements. Since we don't have a Javascript engine executing you should expect that you'll have to parse the HTML and Javascript yourself to figure out what's going on, and set the fields manually in your script. I highly recommend Firefox and the "Web Developer" and Firebug plugins for inspecting the HTML, JS files and the HTTP Requests that the browser submits.

P.S.: I was a bit lazy this time and didn't provide any Java code. If you're really having trouble and can't get it working, leave me a message and I'll put together an example. Secondly, there are other Java HTML parsers out there that may work just as well or maybe even better than Neko, but since I don't have any personal experience with them I didn't mention them. If you like something else, leave a message.

Thursday, May 03, 2007

Aptana RADRails & JRuby

I thought I'd go and take a look at what's been happening on the RADRails project lately. As it turns out, quite a bit! Aptana has taken over the project and are making quite a bit a progress integrating it with their Eclipse based IDE. The most impressive thing I saw was refactoring support! Fantastic! It's great to see RADRails getting some attention again. Go download the beta.

Then I went over to the JRuby project to see what they've been up to. JRuby 0.9.9 is out and looks very good. The Java integration is quite good. But I've been mostly interested in seeing support for deploying a Rails app in a JEE Web Container. Well nestled in beside the JRuby TAR file is a file called sample-rails-warfile.tar.gz. I downloaded it and pretty quickly had a rails application running in Tomcat. The app doesn't do much of anything but it's still pretty impressive to see it. My hope is that this kind of integration will help to get Ruby & Rails adopted into some of Java-only environment I tend to work in. The next thing I did was build my own Rails app and deploy it in Tomcat. I also tried deploying it in WebLogic but didn't have as much luck. Obviously there's still some work to do. Check out the JRuby WIKI for details.

Friday, April 13, 2007

Ruby OLE

The other day someone came over to my desk and asked me how they could programatically invoke the "Find Computer" function of the Windows shell. Normally you just press CTRL-WINDOWS-F and up pops an Explorer window ready for searching. I didn't have a quick answer for him... so I immediately took up the challenge to figure it out.

After a couple dead ends I started looking at Windows Script Host (WSH). It allows you to write VB or JavaScript to access the ActiveX API of a Windows application. After a bit of googling I found the "Shell.Application" documentation on MSDN. After futzing around with Javascript for a few minutes I started thinking that I should be able to do the same things with Ruby. So with a little more searching I discovered that by adding "require 'win32ole'" at the top of my ruby script I could instantiate an instance of "Shell.Application".

The only problem left was finding the right API call. A three line Ruby script like this gave me a list of methods:

require 'win32ole'
wsh = WIN32OLE.new('Shell.Application')

wsh.ole_methods.collect{|m| m.to_s}.sort.each{|m| puts m}


A quick change and my final script looked like:

require 'win32ole'
wsh = WIN32OLE.new('Shell.Application')

wsh.FindComputer()


or in JavaScript:

wsh = WScript.CreateObject("Shell.Application");
wsh.FindComputer();


If you want to take this scripting stuff to the next level I suggest you go check out David Mullet's "Ruby on Windows" blog. He describes some of the same things I just demonstrated above and goes into a lot greater depth about how to use Ruby to script think like Word and Excel.

And in case you're wondering why I had to use Ruby to get a list of methods instead of just looking it up in MSDN, well just try looking at the MSDN page I referenced above with Firefox instead of IE.... That's right... the site navigation only works correctly in Internet Explorer.

Tuesday, April 10, 2007

It's spelled S-Q-L

Why do so many Java developers suck at SQL? Are they just born that way? Are they brainwashed? Do they think that Hibernate will just do it all for them? What's the problem?

The reason I ask is that I'm working on a Java system where the developers obviously thought nothing of letting Hibernate lazily instantiate every relationship as they iterated through collections and navigated down relationships. Not once did they stop to consider the SQL that was being thrown across the network to the database or the performance penalty that it would incur. Just a couple weeks ago I turned on Hibernate's SQL logging just to see 631 queries go flying by in order to prepare the data for a single JSP. WTF?! 631 Queries!!?

Then today I saw another atrocious example of bad code that instantiated several collections of some very large classes from the database to just throw them all away after navigating through them to get a count. Whatever happened to count(*)? In the end I replaced hundreds of lines of convoluted Java code with about twenty lines of SQL. Yes SQL, not HQL (which rocks BTW), but just wasn't appropriate for this task.

Perhaps it's unfair of me to pick on Java developers but for one reason or another a lot of the Java developers I run into have this resistance to leveraging the relational query engine at their disposal. They don't strike a good balance between the object oriented and relational worlds that their systems stride. Use the right language for the right task. And if you can't determine when to turn to SQL, turn on SQL logging and watch what the heck is going on. When you see SQL tearing by, just pause for a moment and ask yourself if there's a better way to do what you want. And remember you have decades of querying technology just waiting to be used. Don't be afraid of writing an elegant query.

Tuesday, April 03, 2007

Prototype, Sitemesh and Struts

The Java environment for my current project is stuck at Java 1.4, but that doesn't mean I have to build my webapps like it's 2002 (that's when 1.4 was released). As a matter of fact I decided to take some lessons from Ruby on Rails.

First of all I decided to ditch Tiles in favor of Sitemesh. Tiles gets the job done but at the expense of a little too much abstraction for my taste. Sitemesh uses the decorator pattern and just simply feels a whole lot cleaner. While not as simple as dropping an RHTML file into a "layouts" directory, it's certainly a whole lot easier than the XML config needed for Tiles.

Secondly, I use DispatchAction to get multiple "action" methods in one Struts Action subclass. It's nothing I haven't done before but keeping the number of classes down is a good thing.

Finally I decided I liked the way RoR uses Prototype and Scriptaculous to provide a little more responsiveness to my webapps. So I decided to jump into Javascript and use Prototype in my Struts webapps. I had to configure Sitemesh to leave my AJAX responses alone and I needed to read a bit of the Prototype docs but it was pretty straightforward. I used the Rails partial convention to let my Java app generate HTML fragments through a Struts action and a JSP and then let my Javascript function replace a piece of the DOM with the result of the AJAX call.

When given lemons, make lemonade. When given ancient Java technology, spice it up with the techniques you learn by looking at alternative implementations.

Objective-C 2.0

Being a bit of a Mac-head and programmer to boot I've taken various looks at writing native Mac OS X apps withe XCode (the IDE), Cocoa (the frameworks), and Objective-C (the language). In general I've come away relatively happy with the toolset. But I must admit, I've filed my own share of enhancement requests with Apple. The top of my list was refactoring support in the IDE. I know it probably sounds lame to the hard core coders but after developing with Java for so long I just expect it and perhaps more embarassingly I feel I need it. Global regex search and replace just doesn't cut it. Secondly, I dislike all the boiler-plate "noise" that appears in your code to declare properties (instance var & accessor/mutator methods) and all the manual memory management.

Well Apple's been looking around at the competition and listening to feedback and judging by their website (here and here) and a few message boards (like this one), Apple has a lot in store for developers. Objective-C 2.0 sports Garbage Collection for the first time, some syntactical sugar for iterating over collections, and a nice simple way of declaring properties. XCode provides refactoring (YAY!) and more enhancements to keep your eyeballs on the code while editing and debugging. And even Interface Builder got cleaned up a bit and exposes nice simple ways of using core animation in Leopard. I'm looking forward to seeing it all in action.

BTW: I read on the RubyCocoa mailing list a few months ago that it might be bundled with Leopard too. Writing Mac OS X apps with Ruby... very cool... Have to wait and see if that one happens.

The New C#

About a year and a half ago I blogged about LINQ (Language INtegrated Query). Anders Hejlesberg starred in a video demoing object/xml/database query functionality and some new language features that Microsoft was playing with.

It's been in the oven for quite a while so it should be just about done, and as a matter of fact it looks like C# 3.0 is scheduled to be released this year. I suggest checking out this MSDN site to read the details for yourself or watch some of the videos. Things like implicitly typed local variables, extension methods, lamda expressions, and anonymous types all seem to be inspired by the features of the so-called scripting languages like Ruby, although Microsoft goes out of their way to make sure you don't confuse the similarity in syntax with the underlying implementation (and with good reason).

In short I'm still quite impressed. I've seriously looked at C# in the past and mostly dismissed it as a Java clone. But with these new features I think it's finally coming out from under it's Java shadow and beginning to shine on its own.

Thursday, March 22, 2007

My MacBook

Over the past few weeks, the developers at work have been taking turns bringing in their laptops... It wasn't something we planned but just started happening spontaneously. One guy brought his Centrino laptop running Linux, another guy brought a 17" screen Dell that he uses for CAD, one guy brought his shiny new Vista laptop and a couple days ago it was my turn to take in my MacBook.

In general my little black MacBook received a fairly warm welcome. People were surprised at how thin it was and the usability of a relatively small 13.3" screen. They liked the built in webcam and although the single button touchpad attracted a bit of grief they quieted down when I showed them that a two finger tap brought up contextual menus. I gave them the flashy demo with Exposé, the magnifying dock and Dashboard and gave them the super abbreviated tour of the iLife and iWork applications.

But in the end the one thing that seemed to get the most attention was the MagSafe Power Adapter. From the magnetic connector to the little brick with "wings" for winding the cord and a removable AC adapter, people definitely liked the design. But having just checked the Apple Store comments on this little item I'm hoping that my little white brick lasts a little longer than everyone else's. Yikes!

But other than the black finish which picks up fingerprints like nothing else I've ever owned, I'm very happy with my laptop. And now my co-workers don't think I'm so crazy for owning a Mac.