Thursday, November 19, 2009

Pair Exchange Program

I just finished the first ever pair programming exchange program!



It all started when I was at SDTConf back in October. I don't remember the exact conversation, but the question was generally if software development as a craft takes two programmers pairing together to pass on and practice the craft then how will it ever scale?



Someone jokingly suggested that Corey Haines should get a bigger car--Corey travels all over the place pairing with people and promoting the craft of software development. One idea that I think Corey actually proposed was the idea of a pair exchange.



The idea is simple: we can't all get Corey Haines or another big name in the XP, Agile, Craftsman, etc. communities to come and pair with us, but there are lots of smart people in every town. If you two are both passionate about practicing and improving your skills then why not use each other as a resource? Everyone has a vacation day to spare, take a day and go pair. If your boss will let you, bring your pair partner to work.



I know a lot of developers in Philadelphia and I had no trouble thinking of the perfect programmer to pilot my pair exchange program with. Woody Zenfell III is not only one of the smartest and most professional programmers I have ever worked with, but we make a killer pair. It is like our brains are wired almost exactly oppositely, but we get along really well. I like that he is fun to work with and we get a lot of good work done together. Plus, I know his company already and I know that he is on a team of 1 and is probably missing working with other developers.



When I first brought this idea up to my manager I had reason to be optimistic. My manager sees the value of pairing, even though my team doesn't really practice it much, and he is very supportive of learning and professional growth. I was thrilled when he agreed to the whole thing, both me going to Woody's office for a day and for Woody to come and pair with me and chat with my team. Woody's boss was also game and we were set!



We decided to do one day at each office, back to back. Since this was our first pair exchange we didn't really know what to expect other than that we would show up, work on some stuff and see what value we get out of it. For me, I knew Woody's code base pretty well, having actually worked on it with him back in our consultant days. For Woody, my team culture and our domain and the code base were all new, so a chunk of time in the morning went to talking about those things. Other than that we just paired; it was awesome. At Woody's place we had some tasks that needed to get done and so we did them. At my place we talked about design for a long time and wrote a test that I was having a hard time writing. Lots of great side-conversations happened with my teammate neighbors. It was fun and we got a lot done.



What did we get out of it?



For this first exchange it seemed like we were for the most part exchanging little tips, tricks and techniques that make us more efficient and effective. Woody, for example, showed me how he is creating dependency graphs (actual pictures) for all of the stored procedures and reports in his system, automatically, so that he can more confidently make changes to them. He is also getting those database elements into source control and refining a test and deployment process for them, which is something I hadn't thought of before, but is really smart given how important those reports are to his company. He also showed me captures in EasyMock, which were exactly what I was always dreaming of but never had because we were still using EasyMock 2.3. In return I showed him ctrl+r in cygwin/linux for searching your history. Then he showed me pushd and popd--that's just so handy.



In addition to tips and tricks we had a lot of conversations about how we do things, like how we work with our users and what process we follow for organizing our work and testing and deployment.



At the end of the second day we took several laps and talked about the experience. We agreed that it was definitely valuable and something we want to do again. We imagined that after a while we will run out of tips and tricks to show each other and then we didn't know what would happen then, but maybe that we could use each other as reinforcements for when something really sticky comes up and we need a fresh perspective. We talked about doing it again quarterly or monthly or more randomly. We aren't sure how our bosses viewed the experiment, and of course they would have to feel like they are getting a good deal out of this for them to allow it to continue. A lot of factors went in to making this experience go smoothly: the fact that we have both paired a lot before and with each other before, that our bosses are agreeable, there are no super-high security requirements that would prevent guests from coming over and peering at the code, etc. I am curious how well it would go if I was pairing with someone I didn't know very well.



I would love to hear about more people who are trying this sort of exchange. If you don't have teammates who pair (or teammates at all) you don't have to miss out on the benefits or pair programming--the discipline and the sharing of new ideas.

Thursday, May 21, 2009

Url patterns for servlet mapping

I came across a baffling problem with my servlet mapping recently for my java web application. In this project we generally use extension-based url patterns for servlet mapping. For example:



<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

This means that every request that comes in that ends in ".html" will get passed into my servlet instead of being handled by Tomcat (who would serve it up like a static file). The problem came up when we could not use extension mapping because we had a few .html files that needed to be served up by Tomcat and the rest were dynamically generated by my servlet. But when I tried to use a path-based url pattern it didn't seem to work as I would expect.



Here is the situation: I know that all .html urls that have the word "library" in the path to need to be sent to my servlet and all other .html requests to be handled by Tomcat, so I tried the following:



<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/library/*</url-pattern>
</servlet-mapping>

My servlet is expecting requests to come in like "/library/index.html", and it worked with the extension url mapping, but with the path url mapping it didn't. It was like nothing was getting passed into my servlet. I did some searching and I didn't find anything in the Java Servlet Specification or on any blogs or forums that explained why path matching would be so different from extension mapping, until I came across this post where PhilipT in the comments explained how tomcat was stripping out the matched part: "So it seems that the Tomcat default servlet (6.0.16 at least) drops the servlet mapping and will try to find the file by using the remaining path." This made me wonder if that always happens with path matching.


I also learned from that post that you can map urls back to tomcat from your servlets web.xml file. In our case we haven't tweaked tomcats configuration so the default servlet is called "default". I let my servlet handle all .html files and I tell tomcat to handle things that come through with the words "static-content" in the path. Since the order of precedence is exact matches, path matches and then extension matches this works exactly as I want it to.



<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static-content/*</url-pattern>
</servlet-mapping>

The only catch with this solution is that you have to remember to put /static-content/ in front of the path to the static content that you want served up by tomcat. It is possibly confusing because there is no "static-content" directory on the server. To give an example, the html files that need to be served by Tomcat are for the fckeditor that we use in our web application. When you want to include a fckeditor on a page you have to tell the javascript where to find the fckeditor home directory. For our project it is a directory called fckeditor sitting in the war directory for our application. Previously we would just say that the home directory was /fckeditor/ and Tomcat would know to find it in <war directory>/fckeditor. Now that we are using path matching we have to tell the fckeditor javascript that its home directory is /static-content/fckeditor/, even though it is still physically on the server at <war directory>/fckeditor