<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="http://my.rsscache.com/rsc/rss2.xsl"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:rsscache="http://ns.rsscache.com/1.0"><channel><title>Raible Designs</title><link>http://raibledesigns.com/rd/</link><atom:link rel="self" type="application/rss+xml" href="http://raibledesigns.com/rd/feed/entries/rss" /><description>&lt;a class="linkedin-profileinsider-popup" href="http://www.linkedin.com/in/mraible"&gt;Matt Raible&lt;/a&gt; is a UI Architect specializing in open source web frameworks. &lt;a href="http://raibledesigns.com/contact.jsp"&gt;Contact me&lt;/a&gt; for rates.</description><language>en-us</language><copyright>Copyright 2010</copyright><lastBuildDate>Wed, 10 Mar 2010 08:16:09 -0700</lastBuildDate><generator>Apache Roller (incubating) 4.0 (20071120033321:dave)</generator><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/how_we_hired_a_team</guid><title>How We Hired a Team of 10 in 2 Months</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/how_we_hired_a_team</link><pubDate>Fri, 5 Mar 2010 12:01:57 -0700</pubDate><category>Java</category><category>recruiting</category><category>interview</category><category>developers</category><category>screening</category><category>java</category><category>hiring</category><category>team</category><description>Back in December, I started a new contract with &lt;a href="http://www.timewarnercable.com/"&gt;Time Warner Cable&lt;/a&gt; (TWC). As part of the terms of that contract, it named the following as one of my deliverables:
&lt;/p&gt;
&lt;p class="quote" style="color: #666"&gt;
Assist in identifying, recruiting and hiring additional full-time Web development staff, emphasizing open-source framework expertise.&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Timeframe: ongoing, throughout the six-month engagement&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Deliverable: targeting 2-3 quality leads/hires
&lt;/p&gt;
&lt;p&gt;Since this was a local gig and I always like a good challenge, I asked my client to raise the number from 2-3 to 4-5. Shortly after signing that contract, my project began. Almost immediately, I began &lt;a href="http://twitter.com/mraible/status/6552522542"&gt;spreading the word on Twitter&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;When TWC hired me, it was just the beginning of a larger initiative. They were making a number of large changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Moving from Waterfall to Agile.&lt;/li&gt;
&lt;li&gt;Restructuring organizationally for functional teams.&lt;/li&gt;
&lt;li&gt;Moving from ColdFusion to JVM technologies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To help with the move to Agile, I contacted a good friend, &lt;a href="http://www.linkedin.com/in/bradswanson"&gt;Brad Swanson&lt;/a&gt;. Brad is the founder of &lt;a href="http://properosolutions.com/"&gt;Propero Solutions&lt;/a&gt; and has always had a passion for agile coaching and making teams more efficient. At the beginning of the year, we setup 2-day training class in Herndon, VA to kick-off the Agile Initiative. There were 15 existing developers on the team when I started and 40 people showed up to that initial training. Most of these additional folks were from Product and QA. Brad's message of working together quickly resonated with the group and you could see their eyes light up with their new-found knowledge.
&lt;/p&gt;
&lt;p&gt;After the success of Brad's training, we leveraged his network to help
us find some very impressive coaches to assist with our efforts. We
hired two Agile Coaches to start working with us at the end of
January.
&lt;/p&gt;
&lt;p&gt;While our agile movement was progressing in January, I started contacting friends, former colleagues and referrals about coming to work for us. For friends and former colleagues, my e-mail simply outlined the positions available, the exciting opportunity of the project and that TWC was willing to pay very competitive salaries for strong engineers. While it didn't happen immediately, I did manage to convince 4 former co-workers to join me, including the team I built at LinkedIn and worked with at Evite.
&lt;/p&gt;
&lt;p&gt;
Following those 4, most of the candidates we interviewed were referrals or folks that contacted me directly after seeing my tweet. I'm amazed that I never had to write a blog post to advertise the positions. 
&lt;/p&gt;
&lt;p&gt;Once we identified potential candidates, we executed the following process:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Requested a resume (or LinkedIn Profile URL) via e-mail.&lt;/li&gt;
&lt;li&gt;If skills and experience looked like a match, we sent a list of screening questions specific to the position. &lt;/li&gt;
&lt;li&gt;If screening answers were satisfactory, we'd schedule a face-to-face interview.&lt;/li&gt;
&lt;li&gt;We then conducted a face-to-face interview with a list of questions specific to the position.&lt;/li&gt;
&lt;li&gt;If convenient, we took the candidate to lunch to explore their social skills.&lt;/li&gt;
&lt;li&gt;After interviewing, the interviewers would huddle for 5-10 minutes and give thumbs-up/thumbs-down and we'd right up a summary e-mail for our boss. &lt;/li&gt;
&lt;li&gt;If thumbs-up, our boss would contact the candidate, discuss the details and extend an offer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This process turned out to be a great way to hire a kick-ass team very quickly. You might notice that HR was not involved at all in this process.
While we did use them to post jobs and such, we found that our
recommendation-based process of identifying high-quality candidates
worked much better. HR was able to bring in folks with lots of
buzzwords on their resume, but no one knew them or what they were
capable of.
&lt;/p&gt;
&lt;p&gt;
Once a person passed the screening questions, our interview focused more on a person's social skills than their technical ability. The first half of the interview was all about their career experiences and what they enjoyed/disliked about employers and projects. The second half consisted of a handful of very technical, hard questions that we expected people to struggle with. If they answered correctly, we were impressed. If they didn't, we examined how they handled explaining they didn't know the answer. It was interesting to see how many people didn't simply answer "I don't know".
&lt;/p&gt;
&lt;p&gt;One of my most interesting observations of the process was our question about "what was your most enjoyable employment experience and why?" Most folks responded with something very early on in their career, and often it was their first job. This caused me to reflect on our industry and careers as a whole and wonder if people get more miserable as they keep working. It's a shame there's not more folks happy with their current jobs. 
&lt;/p&gt;
&lt;p&gt;By mid-February, we managed to fill most of our open headcounts. We'd successfully hired 2 Agile Coaches and 8 Developers in a little over 2 months. While everyone hasn't started yet, there's several of us now working in my Denver office. We pretty much caught everyone off-guard with our success and we've moved onto our next biggest problem - were do we put everyone? The TWC Broomfield office is building out space for us, but it'll likely take them a few months to complete the project. My office that fits 4 comfortably had 8 of us in their last week. I had to sit on a garbage can when pairing because we'd run out of chairs. 
&lt;/p&gt;
&lt;p&gt;To solve our short-term space constrains, I've successfully negotiated additional space upstairs from our landlady and we've ordered a number of new desks for folks. Our desks arrive Monday and we're setting up pairing stations upstairs next week. All-in-all, it's been a wild ride with a fair amount of stress. Interviewing folks wasn't that stressful, but trying to hire folks while writing code and trying to deliver features for our project was challenging. 
&lt;/p&gt;
&lt;p&gt;
We've been emphasizing pair programming and hiring process required a lot of e-mail communication. When we were pairing, we'd ignore our e-mails for most of the day and then have to catch up at night. Once people started on-boarding, we had to figure out the best way to get them started and slinging code. We established an on-boarding plan and we've been able to get everyone running our app on their machines before lunch. We've even had a couple folks committing code by the end of the first day.
&lt;/p&gt;
&lt;p&gt;This week, we on-boarded 3 of our final 4 developers. I breathed a big sigh of relief that the hiring was over and we could get back to slinging code and making things happen. As luck would have it, I received an e-mail from my boss on Tuesday that the hiring engine is starting up again and we need to hire 6 more developers. While I'm not anxious to start the Hiring Engine again, I am glad to know it works well and it &lt;em&gt;has&lt;/em&gt; helped us build a great team. I'm not going to post the positions as part of this blog entry, but there's a good chance you'll hear more about the gigs if you &lt;a href="http://twitter.com/mraible"&gt;follow me on Twitter&lt;/a&gt;.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=73538940&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=73538940&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=73538940 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><title>[Ad] Your city: Mom Discovers $3 Whitening Trick</title><link>http://www.rsscache.com/Section/Advertise/click.aspx?a=801410</link><description>Dentists Do NOT Want You To Know About This Teeth Whitening Secret!</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/jack_s_skiing_like_a</guid><title>Jack's Skiing Like A Madman!</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/jack_s_skiing_like_a</link><pubDate>Sun, 28 Feb 2010 22:56:05 -0700</pubDate><category>General</category><category>skiing</category><category>copper</category><category>abbie</category><category>jack</category><category>winterpark</category><description>My kids have been skiing since they were pretty little. Abbie started when she turned 3 and Jack started when he was 2. I don't know that I'd recommend starting kids that early because it's taken a &lt;em&gt;long&lt;/em&gt; time for them to get good. Abbie &lt;a href="http://raibledesigns.com/rd/entry/the_kids_actually_like_skiing"&gt;was good last year&lt;/a&gt; and it looks like Jack is coming on strong this year. 
&lt;/p&gt;
&lt;p&gt;
On Saturday, I took Abbie and Jack up to &lt;a href="http://www.coppercolorado.com/winter/plan_and_buy/tubing/index.html"&gt;Copper Mountain's Tubing Hill&lt;/a&gt;. It was a balmy 45&amp;deg;F day and we had a blast flying down the mountain. I especially liked run #3 that had a double jump in its path.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2691/4397600502_b2f67c6f29.jpg" title="Tubing at Copper" rel="lightbox[tubingatcopper]"&gt;&lt;img src="http://farm3.static.flickr.com/2691/4397600502_b2f67c6f29_m.jpg" width="240" height="180" alt="Tubing at Copper" style="border: 1px solid black" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;After tubing, Jack proved he's a &lt;a href="http://farm3.static.flickr.com/2734/4396835503_ff496a1b58.jpg" rel="lightbox[tubingatcopper]" title="Crazy Jack"&gt;crazy 5-year old&lt;/a&gt;; then we grabbed our skis and hit the slopes for a couple runs. By the 2nd run, Jack was flying past both Abbie and I and giggling while doing it. It was a special moment for me considering he's been skiing since 2 and only recently let go of me.
&lt;/p&gt;
&lt;p&gt;Today, we headed to Winter Park for a few more runs. Since Jack has become bolder, I decided to skip the lift-walk-bus-walk pain-in-the-ass section at the bottom of Winter Park and park at Mary Jane (where you can easily walk-ski to the lift). We ended up skiing at the top of the mountain most of the time. I recall a couple times where Jack would go flying past Abbie and I and I'd think "I really hope he doesn't wipe out 'cause that's gonna hurt." By the end of the day, he was skiing down blues and even tried some bumps. Great job today Jack - you've made me proud.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2678/4396836045_b1f1401d2f.jpg" title="Abbie showing Jack how to do bumps" rel="lightbox[tubingatcopper]"&gt;&lt;img src="http://farm3.static.flickr.com/2678/4396836045_b1f1401d2f_t.jpg" width="100" height="75" alt="Abbie showing Jack how to do bumps" style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm3.static.flickr.com/2758/4396836309_d1891e9c39.jpg" title="Blue Bumps" rel="lightbox[tubingatcopper]"&gt;&lt;img src="http://farm3.static.flickr.com/2758/4396836309_d1891e9c39_t.jpg" width="100" height="75" alt="Blue Bumps" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4049/4396836719_ae3c59b258.jpg" title="Bumps" rel="lightbox[tubingatcopper]"&gt;&lt;img src="http://farm5.static.flickr.com/4049/4396836719_ae3c59b258_t.jpg" width="100" height="75" alt="Bumps" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;With Spring Skiing right around the corner, I think there's gonna be some good races in the next couple months. &lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=73393217&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=73393217&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=73393217 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/my_future_of_web_frameworks</guid><title>My Future of Web Frameworks Presentation</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/my_future_of_web_frameworks</link><pubDate>Fri, 26 Feb 2010 08:55:39 -0700</pubDate><category>Java</category><category>theserverside</category><category>vegas</category><category>presentation</category><category>tssjs</category><category>webframeworks</category><category>future</category><category>jvm</category><category>java</category><description>Earlier this week, I &lt;a href="http://twitter.com/mraible/status/9467279089"&gt;tweeted about a history of web frameworks timeline&lt;/a&gt; I created for my upcoming &lt;a href="http://javasymposium.techtarget.com/html/frameworks.html#MRaibleFrameworks"&gt;Future of Web Frameworks talk&lt;/a&gt; at &lt;a href="http://javasymposium.techtarget.com/"&gt;TSSJS Vegas 2010&lt;/a&gt;. I immediately received a lot of feedback and requests for adding new frameworks and releases. The image below is the result of that Twitter conversation. Thanks to everyone who contributed.
&lt;/p&gt;
&lt;p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://www.flickr.com/photos/mraible/4378559350/" title="History of Web Frameworks"&gt;&lt;img src="http://farm5.static.flickr.com/4067/4378559350_70bd42f61f.jpg" width="500" height="239" alt="History of Web Frameworks" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Back in &lt;a href="http://raibledesigns.com/rd/entry/the_future_of_web_frameworks"&gt;November&lt;/a&gt;, I wrote about my proposals for TSSJS. I've been thinking a lot about web frameworks lately and I can't help but think we live in a very exciting time. As a Java developer, I've been exposed to one of the most vibrant language ecosystems on the planet. As &lt;a href="http://www.javaworld.com/podcasts/jtech/2009/020909jtech-bray.html"&gt;Tim Bray talks about&lt;/a&gt;, the Java Platform has 3 legs: the language, the virtual machine and a huge, immense library of APIs (both in the JDK and in open source libraries). The diagram below is something I created based on Tim's podcast.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://www.flickr.com/photos/mraible/4388528613/" title="Java has 3 Legs"&gt;&lt;img src="http://farm5.static.flickr.com/4003/4388528613_18df5e164f_o.png" width="418" height="290" alt="Java has 3 Legs" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Tim says, "One of those legs is replaceable and that's the language." And he's right, there's many &lt;a href="http://blog.thinkrelevance.com/2008/9/24/java-next-overview"&gt;Java.next&lt;/a&gt; languages that run efficiently on the JVM. This is one of the most exciting parts of being a Java web developer today. There's many proven web frameworks and languages that you can pick to build your next web application. 
&lt;/p&gt;
&lt;p&gt;
The best part is many of the best web frameworks run on the JVM. Not only that, but the best code editors are the IDEs that you're familiar with and have grown to love. Furthermore, much of the literature for Java.next languages is written &lt;em&gt;for&lt;/em&gt; Java developers. As someone who knows Java, you have wealth of web frameworks and languages just waiting for you to learn them. &lt;!--I think the biggest mistake you can make as developer is to stop learning. Just because you know one language/framework well doesn't mean you shouldn't learn about it's competition. Java vs. Scala, Maven vs. Ant, Rails vs. Grails, GWT vs. Flex, Tomcat vs. Jetty, Spring vs. Guice, Hibernate vs. iBATIS - your knowledge about more than one language/framework can be very rewarding.--&gt;
&lt;/p&gt;
&lt;p&gt;
To create my presentation on the future of web frameworks, I followed the outline I &lt;a href="http://raibledesigns.com/rd/entry/the_future_of_web_frameworks"&gt;posted previously&lt;/a&gt;. I plan on explaining the evolution and history of web frameworks and how we got to where we are today. From there, I'll be speculating on what web applications we'll be developing in the future. Finally, I'll touch on the necessary features of web frameworks that will allow us to develop these applications. 
&lt;/p&gt;
&lt;p&gt;
Of course, I haven't actually presented this talk yet, so it's likely to change in the coming weeks before the conference. The good news is this gives you the opportunity to provide constructive criticism on this presentation and help make it better. I realize that a presentation rarely represents the conversation that takes place during a conference. However, I believe it can portray the jist of my thinking and lead to a meaningful conversation in the comments of this post.
Below is the presentation I created - thanks in advance for any feedback. 
&lt;/p&gt;
&lt;p style="text-align: center"&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=thefutureofwebframeworks-100225012146-phpapp02&amp;rel=0&amp;stripped_title=the-future-of-web-frameworks" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=thefutureofwebframeworks-100225012146-phpapp02&amp;rel=0&amp;stripped_title=the-future-of-web-frameworks" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;
For those who will be joining me at TSSJS ... it's gonna be a great show. St. Patrick's Day in Vegas, what more could you ask for? &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=73304272&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=73304272&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=73304272 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/my_guest_room_remodel_is</guid><title>My Guest Room Remodel is finished!</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/my_guest_room_remodel_is</link><pubDate>Tue, 16 Feb 2010 07:49:37 -0700</pubDate><category>General</category><category>denver</category><category>nuimage</category><category>remodeling</category><category>pipesburst</category><description>On December 5th, I flew home from Orlando (after &lt;a href="http://www.therichwebexperience.com/conference/orlando/2009/12/home"&gt;The Rich Web Experience&lt;/a&gt;) and arrived home to the &lt;a href="http://twitter.com/mraible/status/6376757616"&gt;sound of waterfalls in my house&lt;/a&gt;. As soon as I opened the door, I knew something was wrong. Sure enough, the pipes had burst in my back guest room and water was pouring out of my ceiling. My guess is that it'd been happening for days. 
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2765/4361297053_18945f6085.jpg" title="Waterfalls - a.k.a. Pipes Burst" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm3.static.flickr.com/2765/4361297053_18945f6085_t.jpg" width="75" height="100" alt="Waterfalls - a.k.a. Pipes Burst" style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4019/4361297259_aa5802af44.jpg" title="What we came home to: busted water pipes." rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4019/4361297259_aa5802af44_t.jpg" width="100" height="75" alt="What we came home to: busted water pipes." style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4010/4361297393_9ec3eda9e6.jpg" title="Soaked through the walls" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4010/4361297393_9ec3eda9e6_t.jpg" width="100" height="75" alt="Soaked through the walls" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4062/4361297573_c426736dee.jpg" title="Time for a remodel!" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4062/4361297573_c426736dee_t.jpg" width="75" height="100" alt="Time for a remodel!" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
The following week was quite interesting as I juggled a cleanup with lots of fans and a house without water. My water got turned on by Wednesday and I gained a whole new appreciation for indoor plumbing. Initially, I thought I could get everything fixed before my family arrived for Christmas. As their arrival approached, I became less and less hopeful and quickly scrambled to setup a couple ad hoc guest rooms.&lt;/p&gt;
&lt;p&gt;After the Christmas holiday, I met with a local contractor (the same guy who fixed my plumbing initially) and discussed my options. The cheapest option (a.k.a. the one my homeowner's insurance would cover) was to put everything back like it was. However, it was readily apparent that if we did this, there's a good chance busted pipes would happen again. Therefore, I made the leap and decided to &lt;a href="https://twitter.com/mraible/status/7278870084" title="My burst water pipes has turned into a full scale remodel with a new bathroom. Insurance covers 1/2."&gt;remodel the whole thing&lt;/a&gt;. Major changes made were 1) moving the bathroom to an opposite corner, 2) adding an interior window for light from the skylights and 3) adding a door to the bathroom from Jack's room. 
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm5.static.flickr.com/4014/4254920538_2c6172a600.jpg" title="Tearing out walls" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4014/4254920538_2c6172a600_t.jpg" width="100" height="75" alt="Tearing out walls" style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4059/4254153721_a5bd48d979.jpg" title="Old bathroom gone" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4059/4254153721_a5bd48d979_t.jpg" width="100" height="75" alt="Old bathroom gone" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm3.static.flickr.com/2753/4254919550_1f8c44877e.jpg" title="Soon to be better" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm3.static.flickr.com/2753/4254919550_1f8c44877e_t.jpg" width="100" height="75" alt="Soon to be better" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;

&lt;a href="http://farm5.static.flickr.com/4024/4254919820_e8342f3921.jpg" title="Digging, lots of it." rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4024/4254919820_e8342f3921_t.jpg" width="100" height="75" alt="Digging, lots of it." style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm3.static.flickr.com/2730/4254920190_21e988b634.jpg" title="Cement gone." rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm3.static.flickr.com/2730/4254920190_21e988b634_t.jpg" width="100" height="75" alt="Cement gone." style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4035/4321261448_b642d97186.jpg" title="Framing" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4035/4321261448_b642d97186_t.jpg" width="100" height="75" alt="Framing" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
The results are something I'm very happy with. I'd like to thank &lt;a href="http://www.nuimageplumbing.net/"&gt;Nu Image&lt;/a&gt; for their great work and my parents for flying in to help finish it all up. If you're a friend of mine and looking for some powder runs this winter, I have a nice guest room for you to stay in. &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;
&lt;/p&gt;
&lt;table style="width: 100%"&gt;
&lt;tr&gt;
&lt;td style="text-align: center; padding: 10px; padding-top: 0"&gt;
&lt;a href="http://farm5.static.flickr.com/4058/4362001710_04081a470d.jpg" title="Remodeled Guest Room" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4058/4362001710_04081a470d_m.jpg" width="240" height="180" alt="Remodeled Guest Room" style="border: 1px solid black" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td style="padding: 10px; padding-top: 0"&gt;
&lt;a href="http://farm5.static.flickr.com/4054/4362004354_9f4e3e229e.jpg" title="Bathroom Sink" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4054/4362004354_9f4e3e229e_m.jpg" width="240" height="180" alt="Bathroom Sink" style="border: 1px solid black" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center; padding: 10px; padding-bottom: 0" colspan="2"&gt;
&lt;a href="http://farm3.static.flickr.com/2732/4362003934_d3dccc1beb.jpg" title="Wall Mirror" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm3.static.flickr.com/2732/4362003934_d3dccc1beb_t.jpg" width="100" height="75" alt="Wall Mirror" style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm5.static.flickr.com/4033/4361262765_4b67ff8553.jpg" title="Closet" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm5.static.flickr.com/4033/4361262765_4b67ff8553_t.jpg" width="100" height="75" alt="Closet" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm3.static.flickr.com/2724/4361259949_7ec4d1f630.jpg" title="View into Shower" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm3.static.flickr.com/2724/4361259949_7ec4d1f630_t.jpg" width="100" height="75" alt="View into Shower" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;

&lt;a href="http://farm3.static.flickr.com/2713/4361262181_11f8e65b01.jpg" title="View from Jack's Room" rel="lightbox[remodelfinished]"&gt;&lt;img src="http://farm3.static.flickr.com/2713/4361262181_11f8e65b01_t.jpg" width="100" height="75" alt="View from Jack's Room" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;For more pictures, see my &lt;a href="http://www.flickr.com/photos/mraible/sets/72157623036824189/"&gt;Guest Room Remodeling set on Flickr&lt;/a&gt;.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=73029653&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=73029653&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=73029653 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/web_application_testing_with_selenium1</guid><title>Web Application Testing with Selenium by Jason Huggins</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/web_application_testing_with_selenium1</link><pubDate>Mon, 15 Feb 2010 21:44:44 -0700</pubDate><category>Java</category><category>browsermom</category><category>testing</category><category>castro</category><category>saucelabs</category><category>seleniumide</category><category>seleniumgrid</category><category>seleniumrc</category><category>selenium</category><category>agiledenver</category><description>&lt;a href="http://seleniumhq.org"&gt;&lt;img src="http://static.raibledesigns.com/repository/images/selenium-logo.png" alt="Selenium" height="64" width="64" class="picture" style="border: 0" /&gt;&lt;/a&gt;
This evening, I attended &lt;a href="http://agiledenver.ning.com/"&gt;Agile Denver's&lt;/a&gt; monthly meeting to listen to &lt;a href="http://twitter.com/hugs"&gt;Jason Huggins&lt;/a&gt; talk about &lt;a href="http://seleniumhq.org"&gt;Selenium&lt;/a&gt;. The meeting started off with a panel on UI testing that I participated in. The most interesting part of this panel (for me) was meeting the other panelists and learning about their expertise. Folks from &lt;a href="http://www.redpinestudios.com/"&gt;Red Pine Studios&lt;/a&gt; in Boulder video taped both the panel and presentation. Hopefully it will be published online in the near future.
&lt;/p&gt;
&lt;p&gt;
Below are my notes from Jason's talk. Please keep in mind that most of these are his words, not mine.
&lt;/p&gt;
&lt;p style="border-top: 1px dotted silver; padding-top: 10px"&gt;
Jason is the Executive Software Chef at Sauce Labs. He often experiments with new recipes and is one of the  creators of Selenium. He worked at Google and helped them build and use a Selenium Farm to test Gmail and Google Docs. Selenium was inspired by ThoughtWorks Expense Report system and its "Add Row" button. The button caused so many issues, they needed a way to write a test that could be run in multiple browsers. 
&lt;/p&gt;
&lt;p&gt;
The first thing they tried was &lt;a href="http://jwebunit.sourceforge.net/"&gt;jWebUnit&lt;/a&gt; (a wrapper around &lt;a href="http://htmlunit.sourceforge.net/"&gt;HtmlUnit&lt;/a&gt;). Since HtmlUnit simulates the browser, it wasn't "real world" enough. The 2nd attempt was DriftWood. It was a Mozilla extension that drove a real browser so it could handle JavaScript UI features. The downside it was it didn't work for IE or Safari. It also used XML Syntax for tests. The 3rd attempt was &lt;a href="http://www.jsunit.net/"&gt;JsUnit&lt;/a&gt;. It worked in all browsers, but its emphasis was on a single page unit test; it had no page-to-page workflow support. Also, you couldn't see what it was doing while it was running. The 4th attempt was FIT (Framework for Integration Testing). It allowed more readable tests, but the API wasn't that intuitive and there was &lt;em&gt;too much magic behind the curtain&lt;/em&gt;. So basically, they had to fork FIT. 
&lt;/p&gt;
&lt;p&gt;The first attempt was called "Selenese" and consisted of a 3-column table where each row had an Action, Target and Value. In the beginning, Selenium Core was a TestRunner that ran in any browser. It was written in plain ol' JavaScript and HTML. The next thing that came about was the Selenium IDE for Firefox. It maintains the echo of Selenium Core and FIT. 
&lt;/p&gt;
&lt;p&gt;Selenium Remote Control (RC) was the next product produced by the project. Selenium RC allows you to write your tests in any language. A Selenium server interprets the requests and turns them into browser manipulation events. Finally, Selenium Grid was developed to leverage Selenium's HTTP architecture to allow parallel execution across servers.
&lt;/p&gt;
&lt;p&gt;Cloud computing is a wonderful use case for functional testing. Selenium Hub is a gateway into the Selenium Grid that routes the test request to particular browsers and platforms. &lt;a href="http://saucelabs.com"&gt;Sauce Labs&lt;/a&gt; has a version of Selenium Grid that runs in the cloud.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Selenium Issues&lt;/strong&gt;&lt;br/&gt;
Selenium is slow. Functional tests will always be slower than unit tests. Until the browsers can launch faster, there's always going to be speed issues. Parallel-ization can solve some of these and is something you should think about right away.
&lt;/p&gt;
&lt;p&gt;The JavaScript sandbox, Flash, Java Applets, Silverlight and Canvas all present problems in Selenium. Silverlight was shipped without any testing APIs. There are several libraries that provide a bridge for testing Flash. The Selenium project has though about including &lt;a href="http://www.gorillalogic.com/flexmonkey"&gt;FlexMonkey&lt;/a&gt;, but its GPL license prevents it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Practical Advice&lt;/strong&gt;&lt;br/&gt;
Everyone seems to build a framework on top of Selenium. If you do this, make sure and write your DSL in terms of intent and then map it to Selenium actions. &lt;/p&gt;
&lt;p&gt;Look for abstractions so you're not writing your Selenium tests with its API. It's too much like Assembler.&lt;/p&gt;
&lt;p&gt;K.I.S.S. - don't write large tests, just do small ones. Often, when functional tests fail, they tell you &lt;em&gt;something&lt;/em&gt; failed, but they don't tell you &lt;em&gt;what&lt;/em&gt; failed. The shortest possible functional tests help reduce the scope of where a problem can be. Other benefits of short tests are they're easier to read and easier to write.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Selenium 2.0&lt;/strong&gt;&lt;br/&gt;
The big thing in Selenium 2.0 is a merger with WebDriver. The nice thing about WebDriver is it gets rid of Selenium RC and allows you to drive the browser with a low-level API. For example, you use C++ to drive IE. Basically, every language will talk to the C driver. Except for Firefox, the connection and control is done through telnet. Selenium 2 should fix all the problems with Selenium 1, but also allow you to still use Selenium RC if you want to do grid-style testing.
&lt;/p&gt;
&lt;p&gt;Selenium 2's API is about finding elements and interacting with those elements. Also, it's entirely backwards compatible, so you can use the old API.
&lt;/p&gt;
&lt;p&gt;
At this point, my laptop's battery died and I was unable to take any more notes. However, I was able to see some pretty slick demos, particularly Jason's company's &lt;a href="http://saucelabs.com/products/sauce-ondemand"&gt;Sauce onDemand&lt;/a&gt; cloud testing services. All you need to do to run your tests in the cloud is change &lt;a href="http://saucelabs.com/products/docs/sauce-ondemand/basic-example-java"&gt;how you initialize Selenium&lt;/a&gt;. A kick-ass feature this service provides is &lt;a href="http://saucelabs.com/products/docs/sauce-ondemand%23video"&gt;video playback&lt;/a&gt; (a.k.a. Castro). I'm currently using Selenium's screenshot functionality, but it doesn't hold a candle to the ability to watch a video playback of your tests. Jason also showed us a demo of using Castro and Selenium 2 to create a screencast on-the-fly. Very cool stuff.&lt;/p&gt;
&lt;p&gt;
My only question after seeing this talk is what's the difference between &lt;a href="http://browsermob.com"&gt;BrowserMob&lt;/a&gt; and &lt;a href="http://saucelabs.com"&gt;Sauce Labs&lt;/a&gt;? Both companies were founded by Selenium committers and seem to offer competing projects. My gut feel is that BrowserMob is best for performance/load testing and Sauce Labs is best for running your tests in the cloud. &lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72945247&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72945247&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72945247 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/web_application_testing_with_selenium</guid><title>Web Application Testing with Selenium at Agile Denver next Monday</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/web_application_testing_with_selenium</link><pubDate>Thu, 11 Feb 2010 08:55:51 -0700</pubDate><category>Java</category><category>fattuesday</category><category>agiledenver</category><category>testing</category><category>selenium</category><category>denvertechmeetup</category><description>Next Monday evening, &lt;a href="http://twitter.com/hugs"&gt;Jason Huggins&lt;/a&gt; will be in Denver to talk about web application testing with Selenium. Below is an outline of Jason's talk:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Overview of Selenium, what it does, what it doesn't do&lt;/li&gt;
&lt;li&gt;How to get started with Selenium IDE, RC, and Grid&lt;/li&gt;
&lt;li&gt;Why I started Sauce Labs (Selenium as a Cloud Service)&lt;/li&gt;
&lt;li&gt;Selenium in 2010... Selenium 2&lt;/li&gt;
&lt;li&gt;Future trends: Adobe Flex, mobile (iphone/ipad, android), HTML5 (canvas, video)&lt;/li&gt;
&lt;li&gt;Best practices for succeeding with Selenium&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This is an &lt;a href="http://agiledenver.org/"&gt;Agile Denver&lt;/a&gt; event and I'm really looking forward to it. Prior to Jason's talk (at 6:30), I'll be participating in a panel with several other Denver Testing Experts to discuss Selenium and related topics. This event will be held at the PPA Event Center (&lt;a href="http://www.ppaeventcenter.com/eventcenter/directions.htm"&gt;directions&lt;/a&gt;). We expect a great turnout, so make sure and get there early! For more information, see &lt;a href="http://tech.groups.yahoo.com/group/djug/message/2133"&gt;the meeting announcement&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;On a related meetup note, don't forget &lt;a href="http://denvertechmeetup.com/2010/02/04/get-primed-up-for-fat-tuesday-at-this-months-meeting/"&gt;next Tuesday's Denver Tech Meetup&lt;/a&gt;. Last month was a lot of fun and next week's meetup happens to land on Fat Tuesday. I can't think of a good reason &lt;em&gt;not&lt;/em&gt; to come. &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;
&lt;/p&gt;
&lt;p&gt;If you'd like to RSVP for the Denver Tech Meetup, please do so on &lt;a href="http://events.linkedin.com/Denver-Tech-Meetup/pub/220984"&gt;LinkedIn&lt;/a&gt; or &lt;a href="http://www.facebook.com/event.php?eid=313562836809"&gt;Facebook&lt;/a&gt;.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72854024&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72854024&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72854024 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/17_macbook_pro_stolen_from</guid><title>17" MacBook Pro Stolen from Living Room</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/17_macbook_pro_stolen_from</link><pubDate>Wed, 3 Feb 2010 09:45:52 -0700</pubDate><category>Mac OS X</category><category>denver</category><category>du</category><category>burlary</category><category>theft</category><category>macbookpro</category><category>imac</category><description>Almost 3 years ago, I bought a &lt;a href="http://raibledesigns.com/rd/entry/a_new_17_powerhouse"&gt;17" MacBook Pro&lt;/a&gt;. This laptop served me well for several years, mostly as a home computer. A few months after I bought it, I started working at LinkedIn and got a brand new laptop as part of my &lt;a href="http://raibledesigns.com/rd/entry/first_day_at_linkedin"&gt;first day on the job&lt;/a&gt;. After working with LinkedIn's 15" for almost 2 years, I grew to love the form factor and &lt;a href="http://raibledesigns.com/rd/entry/new_15_macbook_pro_with"&gt;purchased another one&lt;/a&gt; almost a year ago. I found the 17" was too big for planes and the 15" fits me perfectly.&lt;/p&gt;
&lt;p&gt;Fast forward to last night.&lt;/p&gt;
&lt;p&gt;I attended the first half of the &lt;a href="http://www.denveropensource.org/node/2"&gt;Ignite talks at DOSUG&lt;/a&gt; and left around 7. When I arrived home, I suspected something might be out of whack when my front door was unlocked. Julie had come over to pick up Abbie's dance shoes around 6, so I figured she must've forgot to lock the door on her way out. When I got inside and saw my coat closet open, I justified it by thinking she grabbed one of the kids coats out of the closet and forgot to close the door. When I walked into my living room and saw my space heater's remote in the middle of the floor, busted open with batteries out, it clicked that a stranger was in my house. The first thing that jumped into my head was "Where's my laptop?" As I looked at the bare mini-desk in my living room, I realized it had been stolen.
&lt;/p&gt;
&lt;p&gt;I called Julie and asked her if she left the front door open. She said no, but when she arrived at my house (and came through the back), the garage's light was on and my back door was wide open. I asked her if she saw the busted remote on the floor or if the closet door was open. She said no. Putting all the pieces together, it &lt;em&gt;appears&lt;/em&gt; that the burglar was actually hiding in my closet when Julie came into my house. Naturally, she's a little a freaked out by this, but she also saved the day by scaring off perpetrator before they took anything else.
&lt;/p&gt;
&lt;p&gt;This isn't a new trend for me and this incident is mostly my fault. I left my backdoor unlocked. Two years ago, &lt;a href="http://raibledesigns.com/rd/entry/snow_white_gets_molested"&gt;my truck's stereo was stolen&lt;/a&gt; and there's a good chance I left the doors unlocked (and didn't turn on the alarm). Last year, &lt;a href="http://raibledesigns.com/rd/entry/r_i_p_giant_fcr3"&gt;my bike was stolen&lt;/a&gt; and the lock was still there, indicating I missed the frame when locking it up. So getting robbed in the first part of every year seems somewhat par for the course.
&lt;/p&gt;
&lt;p&gt;With my truck's stereo, it worked out well because the rig needed a new stereo. My bike last year? There wasn't any silver lining to that incident, so I &lt;a href="http://raibledesigns.com/rd/entry/running_to_work"&gt;made myself earn a new one&lt;/a&gt;. With this laptop incident, there &lt;em&gt;is&lt;/em&gt; a silver lining in that I've been thinking about getting a 27" iMac for a home computer. Other options include a Mac Pro for my office (and use my laptop for traveling/home use) or a Mac Mini for home and hook it up to my TV with a wireless keyboard and mouse. 
&lt;/p&gt;
&lt;p&gt;The home iMac seems like the best option, but I'd also be interested to hear what others recommend. Of course, I'll be keeping my doors locked from now on. &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72575164&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72575164&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72575164 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/using_jrebel_with_intellij_idea</guid><title>Using JRebel with IntelliJ IDEA on OS X</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/using_jrebel_with_intellij_idea</link><pubDate>Tue, 2 Feb 2010 10:34:08 -0700</pubDate><category>Java</category><category>intellij</category><category>idea</category><category>osx</category><category>java</category><category>jrebel</category><category>intellijidea</category><category>mac</category><description>Yesterday afternoon, I figured out how to use JRebel with IntelliJ IDEA. I wrote up some AppFuse documentation for it at &lt;a href="http://appfuse.org/display/APF/Using+JRebel+with+IntelliJ+IDEA"&gt;Using JRebel with IntelliJ IDEA&lt;/a&gt; and figured I'd repost it here for those developers using IDEA 9 and Maven.
&lt;/p&gt;
&lt;div style="border-bottom: 1px dotted silver; margin-bottom: 10px"&gt;&lt;/div&gt;
&lt;ol&gt;&lt;li&gt;
&lt;a href="http://www.jetbrains.com/idea/download/"&gt;Download&lt;/a&gt; and install IntelliJ IDEA 9 Ultimate Edition (in /Applications on OS X).&lt;/li&gt;

	&lt;li&gt;&lt;a href="http://www.zeroturnaround.com/jrebel/"&gt;Download&lt;/a&gt; and install JRebel.
	&lt;ol style="margin-bottom: 0"&gt;
		&lt;li&gt;&lt;code&gt;java -jar jrebel-setup.jar&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Install the &lt;a href="http://www.zeroturnaround.com/intellij-idea-jrebel-tutorial-formerly-javarebel/"&gt;JRebel Plugin for IDEA&lt;/a&gt;. Shortcut: File &amp;gt; Settings &amp;gt; Search for plugins and find JRebel.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
	&lt;li&gt;On OS X, Modify /etc/launchd.conf and add the following so M2_HOME is available to GUI apps. You'll need to reboot after making this change.
&lt;pre style="margin-top: 10px"&gt;
setenv M2_HOME /opt/tools/maven2
&lt;/pre&gt;
&lt;p&gt;More info on this setting is &lt;a href="http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x"&gt;available on Stack Overflow&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;Modify your project's pom.xml to include the &lt;a href="http://www.zeroturnaround.com/jrebel/configuration/maven/"&gt;JRebel Maven plugin&lt;/a&gt; (for generating the configuration of which directories and files to watch for changes).
&lt;pre class="brush: xml"&gt;&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.zeroturnaround&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;javarebel-maven-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.5&amp;lt;/version&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
          &amp;lt;id&amp;gt;generate-rebel-xml&amp;lt;/id&amp;gt;
          &amp;lt;phase&amp;gt;process-resources&amp;lt;/phase&amp;gt;
          &amp;lt;goals&amp;gt;
              &amp;lt;goal&amp;gt;generate&amp;lt;/goal&amp;gt;
          &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
    &lt;li&gt;If you're using the &lt;a href="http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin"&gt;Maven Jetty plugin&lt;/a&gt;, change your pom.xml so Jetty doesn't reload the app when classes are compiled. Specifically, change &lt;em&gt;scanIntervalSeconds&lt;/em&gt; to 0. If you're not using this plugin, you should definitely check it out for Java webapp development.&lt;/li&gt;
	&lt;li&gt;Use the JRebel icons to start jetty:run in your IDE.
&lt;a href="http://farm3.static.flickr.com/2761/4325774388_e31429dd89_o.png" title="JRebel with IntelliJ IDEA" rel="lightbox[jrebelintellijidea]"&gt;&lt;img src="http://farm3.static.flickr.com/2761/4325774388_5b8a173bec.jpg" width="500" height="299" alt="JRebel with IntelliJ IDEA" style="border: 1px solid silver; margin-top: 5px" /&gt;&lt;/a&gt;
&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Command Line Integration:&lt;/strong&gt; Set a JREBEL_HOME environment variable that points to your JRebel install (/Applications/ZeroTurnaround/JRebel on OS X) and set your MAVEN_OPTS to use JRebel's settings. For example:
&lt;pre style="margin-top: 10px"&gt;
export JAVA_OPTS="-Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true"
export JREBEL_HOME=/Applications/ZeroTurnaround/JRebel 
export MAVEN_OPTS="$JAVA_OPTS -noverify -javaagent:$JREBEL_HOME/jrebel.jar"
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After making these changes, you should able to compile classes in IDEA and refresh your browser. Log messages like the following should show up in your console.&lt;/p&gt;

&lt;pre style="background: black; color: white"&gt;JRebel: Reloading class 'org.appfuse.webapp.action.UserAction'.
&lt;/pre&gt;

&lt;p&gt;To simplify things further, you can map Command+S to compile (instead of Shift+F9). Just look for Keymaps in Settings, rename the default one and search for Compile to remap.&lt;/p&gt;
&lt;p&gt;I'm assuming the steps to make things work on Windows and Linux are similar. Please let me know if you have any issues with these instructions.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72428718&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72428718&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72428718 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/reviews_for_grails_a_quick</guid><title>Reviews for Grails: A Quick-Start Guide and Kanban and Scrum</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/reviews_for_grails_a_quick</link><pubDate>Mon, 1 Feb 2010 09:29:40 -0700</pubDate><category>Java</category><category>grails</category><category>kanban</category><category>books</category><category>infoq</category><category>scrum</category><category>bookreview</category><description>A couple weeks ago, I had a business trip from Denver to Washington, DC. Since I didn't have any coding to do on the flight, I brought along a couple books and was surprisingly able to finish them both en route. Tech books that can be read in a single flight are my favorite. Another book I recall doing this with was &lt;a href="http://www.firststepsinflex.com/"&gt;First Steps in Flex&lt;/a&gt; back in December.&lt;/p&gt;
&lt;p&gt;The books I read were Dave Klein's &lt;a href="http://www.pragprog.com/titles/dkgrails/grails"&gt;Grails: A Quick-Start Guide&lt;/a&gt; and Henrik Kniberg and Mattias Skarin's &lt;a href="http://www.infoq.com/minibooks/kanban-scrum-minibook"&gt;Kanban and Scrum minibook&lt;/a&gt;. Below are short reviews of each book.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Grails: A Quick-Start Guide&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://www.pragprog.com/titles/dkgrails/grails"&gt;&lt;img src="http://farm5.static.flickr.com/4009/4317526332_c8d18eb3f9_t.jpg" width="83" height="100" class="picture" style="border: 1px solid silver" /&gt;&lt;/a&gt;
I've developed a few Grails applications, so I didn't expect to learn a whole lot from this book, but I was pleasantly surprised. Not only did it introduce all the basic concepts in a clear and concise way, it actually made it fun to read. The first chapter does a good job of introducing Groovy; showing you how to use closures and the easy-to-use collections API. From there, you dive into learning about the project, which is actually a real-life web application called &lt;a href="http://tekdays.com/"&gt;TekDays.com&lt;/a&gt;. Then the foundational Iteration Zero is planned and executed.&lt;/p&gt;

&lt;p&gt;In Chapter 3, you dive right into creating domain classes and their relationships. All the different mapping types are covered: one-to-one, one-to-many and the good ol' many-to-many. Since this is often a difficult part of an application, it's always nice to see how much Grails simplifies it. I liked the Ajax section in Chapter 7 and especially the part where it showed how to do a TagLib to show threaded comments in a forum.&lt;/p&gt;
&lt;p&gt;Chapter 7 (Security) was a little disappointing in that it showed how to hand-roll your own security rather than using the &lt;a href="http://grails.org/plugin/acegi"&gt;Spring Security plugin&lt;/a&gt; (formerly Acegi) or the &lt;a href="http://grails.org/plugin/shiro"&gt;Shiro plugin&lt;/a&gt; (formerly JSecurity). I'd especially have liked to see how to do Ajax authentication where a token is generated for the client and included as a header in each subsequent request.
&lt;/p&gt;
&lt;p&gt;Other than that, I really enjoyed Chapter 10 where I learned how to implement search using dynamic finders, Hibernate's Criteria API and the &lt;a href="http://grails.org/Searchable+Plugin"&gt;Searchable Plugin&lt;/a&gt; (which gets its awesomeness from &lt;a href="http://www.compass-project.org/"&gt;Compass&lt;/a&gt;). Implementing Compass in Java requires many, many annotations. In Grails, it's as simple as adding the following to your domain class.
&lt;/p&gt;
&lt;pre&gt;
static searchable = true
&lt;/pre&gt;
&lt;p&gt;I truly enjoyed this book, especially with its Agile Development patterns that used iterations to get things done. Grails: A Quick-Start Guide is a code-intensive journey that gets up you to speed on Grails quickly and efficiently. It's very much like the framework itself. It eliminates the yak shaving and allows you learn without distractions. Kudos to Dave Klein for creating such an enjoyable and easy-to-read book. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Kanban and Scrum&lt;/strong&gt;
&lt;br/&gt;
&lt;a href="http://www.infoq.com/minibooks/kanban-scrum-minibook"&gt;&lt;img src="http://farm3.static.flickr.com/2732/4317526382_473ba07fa0_t.jpg" width="81" height="100" class="picture" style="border: 0" /&gt;&lt;/a&gt;
In my career, I've used Scrum on quite a few projects. Of course, it's not the processes that typically make a team successful. Rather, it's often the gelling of the team members, as well as respect for coding practices that are proven to create higher quality code - specifically TDD and pair programming. Before reading this book, I'd heard a bit about Kanban, most of it from &lt;a href="http://martyhaught.com/"&gt;Marty Haught's&lt;/a&gt; &lt;a href="http://raibledesigns.com/rd/entry/lean_teams_doing_more_with"&gt;Lean Teams: Doing more with less&lt;/a&gt; presentation. 
&lt;/p&gt;
&lt;p&gt;This book did a great job of showing the differences between the two approaches: how Scrum promotes iterations whereas Kanban promotes cycle time. The most interesting part of the book is the Case Study in the 2nd half. This section shows how a team used various techniques to develop a well-oiled development machine. I think the most important thing to note from this section is how the team was willing to change, learn and grow based on their experiences - in a very rapid fashion.&lt;/p&gt;
&lt;p&gt;In my current gig, I'm helping a team of developers move from waterfall to agile processes. We're leveraging many aspects of Scrum and agile by using a coach, iterations, daily standups, TDD, continuous integration and creating "as built" documentation when we finish developing a feature. The "As Built" documentation is something I picked up from working at &lt;a href="http://www.chordiant.com"&gt;Chordiant&lt;/a&gt; and I've found it to be a great way of education developers (and outsiders) how things were done in an iteration.&lt;/p&gt;
&lt;p&gt;One thing we've seen in our first few weeks is that iterations don't work for all teams or individuals. A Kanban model fits much better for them. Having a Kanban board allows them to visualize (and control) their workload in a much more efficient manner. We haven't started implementing actual boards on a wall, we're just using spreadsheets for now. However, we do have two Agile Coaches starting this week so I expect things to improve rapidly. 
&lt;/p&gt;
&lt;p&gt;Back to the book. More than anything, I enjoyed reading this book because it made me excited about the changes I'm helping implement and I believe in many of the practices in both Scrum and Kanban. I enjoy iterations and structured expectations around development, but I can see how Kanban would work better for folks in operations and infrastructure. I look forward to implementing the best parts of both worlds and hopefully a similar Case Study of what worked and what didn't. With any luck, we'll be able to learn, evolve and produce at a much higher level than previous waterfall practices achieved.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72399156&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72399156&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72399156 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/upside_down_man_saves_the</guid><title>Upside Down Man Saves the Day</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/upside_down_man_saves_the</link><pubDate>Sun, 31 Jan 2010 16:54:31 -0700</pubDate><category>General</category><category>jack</category><category>abbie</category><category>video</category><category>superhero</category><category>upsidedownman</category><category>youtube</category><description>Yesterday, Abbie and Jack &lt;a href="http://raibledesigns.com/rd/entry/how_to_be_a_super"&gt;showed you how to be a superhero&lt;/a&gt;. Today they're back with an action-packed video titled Upside Down Man Saves the Day. Watch it if you'd like to see how to take out a tiger, wrestle an alligator and diffuse a bomb. This short film was written, directed and filmed by Abbie, the only thing I did was add the music. &lt;em&gt;Enjoy!&lt;/em&gt; &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;object width="500" height="315"&gt;&lt;param name="movie" value="http://www.youtube.com/v/g1ZjqHX2q7E&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;hd=1&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/g1ZjqHX2q7E&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;hd=1&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="315"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;If you have trouble viewing it here, &lt;a href="http://www.youtube.com/watch?v=g1ZjqHX2q7E"&gt;check it out on YouTube&lt;/a&gt;.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72399155&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72399155&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72399155 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/how_to_be_a_super</guid><title>How to be a Super Hero by Abbie and Jack</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/how_to_be_a_super</link><pubDate>Sat, 30 Jan 2010 16:42:29 -0700</pubDate><category>General</category><category>superhero</category><category>abbie</category><category>jack</category><category>youtube</category><category>video</category><description>For some reason, my kids are very interested in Super Heros lately. In fact, they know so much about them that they've decided to start teaching others how to become one. Checkout the videos we shot earlier today with their step-by-step instructions.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;object width="500" height="315"&gt;&lt;param name="movie" value="http://www.youtube.com/v/sg0ggFFUtQk&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;hd=1&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/sg0ggFFUtQk&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;hd=1&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="315"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;object width="500" height="315"&gt;&lt;param name="movie" value="http://www.youtube.com/v/PK4Jrtk7e40&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;hd=1&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/PK4Jrtk7e40&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;hd=1&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="315"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;I hope Abbie and Jack's tips help you become a super hero! &lt;img src="http://raibledesigns.com/images/smileys/smile.gif" class="smiley" alt=":-)" title=":-)" /&gt;
&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=72399154&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=72399154&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=72399154 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/what_s_your_preferred_development</guid><title>What's your preferred development infrastructure stack?</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/what_s_your_preferred_development</link><pubDate>Tue, 12 Jan 2010 21:54:46 -0700</pubDate><category>Java</category><category>fisheye</category><category>jivesoftware</category><category>cvs</category><category>bugzilla</category><category>mediawiki</category><category>jivesbs</category><category>viewvc</category><category>atlassian</category><category>bamboo</category><category>subversion</category><category>sventon</category><category>clearspace</category><category>jirastudio</category><category>starteam</category><category>chordiant</category><category>hudson</category><category>git</category><category>confluence</category><category>trac</category><category>jira</category><category>jspwiki</category><category>cruisecontrol</category><description>Over the years, I've used many different source control systems, wikis, bug trackers and continuous integration servers. On many projects, I've been responsible for recommending and helping to install these systems. For the most part, they've often been disparate, meaning there wasn't a whole lot of integration between the various applications. Here's a list of all the different systems I've used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source Control Systems
&lt;ul style="margin-bottom: 0"&gt;
&lt;li&gt;&lt;a href="http://www.nongnu.org/cvs/"&gt;CVS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.borland.com/us/products/starteam/index.html"&gt;StarTeam&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://subversion.apache.org/"&gt;Subversion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Source Viewers
&lt;ul style="margin-bottom: 0"&gt;
&lt;li&gt;&lt;a href="http://www.atlassian.com/software/fisheye/"&gt;FishEye&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sventon.org/"&gt;Sventon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.viewvc.org/"&gt;ViewVC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Wikis
&lt;ul style="margin-bottom: 0"&gt;
&lt;li&gt;&lt;a href="http://www.atlassian.com/software/confluence/"&gt;Confluence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mediawiki.org/wiki/MediaWiki"&gt;MediaWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jspwiki.org/"&gt;JSPWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bug Trackers
&lt;ul style="margin-bottom: 0"&gt;
&lt;li&gt;&lt;a href="http://www.bugzilla.org/"&gt;Bugzilla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.borland.com/us/products/starteam/index.html"&gt;StarTeam&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Continuous Integration Servers
&lt;ul style="margin-bottom: 0"&gt;
&lt;li&gt;&lt;a href="http://www.atlassian.com/software/bamboo/"&gt;Bamboo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://continuum.apache.org/"&gt;Continuum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mailing Lists / Forums
&lt;ul style="margin-bottom: 0"&gt;
&lt;li&gt;A private &lt;a href="http://groups.google.com"&gt;Google Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jivesoftware.com/beyond/forums"&gt;Jive Forums&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.gnu.org/software/mailman/index.html"&gt;Mailman&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I believe all of these applications are useful in supporting an efficient development process. When clients have asked me to help them build this type of infrastructure, I've often asked if they wanted to pay for it or not. If not, I'd recommend Trac (since it has a wiki, source viewer and bug tracker all-in-one) and Hudson. If they were willing to pay, I'd recommend the Atlassian Suite (Confluence, JIRA and Bamboo). 
&lt;/p&gt;
&lt;p&gt;These stacks all seem to work &lt;em&gt;pretty well&lt;/em&gt; and the Atlassian Suite certainly works great for &lt;a href="http://appfuse.org"&gt;AppFuse&lt;/a&gt; and other open source projects. However, I recently had the pleasure of working at &lt;a href="http://chordiant.com"&gt;Chordiant Software&lt;/a&gt; where we used &lt;a href="http://www.chordiant.com/cx/mesh.html"&gt;Chordiant Mesh&lt;/a&gt; to collaborate and develop software. Their Mesh system is powered by &lt;a href="http://www.jivesoftware.com/beyond/clearspace"&gt;Jive  Clearspace&lt;/a&gt; and provides a wealth of tools for each project, including a dashboard, discussions, documents, notifications and widgets providing status + links to JIRA and Bamboo. 
&lt;/p&gt;
&lt;p&gt;
Even though Clearspace's rich text editor caused me some early frustration, I really enjoyed the fact that a solid development infrastructure existed. It made it much easier to collaborate, document and execute our development process. I realize that it's difficult to build and maintain a custom development infrastructure stack. Chordiant had a whole team that developed, enhanced and supported their environment. But that doesn't mean it's impossible and not worth striving for. 
&lt;/p&gt;
&lt;p&gt;
I think there's a number of best-of-breed applications you can use to build a sweet development infrastructure stack. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source Control: &lt;strong&gt;Git&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Source Viewer: &lt;strong&gt;FishEye&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Wiki: &lt;strong&gt;Jive SBS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Bug Tracker: &lt;strong&gt;JIRA&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Continuous Integration: &lt;strong&gt;Hudson&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I've only used Git for a few weeks, but I can easily tell it's better than Subversion. I don't think it's easy to convince companies to switch their source control system, so it's probably not worth arguing if you're already using Subversion. I can also envision using Confluence instead of Jive SBS, but then you lose forum support and have to use something like Mailman or Google Groups. &lt;a href="http://www.atlassian.com/studio/"&gt;JIRA Studio&lt;/a&gt; looks close to my dream stack, except it doesn't support Git or a forum + mailing list system.&lt;/p&gt;
&lt;p&gt;
What is your preferred development infrastructure stack? Why?&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=71607868&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=71607868&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=71607868 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/2009_a_year_in_review</guid><title>2009 - A Year in Review</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/2009_a_year_in_review</link><pubDate>Mon, 11 Jan 2010 10:06:09 -0700</pubDate><category>Roller</category><category>roller</category><category>newyear</category><category>2010</category><category>blogging</category><category>yearinreview</category><description>I wrote my first "year in review" post in &lt;a href="http://raibledesigns.com/rd/entry/2005_a_year_in_review"&gt;2005&lt;/a&gt; and continued the tradition in &lt;a href="http://raibledesigns.com/rd/entry/2006_a_year_in_review"&gt;2006&lt;/a&gt; and &lt;a href="http://raibledesigns.com/rd/entry/2008_a_year_in_review"&gt;2008&lt;/a&gt;. This year, my December was filled with &lt;a href="http://twitter.com/mraible/status/6376757616" title="Arrived home to the sound of a waterfall. Water pipes burst in guest room. Doh!"&gt;unplanned circumstances&lt;/a&gt;, a new job and a houseful of family for the holidays, so I never had time to sit down and write this post. As things are returning to normal, I figured it's about time I kicked off 2010 with one of my favorite writing reflections.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://farm4.static.flickr.com/3099/3218234204_c8a83629c6.jpg" title="Experts Only" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3099/3218234204_c8a83629c6_t.jpg" width="100" height="75" alt="Experts Only" class="picture" /&gt;&lt;/a&gt;
2009 started off with a bang: I wrote about my Mom &lt;a href="http://raibledesigns.com/rd/entry/happy_birthday_mom"&gt;nailing a bear's nuts to a tree after she killed it&lt;/a&gt;. My new gig (at Evite) started out fun with &lt;a href="http://raibledesigns.com/rd/entry/choosing_an_ajax_framework"&gt;choosing an Ajax framework&lt;/a&gt; and a &lt;a href="http://raibledesigns.com/rd/entry/la_tech_meetup_tonight"&gt;Tech Meetup in LA&lt;/a&gt;. My &lt;a href="http://raibledesigns.com/rd/entry/r_i_p_giant_fcr3"&gt;bike got stolen&lt;/a&gt;, I started &lt;a href="http://raibledesigns.com/rd/entry/running_to_work"&gt;running to work&lt;/a&gt; and &lt;a href="http://raibledesigns.com/rd/entry/traveling_to_tahoe_without_a"&gt;traveled to Tahoe without an ID&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;
February started off with an &lt;a href="http://raibledesigns.com/rd/entry/epic_weekend_at_silverton_mountain"&gt;epic weekend at Silverton&lt;/a&gt;. I went to &lt;a href="http://north09.webdirections.org/"&gt;Web Directions North&lt;/a&gt; and attended many good talks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://raibledesigns.com/rd/entry/changes_in_the_languages_of"&gt;Changes in the Languages of The Web&lt;/a&gt;
&lt;li&gt;&lt;a href="http://raibledesigns.com/rd/entry/the_state_of_the_web"&gt;The State of the Web 2009&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://raibledesigns.com/rd/entry/ajax_the_state_of_the"&gt;Ajax: The State of the Art&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wrote my first &lt;a href="http://raibledesigns.com/rd/entry/testing_gwt_applications" title="Testing GWT Applications"&gt;GWT-related entry&lt;/a&gt; and a few posts related to independent consulting.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://raibledesigns.com/rd/entry/how_to_setup_your_own"&gt;How To Setup Your Own Software Development Company&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://raibledesigns.com/rd/entry/writing_off_home_office_space"&gt;Writing Off Home Office Space&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://raibledesigns.com/rd/entry/what_s_the_best_retirement"&gt;What's the Best Retirement Plan for Independent Consultants?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I ended February with a &lt;a href="http://raibledesigns.com/rd/entry/enhancing_your_gwt_application_with" title="Enhancing your GWT Application with the UrlRewriteFilter"&gt;couple&lt;/a&gt; &lt;a href="http://raibledesigns.com/rd/entry/gwttestsuite_makes_builds_faster_but" title="GWTTestSuite makes builds faster, but requires JUnit 4.1"&gt;more&lt;/a&gt; GWT-related entries.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://farm4.static.flickr.com/3658/3343506648_caa24e1d39.jpg" title="On the top" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3658/3343506648_caa24e1d39_t.jpg" width="100" height="75" alt="On the top" class="picture"/&gt;&lt;/a&gt;

In March, I bought a &lt;a href="http://raibledesigns.com/rd/entry/new_15_macbook_pro_with"&gt;new 15" MacBook Pro&lt;/a&gt; and shipped it back shortly after to get a 256 GB SSD. I still have nothing but good things to say about the machine. I discovered &lt;a href="http://raibledesigns.com/rd/entry/nexus_is_a_kick_ass"&gt;Nexus is awesome&lt;/a&gt; and the kids and I went on our &lt;a href="http://raibledesigns.com/rd/entry/1st_hike_of_2009"&gt;first hike of the year&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;My GWT Journey continued with &lt;a href="http://raibledesigns.com/rd/entry/gxt_s_mvc_framework"&gt;GXT MVC&lt;/a&gt;, &lt;a href="http://raibledesigns.com/rd/entry/modularizing_gwt_applications_with_gwt"&gt;modularization&lt;/a&gt; and &lt;a href="http://raibledesigns.com/rd/entry/optimizing_a_gwt_application_with"&gt;optimization&lt;/a&gt;. I got a &lt;a href="http://raibledesigns.com/rd/entry/new_office_and_new_bike"&gt;new office and new bike&lt;/a&gt; and proudly witnessed my &lt;a href="http://raibledesigns.com/rd/entry/congratulations_on_retiring_dad"&gt;Dad's Retirement&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;April came and I &lt;a href="http://raibledesigns.com/rd/entry/my_drunk_on_software_interview"&gt;got Drunk on Software&lt;/a&gt;, had a blast at &lt;a href="http://raibledesigns.com/rd/entry/jason_and_holly_s_wedding"&gt;Holly and Jason's Wedding&lt;/a&gt; and published our &lt;a href="http://raibledesigns.com/rd/entry/ajax_framework_analysis_results"&gt;Ajax Framework Analysis Results&lt;/a&gt;. 
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm4.static.flickr.com/3545/3461916124_11582cee7c.jpg" title="Mr. and Mrs. Harris" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3545/3461916124_11582cee7c_m.jpg" width="240" height="180" alt="Mr. and Mrs. Harris" style="border: 1px solid black"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;At the end of April, I started &lt;a href="http://raibledesigns.com/rd/entry/life_update_new_treehouse_new"&gt;building the kids a treehouse and inspired smiles with two new kittens&lt;/a&gt;. On May 7th, I had PRK eye surgery and &lt;a href="http://raibledesigns.com/rd/entry/my_eye_surgery_experience"&gt;wrote about my experience in early June&lt;/a&gt;. I continue to be extremely happy with the results.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm4.static.flickr.com/3656/3471565132_7a5e4ebdb2.jpg" title="Day 3 - They love it!" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3656/3471565132_7a5e4ebdb2_t.jpg" width="100" height="75" alt="Day 3 - They love it!" style="border: 1px solid black"/&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3545/3470751035_d016beb0d9.jpg" title="Day 4 - Floor completed" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3545/3470751035_d016beb0d9_t.jpg" width="100" height="75" alt="Day 4 - Floor completed" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3360/3505899171_3cb4e849b1.jpg" title="Jack and Olivia" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3360/3505899171_3cb4e849b1_t.jpg" width="100" height="75" alt="Jack and Olivia" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3562/3506709142_21fa103252.jpg" title="Abbie and Mittens" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3562/3506709142_21fa103252_t.jpg" width="100" height="75" alt="Abbie and Mittens" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;May ended with &lt;a href="http://raibledesigns.com/rd/entry/ryan_and_breanne_s_wedding"&gt;Ryan and Breanne's Wedding in Playa Del Carmen&lt;/a&gt;. Having so many great friends around and the Nuggets vs. Lakers playoffs the same week made this one of the best vacations of my life.&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm4.static.flickr.com/3618/3580803902_449464cf49.jpg" title="Ready for the Ceremony" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3618/3580803902_449464cf49_t.jpg" width="100" height="75" alt="Ready for the Ceremony" style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3644/3579992115_05c0cb7b7f.jpg" title="Vows" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3644/3579992115_05c0cb7b7f_t.jpg" width="100" height="75" alt="Vows" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3153/3580823360_3e2e997894.jpg" title="Mariachi Band" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3153/3580823360_3e2e997894_t.jpg" width="100" height="75" alt="Mariachi Band" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3374/3580011379_fa403528cb.jpg" title="Mr. and Mrs. Johnson" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3374/3580011379_fa403528cb_t.jpg" width="100" height="75" alt="Mr. and Mrs. Johnson" style="border: 1px solid black; margin-left: 10px" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;June brought the news that the &lt;a href="http://raibledesigns.com/rd/entry/the_end_of_colorado_software"&gt;Colorado Software Summit was over&lt;/a&gt;. There's been several times in the past few months that I've missed the annual experience. Can someone please start a conference at a Colorado mountain resort in the near future? Pretty please! I've always experienced this conference with &lt;a href="http://bsnyderblog.blogspot.com/"&gt;Bruce&lt;/a&gt; and we continued another tradition (riding to Red Rocks) with &lt;a href="http://raibledesigns.com/rd/entry/2nd_row_at_red_rocks"&gt;2nd Row seats at Big Head Todd&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;My GWT posts continued with a &lt;a href="http://raibledesigns.com/rd/entry/creating_a_facebook_style_autocomplete"&gt;Facebook-style Autocomplete&lt;/a&gt;, &lt;a href="http://raibledesigns.com/rd/entry/implementing_oauth_with_gwt"&gt;Implementing OAuth&lt;/a&gt;, &lt;a href="http://raibledesigns.com/rd/entry/json_parsing_with_javascript_overlay"&gt;JSON Parsing with JavaScript Overlays&lt;/a&gt; and a preview of &lt;a href="http://raibledesigns.com/rd/entry/how_to_use_gwt_2"&gt;GWT 2.0&lt;/a&gt;. I wrote about &lt;a href="http://raibledesigns.com/rd/entry/enhancing_evite_com_with_gwt"&gt;implementing SOFEA with GWT and Grails at Evite.com&lt;/a&gt; and &lt;a href="http://raibledesigns.com/rd/entry/a_fun_father_s_day"&gt;had a blast at the Great Sand Dunes on Father's Day&lt;/a&gt;. 
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2461/3655577467_c84ac6e9d7.jpg" title="Abbie and Cookie at The Dunes" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm3.static.flickr.com/2461/3655577467_c84ac6e9d7_m.jpg" width="240" height="180" alt="Abbie and Cookie at The Dunes" style="border: 1px solid black" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
My &lt;a href="http://raibledesigns.com/rd/entry/the_good_ol_job_hunt1"&gt;job hunt&lt;/a&gt; began and I started a month-long vacation in Montana with &lt;a href="http://raibledesigns.com/rd/entry/raible_road_trip_13"&gt;Raible Road Trip #13&lt;/a&gt;. Vacationing for a summer month in Montana has been one of my goals for several years. Accomplishing it this year made me extremely happy and I hope to make it a summer tradition.&lt;/p&gt;
&lt;p&gt;July was an awesome month in 2009. Granted, April and May were special with tropical weddings, but Montana in July is a particularly tasty treat. &lt;a href="http://raibledesigns.com/rd/entry/my_summer_vacation_in_montana"&gt;My Summer Vacation in Montana&lt;/a&gt; attempts to capture how much fun we had. It was particularly enjoyable because my parents, children and many life-long friends were involved.&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2568/3769250242_a002f5d6cb.jpg" title="View of the Missions from Holland Falls" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm3.static.flickr.com/2568/3769250242_a002f5d6cb_t.jpg" width="100" height="75" alt="View of the Missions from Holland Falls" style="border: 1px solid black" /&gt;&lt;/a&gt;

&lt;a href="http://farm3.static.flickr.com/2431/3769250820_19d03c599b.jpg" title="Ready for the Celebrate the Swan Race" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm3.static.flickr.com/2431/3769250820_19d03c599b_t.jpg" width="100" height="75" alt="Ready for the Celebrate the Swan Race" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3293/3769258046_9613fca22c.jpg" title="Horseshoes" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3293/3769258046_9613fca22c_t.jpg" width="100" height="75" alt="Horseshoes" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;

&lt;a href="http://farm4.static.flickr.com/3612/3768465807_39e1cf17f6.jpg" title="Floor Pouring Crew" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm4.static.flickr.com/3612/3768465807_39e1cf17f6_t.jpg" width="100" height="75" alt="Floor Pouring Crew" style="border: 1px solid black; margin-left: 10px"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
As summer began to set, I decided to get back into speaking at conferences, starting with the &lt;a href="http://raibledesigns.com/rd/entry/the_2009_rich_web_experience"&gt;Rich Web Experience&lt;/a&gt;. I wrote about &lt;a href="http://raibledesigns.com/rd/entry/how_to_do_cross_domain" title="How to do cross-domain GWT RPC with a ProxyServlet"&gt;initial&lt;/a&gt; &lt;a href="http://raibledesigns.com/rd/entry/integrating_gwt_with_spring_security" title="Integrating GWT with Spring Security"&gt;GWT&lt;/a&gt; &lt;a href="http://raibledesigns.com/rd/entry/browser_based_username_password_autocomplete" title="My attempt at browser-based username/password autocomplete with GWT"&gt;work&lt;/a&gt; at my &lt;a href="http://chordiant.com/" title="Chordiant Software"&gt;new client&lt;/a&gt;, which included an interesting &lt;a href="http://raibledesigns.com/rd/entry/my_experience_with_java_rest" title="My Experience with Java REST Frameworks (specifically Jersey and CXF)"&gt;experience with Java REST Frameworks&lt;/a&gt;. The month ended with one of my favorite holidays: &lt;a href="http://raibledesigns.com/rd/entry/happy_birthday_jack3"&gt;Jack's Birthday&lt;/a&gt;.

&lt;/p&gt;
&lt;p&gt;September was nice and uneventful. I learned about &lt;a href="http://raibledesigns.com/rd/entry/concurrency_on_the_jvm_using" title="Concurrency on the JVM Using Scala with Venkat Subramaniam"&gt;Concurrency on the JVM Using Scala&lt;/a&gt;, started using &lt;a href="http://raibledesigns.com/rd/entry/building_gwt_applications_with_mvp" title="Building GWT Applications with MVP and Issues with Overlay Types"&gt;MVP with GWT&lt;/a&gt; and learned how to &lt;a href="http://raibledesigns.com/rd/entry/lean_teams_doing_more_with" title="Lean Teams: Doing more with less (Derailed)"&gt;do more with less&lt;/a&gt;. I also ran in a &lt;a href="http://www.fansonthefield.com/"&gt;10K&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;October started out with a family trip to Washington for &lt;a href="http://raibledesigns.com/rd/entry/my_sister_s_fabulous_wedding"&gt;my sister's fabulous wedding&lt;/a&gt;. People flew in from all over the US and we had a sweet condo on Lake Chelan for the week. Playing golf, wine tasting and celebrating with good people made for a great start to the fall season.&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2537/4142221061_af166b8b3b.jpg" title="Kalin and Mya" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm3.static.flickr.com/2537/4142221061_af166b8b3b_m.jpg" width="240" height="160" alt="Kalin and Mya" style="border: 1px solid black" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://farm3.static.flickr.com/2737/4104358666_a4628d6e38.jpg" title="Abbie and Charles" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm3.static.flickr.com/2737/4104358666_a4628d6e38_t.jpg" width="100" height="75" alt="Abbie and Charles" class="picture" /&gt;&lt;/a&gt;
In November, I started writing more, mostly because I was gearing up for &lt;a href="http://raibledesigns.com/rd/entry/the_future_of_web_frameworks" title="The Future of Web Frameworks at TSSJS"&gt;upcoming&lt;/a&gt; &lt;a href="http://raibledesigns.com/rd/entry/consulting_sofea_grails_and_gwt" title="Building SOFEA Applications with GWT and Grails"&gt;talks&lt;/a&gt; and &lt;a href="http://raibledesigns.com/rd/entry/a_letter_to_the_appfuse" title="A Letter to the AppFuse Community"&gt;thinking about&lt;/a&gt; / &lt;a href="http://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1" title="AppFuse 2.1 Milestone 1 Released"&gt;working on AppFuse&lt;/a&gt;. I celebrated &lt;a href="http://raibledesigns.com/rd/entry/happy_birthday_abbie5"&gt;Abbie's Birthday&lt;/a&gt;, did some &lt;a href="http://raibledesigns.com/rd/entry/javascript_and_css_concatenation"&gt;website&lt;/a&gt; &lt;a href="http://raibledesigns.com/rd/entry/adding_expires_headers_with_oscache"&gt;optimization&lt;/a&gt; and chuckled at the comments about my &lt;a href="http://raibledesigns.com/rd/entry/my_hunting_season_adventure_at"&gt;hunting season adventure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Right before Thanksgiving, I got a call from my client letting me know that their budget had run out my contract would end soon. Luckily, I had an interview setup the next day and had great success in finding a new gig.&lt;/p&gt;
&lt;p&gt;I ended November with a trip to Oregon for Thanksgiving and ran in the &lt;a href="http://www.omroadrace.org/"&gt;Oregon Mid-Valley Road Race&lt;/a&gt;. The followed week, I flew with my kids and parents to The Rich Web Experience and learned about &lt;a href="http://raibledesigns.com/rd/entry/introduction_to_objective_j_and"&gt;Objective-J and Cappuccino&lt;/a&gt;. I had a near-perfect (high 70s, no lines) Disney World experience with my family, watched the Ducks with the &lt;a href="http://en.wikipedia.org/wiki/Civil_War_%28college_football_game%29"&gt;Civil War&lt;/a&gt; and &lt;a href="http://raibledesigns.com/rd/entry/comparing_kick_ass_web_frameworks"&gt;compared kick-ass web frameworks&lt;/a&gt;.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2767/4253979011_4bc9a5e350.jpg" title="Kids at Loews Portofino, Universal Studios Florida" rel="lightbox[2009yearinreview]"&gt;&lt;img src="http://farm3.static.flickr.com/2767/4253979011_4bc9a5e350_m.jpg" width="240" height="180" alt="Kids at Loews Portofino, Universal Studios Florida" style="border: 1px solid black" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;In December, I didn't do much blogging - mostly because I arrived home from Florida to discover a waterfall in my guest room. The water pipes were routed through the ceiling, had &lt;a href="http://twitpic.com/s9xo9"&gt;busted from the cold&lt;/a&gt;, and water was pouring everywhere. Dealing with that and starting a new job occupied most of my time and I never got a chance to write much down. I ran in the &lt;a href="http://www.arthritis.org/jingle-bell-run.php"&gt;Jingle Bell 5K&lt;/a&gt; and watched the Broncos lose a lot. Shortly after, my family came for Christmas and a good time was had by all.
&lt;/p&gt;
&lt;p&gt;As I reflect back on last year, my biggest surprise is that I got into running. I ended up running in 5 races last year and even enjoyed doing it a few times. It's still not my favorite activity (skiing and mountain biking win that title), but I enjoy it enough to do it a couple times each week. The goals I wrote down for last year were: visit 3 foreign countries, take 3 months of vacation and spend 1 month in Montana. I only made it to 1 foreign country (Mexico), but I did take 2 months of vacation and got my month in Montana. I'll take that.&lt;/p&gt;
&lt;p&gt;In 2010, I hope to speak at (or attend) 3 conferences, finish up The Bus and do a whole bunch of skiing and mountain biking. More than anything, I plan to continue having a lot of fun with my family and implementing a lot of cool technologies along the way. &lt;/p&gt;
&lt;p&gt;It's gonna be a great year.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=71562550&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=71562550&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=71562550 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/grails_oauth_and_linkedin_apis</guid><title>Grails OAuth and LinkedIn APIs</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/grails_oauth_and_linkedin_apis</link><pubDate>Tue, 22 Dec 2009 15:37:57 -0700</pubDate><category>Java</category><category>github</category><category>grails</category><category>linkedin</category><category>profile</category><category>oauth</category><description>Back in November, I wrote about &lt;a href="http://raibledesigns.com/rd/entry/gwt_oauth_and_linkedin_apis"&gt;how to talk to LinkedIn APIs with GWT&lt;/a&gt;. A week later, I &lt;a href="http://twitter.com/mraible/status/6195066631"&gt;figured out how to do it with Grails&lt;/a&gt; and contributed a &lt;a href="http://code.google.com/p/grails-oauth/issues/detail?id=1"&gt;patch&lt;/a&gt; to the grails-oauth plugin. 
&lt;/p&gt;
&lt;p&gt;Since then, a few folks have asked how I did it. Since code speaks louder than words, I took some time and 1) verified the oauth plugin works as expected and 2) created an example application demonstrating functionality. You can find the results in &lt;a href="http://github.com/mraible/grails-oauth"&gt;my fork of grails-oauth on GitHub&lt;/a&gt;. You can also &lt;a href="http://demo.raibledesigns.com/grails-oauth"&gt;view the example online&lt;/a&gt;.
&lt;/p&gt;
&lt;p style="border-bottom: 1px dotted silver; padding-bottom: 5px"&gt;Below is a quick tutorial explaining how to integrate LinkedIn into your Grails application.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://www.grails.org/Download"&gt;Download&lt;/a&gt; and install Grails 1.1.2.&lt;/li&gt;
&lt;li&gt;Run &lt;em&gt;grails create-app&lt;/em&gt; to create your application.&lt;/li&gt;
&lt;li&gt;Add the following to the bottom of &lt;em&gt;grails-app/conf/Config.groovy&lt;/em&gt;:
&lt;pre class="brush: java"&gt;
oauth {
    linkedin {
        requestTokenUrl="https://api.linkedin.com/uas/oauth/requestToken"
        accessTokenUrl="https://api.linkedin.com/uas/oauth/accessToken"
        authUrl="https://api.linkedin.com/uas/oauth/authorize"
        consumer.key="XXX"
        consumer.secret="XXX"
    }
}
&lt;/pre&gt;
You can get your consumer.key and consumer.secret at &lt;a href="https://www.linkedin.com/secure/developer"&gt;https://www.linkedin.com/secure/developer&lt;/a&gt;. Make sure to set the &lt;em&gt;OAuth Redirect URL&lt;/em&gt; to http://localhost:8080/{your.app.name}/oauth/callback for testing.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/mraible/grails-oauth/archives/master"&gt;Download&lt;/a&gt; the oauth-plugin, extract it and build it using &lt;em&gt;grails package-plugin&lt;/em&gt;. Install it in your project using &lt;em&gt;grails install-plugin path/to/zip&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Add a link to the GSP you want to invoke LinkedIn Authentication from:
&lt;pre class="brush: html"&gt;
&amp;lt;g:oauthLink consumer='linkedin' returnTo="&amp;#91;controller:'profile'&amp;#93;"&amp;gt;
    Login with LinkedIn
&amp;lt;/g:oauthLink&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Create &lt;em&gt;grails-app/controllers/ProfileController.groovy&lt;/em&gt; to access your LinkedIn Profile.
&lt;pre class="brush: java"&gt;
class ProfileController {
    def apiUrl = "http://api.linkedin.com/v1/people/~"
    def oauthService
    
    def index = {
 
        if (session.oauthToken == null) {
            redirect(uri:"/")
        }
 
        if (params?.apiUrl) apiUrl = params.apiUrl
        
        def response = oauthService.accessResource(
                apiUrl, 'linkedin', &amp;#91;key:session.oauthToken.key, secret:session.oauthToken.secret&amp;#93;, 'GET')
 
        render(view: 'index', model: &amp;#91;profileXML: response, apiUrl: apiUrl&amp;#93;)
    }
 
    def change = {
        if (params?.apiUrl) {
            println("Setting api url to " + params.apiUrl)
            apiUrl = params.apiUrl
        }
        
        redirect(action:index,params:params)
    }
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Create &lt;em&gt;grails-app/views/profile/index.gsp&lt;/em&gt; to display the retrieved profile and allow subsequent API calls.
&lt;pre class="brush: html"&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Your Profile&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;a class="home" href="${createLinkTo(dir:'')}"&amp;gt;Home&amp;lt;/a&amp;gt;
&amp;lt;g:hasOauthError&amp;gt;
    &amp;lt;div class="errors"&amp;gt;
        &amp;lt;g:renderOauthError/&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/g:hasOauthError&amp;gt;

&amp;lt;g:form url="&amp;#91;action:'change',controller:'profile'&amp;#93;" method="get"&amp;gt;
    Your LinkedIn Profile:
    &amp;lt;textarea id="payload" style="width: 100%; height: 50%; color: red"&amp;gt;${profileXML}&amp;lt;/textarea&amp;gt;
    &amp;lt;p&amp;gt;
        &amp;lt;g:textField name="apiUrl" value="${apiUrl}" size="100%"/&amp;gt;
        &amp;lt;br/&amp;gt;
        &amp;lt;g:submitButton name="send" value="Send Request"/&amp;gt;
    &amp;lt;/p&amp;gt;
&amp;lt;/g:form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Start your app using &lt;em&gt;grails run-app&lt;/em&gt; and enjoy.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style="border-top: 1px dotted silver; padding-top: 5px"&gt;As mentioned earlier, you can &lt;a href="http://github.com/mraible/grails-oauth/archives/master"&gt;download the grails-oauth-example&lt;/a&gt; or &lt;a href="http://demo.raibledesigns.com/grails-oauth"&gt;view it online&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;One improvement I'd like to see is to simplify the parsing of XML into a Profile object, much like the &lt;a href="http://pivotallabs.com/users/will/blog/articles/1096-linkedin-gem-for-a-web-app"&gt;linkedin gem&lt;/a&gt; does for Rails. 
&lt;/p&gt;
&lt;p&gt;
If you're interested in learning more about LinkedIn and OAuth, I encourage you to checkout &lt;a href="http://www.linkedin.com/in/taylorsingletary"&gt;Taylor Singletary's&lt;/a&gt; presentation &lt;a href="http://www.slideshare.net/episod/linkedin-oauth-zero-to-hero"&gt;LinkedIn OAuth: Zero to Hero&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I &lt;a href="http://github.com/mraible/grails-oauth/commit/6db20f3b8341383b869f49d6ca126ebd99ccb364"&gt;updated&lt;/a&gt; the oauth-plugin so it's backwards-compatible with OAuth 1.0 and added Twitter to the example application to prove it. If you're seeing "Cannot invoke method remove() on null object", it's likely caused by your redirect URL pointing to an application on a different domain.&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=70909760&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=70909760&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=70909760 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/comparing_kick_ass_web_frameworks</guid><title>Comparing Kick-Ass Web Frameworks at The Rich Web Experience</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/comparing_kick_ass_web_frameworks</link><pubDate>Fri, 4 Dec 2009 08:16:48 -0700</pubDate><category>Java</category><category>gwt</category><category>grails</category><category>jobs</category><category>rails</category><category>richwebexperience</category><category>trends</category><category>richweb</category><category>flex</category><category>struts</category><description>Yesterday, I delivered my &lt;a href="http://www.therichwebexperience.com/conference/orlando/2009/12/session?id=15951"&gt;Comparing Kick-Ass Web Frameworks&lt;/a&gt; talk at the Rich Web Experience in Orlando, Florida. Below are the slides I used:&lt;/p&gt;
&lt;div style="text-align:center; margin-bottom: 10px" id="__ss_2644393"&gt;
&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=comparingkickasswebframeworks-091203145644-phpapp02&amp;stripped_title=comparing-kick-ass-web-frameworks" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=comparingkickasswebframeworks-091203145644-phpapp02&amp;stripped_title=comparing-kick-ass-web-frameworks" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;Although it's difficult to convey a presentation in a slide deck, I can offer you my conclusion: &lt;a href="http://java.dzone.com/news/there-no-best-web-framework"&gt;there is no "best" web framework&lt;/a&gt;. I believe web frameworks are like &lt;a href="http://www.ted.com/talks/malcolm_gladwell_on_spaghetti_sauce.html"&gt;spaghetti sauce&lt;/a&gt; in that everyone has different tastes and having so many choices is necessary to satisfy everyone. You can read more about the &lt;em&gt;plural nature of perfection&lt;/em&gt; in Malcolm Gladwell's &lt;a href="http://www.gladwell.com/2004/2004_09_06_a_ketchup.html"&gt;The Ketchup Conundrum&lt;/a&gt; (a written version of &lt;a href="http://www.ted.com/talks/malcolm_gladwell_on_spaghetti_sauce.html"&gt;What we can learn from spaghetti sauce&lt;/a&gt;). Even though there is no "best" web framework, I believe GWT, Flex, Rails and Grails are frameworks that every web developer should try. They really do make it fun to develop web applications.
&lt;/p&gt;
&lt;p&gt;You can find the slides for my other RWE talk at &lt;a href="http://raibledesigns.com/rd/entry/building_sofea_applications_with_gwt"&gt;Building SOFEA Applications with GWT and Grails&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Kudos to &lt;a href="http://www.nofluffjuststuff.com"&gt;Jay Zimmerman&lt;/a&gt; for putting on a great show in Orlando this year. I had a great time talking with folks and learning in the sessions I attended. I particularly enjoyed bringing my parents and kids and staying at such a nice resort. Disney World (Magic Kingdom) and Universal Studios was very enjoyable due to the short lines. Also, the weather was perfect - especially considering the freezing cold in Denver this week. &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=70237078&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=70237078&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=70237078 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/introduction_to_objective_j_and</guid><title>Introduction to Objective-J and Cappuccino with Tom Robinson</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/introduction_to_objective_j_and</link><pubDate>Thu, 3 Dec 2009 11:21:59 -0700</pubDate><category>The Web</category><category>tlrobinson</category><category>dom</category><category>richweb</category><category>cappuccino</category><category>280north</category><category>objectivej</category><category>richwebexperience</category><category>javascript</category><description>This morning, I attended &lt;a href="http://tlrobinson.net/"&gt;Tom Robinson's&lt;/a&gt; talk on &lt;a href="http://www.therichwebexperience.com/conference/orlando/2009/12/session?id=15958"&gt;Objective-J and Cappuccino&lt;/a&gt;. Tom is one of the founders of &lt;a href="http://280north.com/"&gt;280 North&lt;/a&gt; and creators of the &lt;a href="http://cappuccino.org/"&gt;Cappuccino framework&lt;/a&gt; and Objective-J language, so I was very interested in hearing about Cappuccino from &lt;em&gt;the source&lt;/em&gt;. The text below are my notes, but they're also mostly Tom's words, not mine. I've added a "Thoughts" section at the end that are my words.&lt;/p&gt;
&lt;p&gt;Tom's Team was Cocoa programmers before they started building Cappuccino. They wanted to focus on building Desktop Class Web Applications (for example, Google Maps, Meebo and 280 Slides). Tom showed a  demo of 280 Slides and how it can rotate and scale images very easily, something you don't often see in web applications. 
&lt;/p&gt;
&lt;p&gt;
To build desktop class web applications, you can use Flash or Silverlight, but they're controlled by Adobe and Microsoft. Also, they have no iPhone support and poor Mac and Linux performance. The other option is JavaScript + DOM. They're open standards, available almost everywhere (including mobile devices) and its a very rich ecosystem with lots of competition. The downside to JavaScript is standards bodies, many incompatibilities, technical limitations (e.g. can't access web cam) and the DOM is very document-centric.
&lt;/p&gt;
&lt;p&gt;The bottom line is we can't fix Flash, but we can fix JavaScript. 
&lt;/p&gt;
&lt;p&gt;
This is what 280 North is trying to do with Objective-J. It's a proper superset of JavaScript, has a few syntax additions, has a powerful runtime and is implemented &lt;em&gt;in&lt;/em&gt; JavaScript. Objective-J is analogous to Objective-C. It adds to JavaScript like Objective-C adds to C. &lt;/p&gt;
&lt;p&gt;One of the first things Objective-J adds is Dependency Management. You can import from search paths:&lt;/p&gt;
&lt;pre class="brush: java"&gt;
@import &amp;lt;Foundation/CPObject.j&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Or from relative paths:&lt;/p&gt;
&lt;pre class="brush: java"&gt;
@import "ApplicationController.j"
&lt;/pre&gt;
&lt;p&gt;@import prevents duplicate loads has asynchronous downloading and synchronous execution. That means all files are downloaded before evaluation begins, but to the programmer, it seems to happen synchronously.&lt;/p&gt;
&lt;p&gt;The thing that sets Cappuccino apart from other libraries is its inheritance model. It uses  classical OO inheritance (using Objective-C syntax).
&lt;/p&gt;
&lt;pre class="brush: java"&gt;
@implementation Person : CPObject {
    String firstName @accessors;
    String lastName @accessors;
}

- (String) fullName {
    return firstName + lastName;
}

@end
&lt;/pre&gt;
&lt;p&gt;The type definitions (String) are ignored for now and primarily used for documentation. In the future, they plan to add optional static typing, hence the reason for having them. Tom is unsure if you can leave off the String type or if the compiler requires it.&lt;/p&gt;
&lt;p&gt;@implementation has proper support for &lt;code&gt;super&lt;/code&gt; and language syntax support. One of the reasons they chose Objective-C is because classical inheritance works great for UI Frameworks. &lt;/p&gt;
&lt;p&gt;Objective-J uses "send a message" syntax instead of "call a method" syntax. In the code snippets below, the first line is JavaScript, the second is Objective-J:&lt;/p&gt;
&lt;pre class="brush: java"&gt;
object.method()
[object method]

object.methodWithFoot(arg1)
[object methodWithFoo:arg1]

object.methodWithFooBar(arg1, arg2)
[object methodWithFoo:arg1 bar:arg2]
&lt;/pre&gt;
&lt;p&gt;Dynamic Dispatch is one of the most interesting parts of Objective-J. &lt;em&gt;forwardInvocation&lt;/em&gt; in Objective-C is like &lt;em&gt;method_missing&lt;/em&gt; in Ruby. Methods can be used as references, for example:
&lt;/p&gt;
&lt;pre&gt;
var action = @selector(someMethod:);
&lt;/pre&gt;
&lt;p&gt;Runtime mutability is important for KeyValueCoding (KVC) and KeyValueObserving (KVO). KVC allows you to swap classes at runtime and KVO allows you to listen for when property values change. At runtime, a $KVO_ClassName is generated. This class notifies any registered observers when values are changed and then calls the original class to change the property.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cappuccino&lt;/strong&gt;&lt;br/&gt;
Cappuccino is an application framework, not a library. It uses the &lt;em&gt;Hollywood Principle&lt;/em&gt;: "Don't call us, we'll call you". 
&lt;/p&gt;
&lt;p&gt;
The Framework handles document management (open, save, revert), content editing (undo, redo, copy, paste) and graphics manipulation. The DOM is designed for documents (same is true for HTML and CSS). Tom doesn't like the DOM as its not a good API for building applications. Proof is all the JavaScript libraries built to make the DOM better. &lt;/p&gt;
&lt;p&gt;Cappuccino has an MVC framework and CPView is its View. It's analogous to a &amp;lt;div&amp;gt; and represents a rectangle on the screen. Everything visible is a CPView or one of its subclasses. It defines resizing and layout behavior. CoreGraphics is Cappuccino's canvas-like drawing API. It uses VML on IE, canvas on everything else. &lt;/p&gt;
&lt;p&gt;Very little of the code in Cappuccino talks to the DOM (less than 2%). It's not just about providing widgets that work in all browsers, it's a way to write platform independent display code. &lt;/p&gt;
&lt;p&gt;Events are done very differently than most JavaScript libraries. Browser's dispatching is not used. A single event listener is registered for each type of event on the window. These events are captured and sent to the objects that need to know about them. This allows for consistent events across all browsers, even keyboard events. It also allows for creating custom event flows and easily creating custom events. Cappuccino events allow you to get around a common problem with DOM Events where you can't click on overlapping rectangles.&lt;/p&gt;
&lt;p&gt;Notifications can be registered and sent very easily. Both "scoped" and private notifications can be created.&lt;/p&gt;
&lt;p&gt;Undo Management is included in Cappuccino. It manages a stack of undos for you. Redos are "free" and undo functionality is part of the document architecture. This makes it easy to integrate with auto-save functionality.&lt;/p&gt;
&lt;p&gt;Run loops (also called event loops) are an advanced feature of Cappuccino. They allow you to perform actions on every run loop. This enables complex optimizations for DOM/Graphic operations and undo grouping. &lt;/p&gt;
&lt;p&gt;The final part of Cappuccino is Keyed Archiving. Keyed Archiving stores a graph of Objective-J objects. It handles reference cycles, conditional inclusions, has an efficient data format and works on the client and server (Objective-J can be run on the server). The data format is similar like binary, but it's UTF-8. Keyed Archiving is used for archiving views and used heavily in &lt;a href="http://280slides.com/"&gt;280 Slides&lt;/a&gt; for storing, retrieving, and exporting presentations. 
&lt;/p&gt;
&lt;p&gt;Other applications implemented with Cappuccino include &lt;a href="http://almost.at"&gt;almost.at&lt;/a&gt; 
and &lt;a href="http://gomockingbird.com"&gt;Mockingbird&lt;/a&gt;. &lt;a href="http://enstore.com"&gt;EnStore&lt;/a&gt; uses it too, but only for its admin interface.&lt;/p&gt;
&lt;p&gt;An interesting extension for Rails developers is &lt;a href="http://github.com/nciagra/Cappuccino-Extensions/tree/master/CPActiveRecord/"&gt;CPActiveRecord&lt;/a&gt;, a reimplementation of Rails' ActiveRecord in Cappuccino.
&lt;/p&gt;
&lt;p&gt;There are several tools included with Cappuccino:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;objj: command line Objective-J&lt;/li&gt;
&lt;li&gt;objcc: "compile" ahead of time&lt;/li&gt;
&lt;li&gt;press: optimize code and resources&lt;/li&gt;
&lt;li&gt;nib2cib: convert Mac OS X nibs&lt;/li&gt;
&lt;li&gt;capp: project creation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these tools are built on &lt;a href="http://github.com/tlrobinson/narwhal"&gt;Narwhal&lt;/a&gt; (which conforms to the CommonJS standard).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CommonJS&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://wiki.commonjs.org/wiki/CommonJS"&gt;CommonJS&lt;/a&gt; is an effort among server-side JavaScript projects to standardize non-browser JavaScript APIs. There's numerous API specifications (so far):
&lt;ul&gt;
&lt;li&gt;Binary, File, IO&lt;/li&gt;
&lt;li&gt;stdin, stdout, stderr, args, env&lt;/li&gt;
&lt;li&gt;Web server gateway (&lt;a href="http://jackjs.org/jsgi-spec.html"&gt;JSGI&lt;/a&gt;) - similar to &lt;a href="http://wsgi.org/wsgi/"&gt;WSGI&lt;/a&gt; and &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; for Python and Ruby&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To learn more about CommonJS, see &lt;a href="http://arstechnica.com/web/news/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination.ars"&gt;CommonJS effort sets JavaScript on path for world domination&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Narwhal is 280 North's implementation of CommonJS APIs. It works with multiple JavaScript engines, including Rhino, JavaScriptCore (SquirrelFish) and XUL Runner. According to Tom, Rhino is an order of magnitude slower than JavaScriptCore and V8. Of course, Narwhal supports Objective-J too.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Aristo&lt;/strong&gt;&lt;br/&gt;
Aristo is the new default theme in Cappuccino and was created by the &lt;a href="http://www.madebysofa.com/"&gt;Sofa&lt;/a&gt; design firm. It includes windows, tabs and menus and is &lt;a href="http://wiki.github.com/280north/aristo"&gt;open source&lt;/a&gt; so you can modify. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Atlas&lt;/strong&gt;&lt;br/&gt;
Atlas is an IDE for Cappuccino, focused on building user interfaces graphically. Atlas is a downloadable application for OS X. It's written almost entirely in Cappuccino. The desktop version bridges Cappuccino windows to native windows. Tom did a demo of Atlas and showed how its layout feature allows you pin, center and align very easily. It's all done with JavaScript because doing layouts with CSS is often very painful. After that, he showed us how can you Atlas to very easily build a Web Application and then export it as a native OS X application without changing a line of code. Atlas includes Mozilla's &lt;a href="https://bespin.mozilla.com/"&gt;Bespin&lt;/a&gt; for code editing. &lt;/p&gt;
&lt;p&gt;
&lt;p&gt;To learn more about Aristo and Atlas, you might want to checkout Ajaxian's &lt;a href="http://ajaxian.com/archives/big-news-from-cappuccino-aristo-and-atlas"&gt;Big News from Cappuccino: Aristo and Atlas&lt;/a&gt; from earlier this year.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://280atlas.com"&gt;Atlas&lt;/a&gt; has a $20 &lt;a href="https://atlas-beta.heroku.com/users/new"&gt;Beta Program&lt;/a&gt; if you're interested in trying it out.&lt;/p&gt;
&lt;p style="border-top: 1px dotted silver; padding-top: 10px"&gt;
&lt;strong&gt;My Thoughts&lt;/strong&gt;&lt;br/&gt;
Cappuccino looks like a very cool web framework. It reminds me of GWT in that you have to learn a new language to use it. However, Atlas takes a lot of that pain away. I particularly like how it has document and undo/redo support built-in. On my current GWT project, this would be very useful as we've had to build this functionality by hand. &lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=70192161&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=70192161&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=70192161 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/gwt_oauth_and_linkedin_apis</guid><title>GWT OAuth and LinkedIn APIs</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/gwt_oauth_and_linkedin_apis</link><pubDate>Tue, 24 Nov 2009 15:46:05 -0700</pubDate><category>The Web</category><category>twitter</category><category>api</category><category>linkedin</category><category>gwt</category><category>google</category><category>oauth</category><category>profile</category><description>&lt;a href="http://www.linkedin.com"&gt;&lt;img src="http://static.raibledesigns.com/repository/images/linkedin-logo.gif" width="129" height="36" alt="LinkedIn Logo" class="picture" style="border: 0" /&gt;&lt;/a&gt;
When I worked at LinkedIn last year, I received a lot of inquiries from friends and developers about LinkedIn's APIs. After a while, I started sending the following canned response:&lt;/p&gt;
&lt;p class="quote" style="color: #666"&gt;
For API access to build LinkedIn features into your application, fill
out the following form:
&lt;br/&gt;&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a style="color: #666" href="http://www.linkedin.com/static?key=developers_apis"&gt;http://www.linkedin.com/static?key=developers_apis&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;
For requests to build an application, go to:
&lt;br/&gt;&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a style="color: #666" href="http://www.linkedin.com/static?key=developers_opensocial"&gt;http://www.linkedin.com/static?key=developers_opensocial&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;
I talked with the API team and they did say they look at every request that's sent via these forms. They don't respond to all of them b/c they know that many people would be angry if they told them "no", so they'd rather not have that headache.
&lt;/p&gt;
&lt;p&gt;Yesterday, I was pumped to see that they've finally decided to &lt;a href="http://blog.linkedin.com/2009/11/23/linkedin-platform-launch/"&gt;open up their API to Developers&lt;/a&gt;.
&lt;/p&gt;
&lt;p class="quote" style="color: #666"&gt;
Starting today, developers worldwide can integrate LinkedIn into their business applications and Web sites.  &lt;a href="http://developer.linkedin.com/"&gt;Developer.linkedin.com&lt;/a&gt; is now &lt;strong&gt;live &lt;/strong&gt;and open for business.
&lt;/p&gt;
&lt;p&gt;First of all, congratulations to the API team on finally making this happen! I know it's no small feat. Secondly, it's great to see them using &lt;a href="http://www.jivesoftware.com/products"&gt;Jive SBS&lt;/a&gt; for their API documentation and developer community. My current client uses this to facilitate development and I love how it integrates a wiki, JIRA, FishEye, Crucible and Bamboo into one central jumping off point.&lt;/p&gt;
&lt;p&gt;I've always been a fan of LinkedIn, ever since I joined way back in &lt;a href="http://raibledesigns.com/rd/entry/happy_cinco_de_linko"&gt;May 2003&lt;/a&gt;. However, I've longed for a way to access my data. &lt;a href="http://developer.linkedin.com/community/widgets"&gt;LinkedIn Widgets&lt;/a&gt; are nice, but there's something to be said for the full power of an API. Last night, I sat down for a couple hours and enhanced my &lt;a href="http://raibledesigns.com/rd/entry/implementing_oauth_with_gwt"&gt;Implementing OAuth with GWT&lt;/a&gt; example to support LinkedIn's API.&lt;/p&gt;
&lt;p&gt;I'm happy to report my experiment was a success and you can &lt;a href="http://static.raibledesigns.com/downloads/gwt-oauth-1.2.zip"&gt;download GWT OAuth 1.2&lt;/a&gt; or &lt;a href="http://demo.raibledesigns.com/gwt-oauth"&gt;view it online&lt;/a&gt;. For now, I'm simply &lt;a href="http://developer.linkedin.com/docs/DOC-1008"&gt;authenticating with OAuth&lt;/a&gt; and accessing the &lt;a href="http://developer.linkedin.com/docs/DOC-1002"&gt;Profile API&lt;/a&gt;. 
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://demo.raibledesigns.com/gwt-oauth" title="OAuth with GWT Demo"&gt;&lt;img src="http://farm3.static.flickr.com/2655/4132814004_b423779e59.jpg" width="453" height="326" alt="OAuth with GWT" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;In the process, I learned a couple things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LinkedIn's OAuth implementation returns an &lt;a href="http://wiki.oauth.net/Signed-Callback-URLs"&gt;oauth_verifier&lt;/a&gt; parameter after authenticating, whereas Google and Twitter do not. This parameter needs to be included when calling the &lt;em&gt;Access token path&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The Profile API example I implemented gets the current user's profile with &lt;a href="http://api.linkedin.com/v1/people/~"&gt;http://api.linkedin.com/v1/people/~&lt;/a&gt;. This returns a "light" version of your profile. To get a more detailed version, you need to use &lt;a href="http://developer.linkedin.com/docs/DOC-1014"&gt;Field Selectors&lt;/a&gt;. For example:
&lt;span style="display: block; margin: 5px 5px"&gt;
&lt;a href="http://api.linkedin.com/v1/people/~:(id,first-name,last-name,picture-url,headline,summary,positions,educations)"&gt;http://api.linkedin.com/v1/people/~:(id,first-name,last-name,picture-url,headline,summary,positions,educations)&lt;/a&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn's API only supports passing OAuth parameters in a header, rather than query parameters. To make this work, I modified my &lt;a href="http://raibledesigns.com/rd/entry/how_to_do_cross_domain#proxyServlet"&gt;ProxyServlet&lt;/a&gt; to convert query parameters to an "Authorization" header at the end of the &lt;em&gt;setProxyRequestHeaders()&lt;/em&gt; method.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="brush: java"&gt;
// For LinkedIn's OAuth API, convert request parameters to an AuthorizationHeader
if (httpServletRequest.getRequestURL().toString().contains("linkedin-api")) {
    String&amp;#91;&amp;#93; parameters = httpServletRequest.getQueryString().split("&amp;amp;");
    StringBuilder sb = new StringBuilder("OAuth realm=\"http://api.linkedin.com/\",");
    for (int i = 0; i &amp;lt; parameters.length; i++) {
        sb.append(parameters&amp;#91;i&amp;#93;);
        if (i &amp;lt; parameters.length - 1) {
            sb.append(",");
        }
    }

    Header authorization = new Header("Authorization", sb.toString());
    httpMethodProxyRequest.setRequestHeader(authorization);
}
&lt;/pre&gt;
&lt;p&gt;You might recall that my previous example had issues authenticating with Google, but worked well with Twitter. LinkedIn's authentication seems to work flawlessly. This leads me to believe that Twitter and LinkedIn have a much more mature OAuth implementation than Google.&lt;/p&gt;
&lt;p style="padding-top: 5px; border-top: 1px dotted silver; color: #666"&gt;&lt;em&gt;&lt;strong&gt;Related OAuth News&lt;/strong&gt;: Apache Roller 5 will be shipping with OAuth support. See &lt;a href="http://rollerweblogger.org/roller"&gt;Dave Johnson's&lt;/a&gt; &lt;a href="http://www.slideshare.net/snoopdave/whats-new-in-roller5"&gt;What's New in Roller 5 presentation&lt;/a&gt; for more information.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=69832801&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=69832801&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=69832801 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/adding_expires_headers_with_oscache</guid><title>Adding Expires Headers with OSCache's CacheFilter</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/adding_expires_headers_with_oscache</link><pubDate>Mon, 23 Nov 2009 11:17:05 -0700</pubDate><category>Roller</category><category>oscache</category><category>expiresheaders</category><category>roller</category><category>appfuse</category><category>ehcache</category><category>highperformance</category><description>A couple of weeks ago, I wrote about how I improved this site's YSlow grade by &lt;a href="http://raibledesigns.com/rd/entry/javascript_and_css_concatenation"&gt;concatenating JavaScript and CSS with wro4j&lt;/a&gt;. Even though I loved the improvements, there was still work to do:&lt;/p&gt;
&lt;p class="quote" style="color: #666"&gt;
I'm now sitting at a YSlow (V2) score of 75; 90 if I use the "Small Site or Blog" ruleset. I believe I can improve this by adding expires headers to my images, js and css.
&lt;/p&gt;
&lt;p&gt;Last Monday, &lt;a href="http://groups.google.com/group/wro4j/browse_thread/thread/364dc86a194d712a"&gt;wro4j 1.1.0 was released&lt;/a&gt; and I thought it would solve my last remaining issue. Unfortunately, it only adds expires headers (and ETags) to images referenced in included CSS. Of course, this makes sense, but I thought they'd add a filter to explicitly add expires headers.&lt;/p&gt;
&lt;p&gt;Since I still wanted this feature, I did some searching around and found what I was looking for: &lt;a href="http://www.opensymphony.com/oscache/wiki/CacheFilter.html"&gt;OSCache's CacheFilter&lt;/a&gt;. It was surprisingly easy to setup, I &lt;a href="https://oscache.dev.java.net/files/documents/629/61424/oscache-2.4.1.jar"&gt;downloaded OSCache 2.4.1&lt;/a&gt;, added it to my WEB-INF/lib directory, and added the following to my web.xml.
&lt;/p&gt;
&lt;pre class="brush: xml"&gt;
&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;CacheFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;com.opensymphony.oscache.web.filter.CacheFilter&amp;lt;/filter-class&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;expires&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;time&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;time&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;2592000&amp;lt;/param-value&amp;gt; &amp;lt;!-- one month --&amp;gt;
    &amp;lt;/init-param&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;scope&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;session&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
&amp;lt;/filter&amp;gt;

&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;CacheFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;*.gif&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;CacheFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;*.jpg&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;CacheFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;*.png&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After restarting Tomcat and clearing out my Firefox cache, I was in business. 
&lt;/p&gt;
&lt;p&gt;
I did experience one issue along the way when I tried to remove the oscache.jar from my WEB-INF/lib directory. I'm using the &lt;a href="http://wiki.java.net/bin/view/Javanet/JSPWikiPlugin"&gt;JSPWiki Plugin&lt;/a&gt; and it seems to rely on a class in oscache.jar. I'm not sure which version oscache.jar is, but the packages got moved around somewhere along the way. The good news is it seems OK to have both oscache.jar and oscache-2.4.1.jar in Roller's classpath.
&lt;/p&gt;
&lt;p&gt;After discovering the duplicate JARs issue, I got to thinkin' that EhCache would probably have a solution. Sure enough, it has a &lt;a href="http://ehcache.org/documentation/web_caching.html"&gt;SimpleCachingHeadersPageCachingFilter&lt;/a&gt;. Since I already had a working solution, I didn't bother trying EhCache (especially since my Roller install uses EhCache 1.1 and the filter is only available in a later version). However, when I implement expires headers in &lt;a href="http://appfuse.org"&gt;AppFuse&lt;/a&gt;, I'll definitely try EhCache's solution.&lt;/p&gt;
&lt;p&gt;As for my YSlow score, it didn't improve as much as I'd hoped (low 80s instead of mid 80s). Some of this is due to my &lt;a href="http://raibledesigns.com/rd/entry/building_sofea_applications_with_gwt"&gt;embedded presentation from Slideshare&lt;/a&gt;. There's also some external images I'm using in my &lt;a href="http://raibledesigns.com/rd/entry/lightbox_js"&gt;Lightbox JS&lt;/a&gt; implementation. So if I can find a better Lightbox implementation (supports rel="lightbox" syntax), there's a good chance I'll switch. In the meantime, I'm lovin' how much faster this site loads.
&lt;/p&gt;
&lt;p&gt;In case you're wondering, I do plan on adding css/js concatenation and expires headers to both AppFuse 2.1 and &lt;a href="http://roller.apache.org"&gt;Roller&lt;/a&gt; 5.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; FWIW, I did try to configure expires headers in Apache, but the AJP 1.3 Connector doesn't seem to allow this to work. To quote Keith from &lt;a href="http://kgbinternet.com/"&gt;KGB Internet&lt;/a&gt;:&lt;/p&gt;
&lt;p class="quote" style="color: #666"&gt;
I added an expires directive and it didn't touch the header for anything served from Tomcat, but does for content served directly by Apache.  This might have to be set up in Tomcat.
&lt;/p&gt;&lt;p&gt;&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=69832800&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=69832800&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=69832800 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1</guid><title>AppFuse 2.1 Milestone 1 Released</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1</link><pubDate>Thu, 19 Nov 2009 07:16:36 -0700</pubDate><category>Java</category><category>springmvc</category><category>java</category><category>tapestry</category><category>maven</category><category>struts2</category><category>ibatis</category><category>webframeworks</category><category>appfuse</category><category>stripes</category><category>archetypes</category><category>jsf</category><category>spring</category><category>java5</category><category>myfaces</category><category>hibernate</category><category>maven2</category><category>jpa</category><category>freemarker</category><category>wicket</category><category>appfuse-light</category><description>&lt;a href="http://appfuse.org"&gt;&lt;img src="https://appfuse.dev.java.net/images/icon.gif" class="picture" style="border: 0"&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the first milestone release of AppFuse 2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are &lt;a href="http://raibledesigns.com/rd/entry/upgrading_hibernate_to_3_4"&gt;Hibernate&lt;/a&gt;, &lt;a href="http://raibledesigns.com/rd/entry/moving_from_spring_s_xml"&gt;Spring&lt;/a&gt; and Tapestry 5. 
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br/&gt;
AppFuse is an open source project and application that uses open source tools built on the Java platform to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time found when building new web applications for customers. At its core, AppFuse is a project skeleton, similar to the one that's created by your IDE when you click through a wizard to create a new web project.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Release Details&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://static.appfuse.org/archetypes.html"&gt;Archetypes&lt;/a&gt; now include all the source for the web modules so using &lt;em&gt;jetty:run&lt;/em&gt; and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose which persistence framework (Hibernate, iBATIS or JPA) you'd like to use. If you want to modify the source for that, &lt;a href="http://appfuse.org/display/APF/AppFuse+Core+Classes"&gt;add the core classes to your project&lt;/a&gt; or run &lt;em&gt;appfuse:full-source&lt;/em&gt;. 
&lt;/p&gt;
&lt;p&gt;
In addition, AppFuse Light has been &lt;a href="http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven"&gt;converted to Maven&lt;/a&gt; and has archetypes available. AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The &lt;em&gt;light&lt;/em&gt; archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket.
&lt;/p&gt;
&lt;p&gt;Other notable improvements:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Added &lt;a href="http://issues.appfuse.org/browse/APF-267"&gt;Compass support&lt;/a&gt; thanks to a patch from &lt;a href="http://www.kimchy.org/"&gt;Shay Banon&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Upgraded from &lt;a href="http://issues.appfuse.org/browse/APF-1125"&gt;XFire to CXF&lt;/a&gt; for Web Services.&lt;/li&gt;
&lt;li&gt;Moved Maven repository to &lt;a href="https://docs.sonatype.com/display/NX/OSS+Repository+Hosting"&gt;Sonatype's OSS Repository Hosting&lt;/a&gt; for snapshots and releasing to Maven Central. There are no longer any AppFuse-specific artifacts, all are available in central. Thanks to &lt;a href="http://sonatype.com"&gt;Sonatype&lt;/a&gt; for this great service and its &lt;a href="http://raibledesigns.com/rd/entry/nexus_is_a_kick_ass"&gt;excellent repository manager&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Upgraded to Canoo WebTest 3.0. &lt;em&gt;Now if we could just get its &lt;a href="http://people.apache.org/~sgoeschl/download/maven-plugins/webtest-maven-plugin/site/index.html"&gt;Maven Plugin&lt;/a&gt; moved to Codehaus.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Added &lt;a href="http://raibledesigns.com/rd/entry/ajaxified_body"&gt;Ajaxified Body&lt;/a&gt; to AppFuse Light archetypes.&lt;/li&gt;
&lt;li&gt;Infrastructure upgrades, including &lt;a href="http://issues.appfuse.org/"&gt;JIRA 4&lt;/a&gt;, &lt;a href="http://appfuse.org/"&gt;Confluence 3&lt;/a&gt;, &lt;a href="http://source.appfuse.org"&gt;FishEye 2&lt;/a&gt;, &lt;a href="http://builds.appfuse.org"&gt;Bamboo 2&lt;/a&gt; and &lt;a href="http://login.appfuse.org"&gt;Crowd 1.6&lt;/a&gt;. Many thanks to &lt;a href="http://www.atlassian.com/c/NPOS/10160"&gt;Atlassian&lt;/a&gt; and &lt;a href="http://contegix.com"&gt;Contegix&lt;/a&gt; for their excellent products and services.&lt;/li&gt;
&lt;li&gt;For more details on specific changes see the &lt;a href="http://appfuse.org/display/APF/Release+Notes+2.1.0+M1" title="Release Notes 2.1.0 M1"&gt;release notes&lt;/a&gt;.
&lt;/ul&gt;
&lt;p&gt;Please note that this release does not contain updates to the documentation. Code generation will work, but it's likely that some content in the &lt;a href="http://appfuse.org/display/APF/Tutorials"&gt;tutorials&lt;/a&gt; won't match. For example, you can use annotations (vs. XML) for dependency injection and Tapestry is a whole new framework. I'll be working on documentation over the next several weeks in preparation for Milestone 2.
&lt;/p&gt;
&lt;p&gt;AppFuse is available as several Maven archetypes. For information on creating a new project, please see the &lt;a href="http://appfuse.org/display/APF/AppFuse+QuickStart" title="AppFuse QuickStart"&gt;QuickStart Guide&lt;/a&gt;.
&lt;/p&gt;
&lt;p class="smokey"&gt;
To learn more about AppFuse, please read Ryan Withers' &lt;a href="http://www.ociweb.com/jnb/jnbMay2008.html"&gt;Igniting your applications with AppFuse&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;The 2.x series of AppFuse has a minimum requirement of the following specification versions:&lt;/p&gt;

&lt;ul class="glassList"&gt;
	&lt;li&gt;Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)&lt;/li&gt;
	&lt;li&gt;Java 5+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href="http://appfuse.org/display/APF/FAQ" title="FAQ"&gt;FAQ&lt;/a&gt; or join the &lt;a href="http://appfuse.org/display/APF/Mailing+Lists" title="Mailing Lists"&gt;user mailing list&lt;/a&gt;. If you find bugs, please &lt;a href="http://issues.appfuse.org/secure/CreateIssue!default.jspa"&gt;create an issue in JIRA&lt;/a&gt;.&lt;/p&gt; 

&lt;p&gt;Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues. &lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=69739741&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=69739741&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=69739741 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><item><guid isPermaLink="true">http://raibledesigns.com/rd/entry/my_hunting_season_adventure_at</guid><title>My Hunting Season Adventure at The Cabin</title><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Raible</dc:creator><link>http://raibledesigns.com/rd/entry/my_hunting_season_adventure_at</link><pubDate>Mon, 16 Nov 2009 21:43:44 -0700</pubDate><category>General</category><category>swanvalley</category><category>buck</category><category>dad</category><category>deer</category><category>montana</category><category>huntingseason</category><category>thecabin</category><category>whitetail</category><description>&lt;a href="http://www.flickr.com/photos/bitterroot/218747013/" title="Swan Valley, Montana"&gt;&lt;img src="http://farm1.static.flickr.com/70/218747013_286eb979f9_m_d.jpg" width="240" height="180" class="picture" /&gt;&lt;/a&gt;
Last year, I decided &lt;a href="http://raibledesigns.com/rd/entry/great_weekend_in_montana"&gt;Hunting Season in Montana would be a yearly tradition for me&lt;/a&gt;. It all started a couple years ago when I was talking to my Dad about his yearly hunting trip. He hunted a lot when we lived in Montana (early 70s - 1990) and continued this tradition when he moved to Oregon. I figured it'd be a good opportunity for some father/son bonding and asked him if I could join him one year. We soon realized we had the perfect Hunting Oasis at &lt;a href="http://raibledesigns.com/rd/entry/the_cabin"&gt;The Cabin&lt;/a&gt; and should make it a yearly tradition.&lt;/p&gt;
&lt;p&gt;My Dad lived in Oregon for 20 years, hunted every fall with his buddy Wayne, and &lt;a href="http://raibledesigns.com/rd/entry/congratulations_on_retiring_dad"&gt;retired earlier this year&lt;/a&gt;. Shortly after retiring, he moved to Montana to start building his "retirement cabin" (with running water and indoor plumbing). My Mom, kids and I &lt;a href="http://raibledesigns.com/rd/entry/my_summer_vacation_in_montana"&gt;joined him in July&lt;/a&gt; and made some good progress on finishing the foundation.
&lt;/p&gt;
&lt;p&gt;This weekend, shortly after &lt;a href="http://twitter.com/mraible/status/5677140702" title="The good news is it looks like I'll finish all my tasks for this iteration. The bad news is it's 4:30 AM and I have to get up in 3 hours..."&gt;working all night&lt;/a&gt;, missing a flight, and &lt;a href="http://twitter.com/mraible/status/5691758248" title="Missed my flight, but landed at the Best Shop at DIA. Feels like it was meant to be."&gt;discovering the New Belgium Hub at DIA&lt;/a&gt;, I arrived in Missoula for this year's hunting season. Because I arrived at midnight, we decided to spend the night at a hotel near the airport. The next morning, we woke up and drove 2 hours to the Swan Valley. We arrived at The Cabin, started the heat stove and began unloading the truck. After being there 15 minutes and starting to settle in, my Dad started to talk about where the deer usually roamed. He pointing down by the garden and mumbled "They usually come out of there..." As he was talking, I looked out our kitchen window and say a huge buck. My heart leapt into my throat.
&lt;/p&gt;
&lt;p&gt;I shouted "&lt;em&gt;GO!&lt;/em&gt;" and my Dad quickly responded with "NO! It's yours!" I said "It's been 20 years, &lt;em&gt;YOU&lt;/em&gt; go!" and off he went to grab his rifle. Seconds later we were out on the porch and he was trying to find the beautiful 4-point Whitetail buck in his scope. The buck quickly disappeared behind the woodshed and outhouse and didn't appear again until he was almost on the front road. 
&lt;/p&gt;
&lt;p&gt;
When the target walked across the road, I whispered loudly "Go, &lt;em&gt;GO&lt;/em&gt; - get him!!" 
&lt;/p&gt;
&lt;p&gt;
Shortly after a shot was fired that dropped him from our view. 
&lt;/p&gt;
&lt;p&gt;
My Dad scrambled off the porch, trying to reload at the same time and jamming his rifle. "Get the other gun!" he yelled (because a deer is rarely done after the first shot) and I ran into the house to grab some bullets and the other rifle. By the time I made it back out to the front yard, another shot was fired. My Dad turned to me and said, "He's gone." 
&lt;/p&gt;
&lt;p&gt;I thought, "WTF?!" I thought for sure he'd got him on the first shot. Turns out, "He's gone" also means "He's dead". The picture below illustrates my Dad's impressive accomplishment.&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://farm3.static.flickr.com/2698/4104447592_512831f518.jpg" title="Dad gets a 4 point buck! First deer in 20 years." rel="lightbox[huntingseason2009]"&gt;&lt;img src="http://farm3.static.flickr.com/2698/4104447592_512831f518_m.jpg" width="240" height="180" alt="Dad gets a 4 point buck! First deer in 20 years." style="border: 1px solid black" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After that, we both walked back to The Cabin to put our rifles away and got ready to haul it back.
&lt;/p&gt;
&lt;p&gt;
As I was returning down the road to the deer, I spotted a good-size mountain lion on top of the hill. I didn't see its face, but saw enough of it to realize I should be carrying a rifle with me. A short sprint back to The Cabin and before I knew it, I was back by the deer, guarding it from any predators.&lt;/p&gt;
&lt;p&gt;For the next couple hours, I learned how to gut a deer and enjoyed my Dad's overdue success. Congratulations Pappy - it seems you belong in Montana after all. &lt;img src="http://raibledesigns.com/images/smileys/wink.gif" class="smiley" alt=";-)" title=";-)" /&gt;&lt;/p&gt;
&lt;p&gt;P.S. Today is my parents' 37th Anniversary. Happy Anniversary Mom and Dad! You make marriage look both fun and easy. I hope you have fun cutting up all that meat!&lt;p&gt;&lt;a href=http://nimbb.com&gt;&lt;span style=&amp;quote;text-decoration:none; font-family: Verdana, Arial;&amp;quote;&gt;&lt;img src="http://service.nimbb.com/Images/logo.png" border=0&gt; Webcam video recording in your browser!&lt;/span&gt;&lt;/a&gt; &lt;p&gt;&lt;a href=http://www.rsscache.com/Section/Advertise/click.aspx?n=69562311&gt;&lt;img src="http://www.rsscache.com/Section/Advertise/ads.aspx?n=69562311&amp;f=133" border=0&gt;&lt;/a&gt;&lt;p&gt;&lt;div style="font-size: 8pt;"&gt;&lt;img align=left src=http://www.rsscache.com/Section/Stats/logo.aspx?n=69562311 border=0&gt; Bandwidth saved by &lt;a href=http://www.rsscache.com&gt;RSScache.com&lt;/a&gt;&lt;/div&gt;</description></item><rsscache:id>133</rsscache:id></channel></rss>