Wednesday, November 17, 2010

Introduction to Mercurial

Hands up if you've been happily using Subversion for many years when some crazy dude comes in and makes you use Mercurial. Anyone? I'm sure it can't just be me.

Anyway, Mercurial is very different to Subversion. I recently found out that Subversion causes brain damage in developers which makes it very difficult to understand how Mercurial works: you try to do things in Mercurial the way you do in Subversion, it doesn't work and you go "ARGH" and rm -rf your repository and start again (being more careful this time).

Well, rm -rf no longer my friends. Joel Spolsky has written a rather excellent introduction to Mercurial which I would recommend you all read if you need to use Mercurial or you're sick of merging in Subversion. I especially appreciated the first page -- Mercurial for Subversion users -- basically a pep talk telling you not to give up on Mercurial just because it's not Subversion.

My take on Mercurial? As far as I can tell, its view of the world is identical to the one I end up drawing when I try to map out how I think Subversion should be working. Instead of representing your codebase as a series of snapshots in time, it represents the changes you make to it. This makes it very easy to merge different branches together, which is pretty much the most painful thing you have to do in Subversion.

Joel explains it very well. Please go and read his tutorial now, if only so you're not surprised when some crazy guy makes you use it.

Monday, October 11, 2010

Ubuntu 10.10 Netbook Edition: Unity

I wanted to like Unity, the new Ubuntu Netbook interface, I really did. I had seen the screenshots and the promos, and I liked the idea of a dock-like interface for launching my programs. Until I installed it.

It's slow.
I was trying this on a Dell Mini 9. It's not a new netbook, but it's Tier One supported hardware. Ubuntu itself is quick to boot -- I looked away while it was restarting and found it had booted when I looked back. Browsing seems relatively quick. Youtube videos play without stuttering.

Yet, the Unity interface has got to be the slowest way of launching programs on my netbook. When I click them, I'm never sure if I did it successfully because it takes so long to load them.

Weirdly, it's worse for the built-in parts of the interface. Want to launch a program that's not in the dock? Click the Applications button, and wait while it populates the list of all your applications. Want the 'hub' (the menu that launches when you click the Ubuntu logo)? That's not instant to launch either. Overall, it's lacking the speed I would expect from a final release.

It's inflexible
The 'dock' (they don't want you to call it one) is always there. You can't hide it. You can't resize it. It's a permanent fixture of your screen, so you'd better learn to love it.

One of the ideas of the dock placement down the size is that it saves vertical space, which on a netbook is more precious than horizontal (more vertical space means less scrolling). Unfortunately, it also means you have less horizontal space, meaning the space available to my browser is less than the 1024 pixels most websites have come to expect. That means I permanently now have horizontal scrollbars which means: less vertical space. Urgh. How many netbooks have a screen resolution wider than 1024 pixels? Doesn't that mean that everybody will have this problem?

It's buggy
Once you push an application into full screen (perhaps you're sick of scrolling), the dock helpfully animates itself out of the way. When you leave full screen mode though, the icons are now halfway down your dock. Why's this? Dunno. You have to drag them back up to the top if you want to see them all.

When you open an application that's not already on your dock (and you want to put it there), you're meant to be able to right click it and add it. At least, that's what happens with the built in apps, like Solitaire. But if you install Chrome or Skype and want that? Nope, it won't work. You can't drag the icon from the Applications folder, so don't be trying that either.

And when you launch an application, its title is meant to go to the top frame. In my experience, the title just disappears, leaving you with a mysterious File menu up there instead. Lucky I can tell what application is open by looking at the little arrow indicators on the dock, eh?

In Summary
Unity is not ready for the prime time -- at least not on my Dell Mini. The version of Ubuntu that came with it worked fine, albeit anciently. The latest version also ran acceptably, although it chewed the battery like nothing else. The netbook version of 10.10? Well, it's barely usable. It lasted one evening before I wiped it off.

Wednesday, September 22, 2010

On the Oddness of javac

At work recently, we had a strange problem: one of our jars was not being loaded in Tomcat. Some closer investigation revealed the all too familiar error message instructing us to See Servlet Spec 2.3, section 9.7.2. Normally I see this when the servlet api jar makes its way into lib directory by mistake (usually a poorly configured pom.xml file). However, this was in one of our jars -- and we certainly don't check in the servlet api in our codebase. What gives?

It's always Maven's fault, right?


Well, usually it is. First of all, we (rather densely) configured Maven to realise the servlet api was a provided library. About two seconds of thought showed this wasn't the problem -- the servlet classes must have been actually in our jar file.

We knew they weren't checked in, so we whacked Maven into verbose mode (mvn -X for those of you playing at home) and scanned the output, line by line. No clues there. At this point my coworker began pushing for a manual compile using javac, and after about an hour of me saying "no, it can't possibly be javac" but not being able to find the problem, I relented. (The verbose output proved helpful to get the classpath out, even if Maven doesn't print it out in the standard format.)

Et tu, javac?


We did a manual compile, and I was gobsmacked when the servlet files were in the resulting output directory. javac, which I had considered a close personal friend (except when it exhibited this bug), was the culprit. There must have been a reasonable explanation, and I was out to find it.

I headed to the javac documentation page, and it didn't take too long to find this part:
Note: Classes found through the classpath may be subject to automatic recompilation if their sources are also found.


What?! Lemme get this straight: if there are java source files in the classpath, they can be compiled and placed into the output directory? Alas, it is true. This meant that somewhere, we had the servlet source code in our classpath, and that it was newer than the regular servlet api.

GWT: Gee, What Twits


Some spectacularly 1337 searching found that GWT distributes the servlet api and sources inside its jars (note that we were using version 1.7.1. Maybe it's fixed now?)

Including somebody else's library inside yours is a really bad idea. Sure, it's convenient -- junit distributes hamcrest matchers -- but unless you also provide a version that doesn't include them (like junit-dep), your users are in for a world of hurt. If they need a different version of the library from the one you're distributing, well, they'll have to rely on the magic of the classpath to find the one they want before they find yours (and good luck with that if you're using Tomcat, which doesn't define the jar order when it loads jar files).

Lessons


Here are the lessons I learnt that day:
  1. javac has some interesting features that you might not come across on a day to day basis.

  2. GWT is evil.

In the end, we hacked the build file to exclude anything in the javax directory from being jar'ed up. That solved the problem, and I went home to take a long shower.

Footnote


Why didn't we RTFM and use javac -implicit:none? Cos we were using Java 1.5, that's why.