<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Geek London - absolutely capital</title>
    <link>http://geeklondon.com/</link>
    <description>Meddling with forces I do not understand</description>
    <item>
      <title>The Nokia e75</title>
      <link>http://geeklondon.com/blog/view/unfit-and-finnish</link>
      <content:encoded>&lt;div class="main_article"&gt;&#xD;
&lt;p&gt;Nokia have lost their way. Profoundly.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Before Christmas some complete bastard nicked my backpack. Not a bad haul for them: shoes, jeans, shirts, bottle of champagne, box of chocolates, wallet, ipod, phone. Bastard bastard. Oh well, these things happen. I replaced various bits and pieces and the last of them to sort out was the phone. New gadget time. I wanted to stay with Orange and they didn't have the iPhone at that point so that made the choice more difficult. I've had fairly good experiences with Nokia phones and one ghastly one with a Motorola phone so I was inclined to stay with Nokia. I kind of wanted a phone with a keyboard so that limited things a bit more. In the end I plumped for the Nokia e75 expecting it to be adequate. It's not; it's horrible. &lt;em&gt;It's not just not a good pocket computer - it's not even a good phone.&lt;/em&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Previously Nokia phones have had good quality&lt;sup&gt;&lt;a href="#footnote_1"&gt;1&lt;/a&gt;&lt;/sup&gt; hardware and very usable software. The e75 lives up to the first expectation - it looks and feels nice, if a little heavy (but heavy is good - heavy feels expensive). The build quality is good. The keyboard&lt;sup&gt;&lt;a href="#footnote_2"&gt;2&lt;/a&gt;&lt;/sup&gt; is about what you'd expect. The software is a bloody abomination.&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;The damn thing takes ages to boot up from a cold start.&lt;/li&gt;&#xD;
&lt;li&gt;Screen updates/app launches are slow - it takes a couple of seconds to get into Contacts for instance. Looking up phone numbers is a fairly fundamental usage pattern.&lt;/li&gt;&#xD;
&lt;li&gt;Slow responsiveness means that getting to the point where you can actually dial a number is non-intuitive; you're waiting for the OS to get around to it even while you try to dial a number in manually.&lt;/li&gt;&#xD;
&lt;li&gt;The provided web browser is a bodged usability nightmare - unusable. Installing Opera Mini gets you a browser that just about gets the job done, but because it's forced to defer to the phone's OS for things like text input there are glaring discontinuities in the quality of the experience.&lt;/li&gt;&#xD;
&lt;li&gt;The email package is unusable - it's easier for me to use Opera to get at my webmail account than to use the provided email client to get at my email. This is a phone with 3G and a keyboard FFS - did nobody even try to use the damn thing in the real world before they foisted it upon the customers? The thing's so flakey that you can never be sure whether it's being mysteriously slow at getting the connection or has hung. There's an "updating" icon but it doesn't go into animated mode unless you back out of the inbox and go back into it. Even if you do that it carries on animating when the app's crashed so you might as well give up.&lt;/li&gt;&#xD;
&lt;li&gt;The camera is extraordinarily bad. In poor lighting conditions it is astoundingly noisy. This means any indoor shots - not just in the evening; light from a window on a bright day isn't sufficient. Nor is the flash. In fact the flash makes no discernible difference to the quality of the pictures! I'm not comparing it to my Nikon for quality - I'm comparing it to the steam powered Nokia 7630i&lt;sup&gt;&lt;a href="#footnote_3"&gt;3&lt;/a&gt;&lt;/sup&gt; I had before which had a camera that was merely mediocre rather than utterly pointless.&lt;/li&gt;&#xD;
&lt;li&gt;I did briefly toy with the idea of installing PuTTY onto the phone but gave up rapidly. There's no obvious way to access a binary file on the memory card from the built in OS.&lt;/li&gt;&#xD;
&lt;li&gt;The music player doesn't have any obvious way to play a group of songs. Perhaps there's a way but I couldn't find it.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;These last two problems might possibly be ameliorated by using the Nokia Connect software on my PC to install things but I've avoided this for two reasons:&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;I have in the past used Nokia Connect with my Nokia 7630i. I would rather smear excrement on my face than use it again.&lt;/li&gt;&#xD;
&lt;li&gt;Even if I hadn't used it in the past, the software on the phone is so monumentally bad that nothing on earth would persuade me to contaminate my PC with something from the same authors.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;Having been bitten by a manufacturer that I always had reason to trust&lt;sup&gt;&lt;a href="#footnote_4"&gt;4&lt;/a&gt;&lt;/sup&gt;, there is no way that my next phone will be anything other than an iPhone - plenty of people hate the iPhone for what it represents (Apple, Steve Jobs, smug hippy software developers, smug yuppie bankers) but nobody much hates it for what it is - a decent working phone with some high quality applications. Niggles about "such and such an interaction isn't completely intuitive" don't cut the mustard when compared with "doesn't work properly".&lt;/p&gt;&#xD;
&lt;p&gt;In fact I think this is Steve Job's real genius: his company makes products that work properly. The software is finished. Not perfect, but definitely finished. Nokia, it seems, now make products that look quite nice but don't do what you bought them for. Once your customers start realising that you're doomed, so my prophecy is that Nokia's going to sink until it only exists (perhaps) as a brand owned by someone else and Apple will continue its inexorable rise until they take their eye off the ball and stop paying attention to making products that work properly.&lt;/p&gt;&#xD;
&lt;p&gt;The others? Until they stop defining their products by running to keep up with Apple I'll give it a miss. If you're chasing that hard you probably think you don't have time to finish your software.&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;hr width="50%"/&gt;&#xD;
&lt;div class="footnotes"&gt;&#xD;
&lt;p&gt;&lt;sup&gt;&lt;a name="footnote_1"&gt;1&lt;/a&gt;&lt;/sup&gt;. Not always reliable though - in general they've been fine but one phone, as a result of a design flaw in the screen connection, had to be replaced half a dozen times before I got a good one. However the one that finally worked properly is still in active use by the mother of an ex-gf several (six I think?) years later which rather makes up for that.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;sup&gt;&lt;a name="footnote_2"&gt;2&lt;/a&gt;&lt;/sup&gt;. What I really want is a Psion 5mx that's also a phone. I wish someone would buy the patent for that clever keyboard and build it into something with a more topical version of the processor - it's ironic that the software on that is the antecedent of the horrible cockup on the Nokia.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;sup&gt;&lt;a name="footnote_3"&gt;3&lt;/a&gt;&lt;/sup&gt;. The Nokia 7630i was a reasonable phone. As a phone it was good and because it made no pretension to being anything other than a phone I was happy to accept the limitations.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;sup&gt;&lt;a name="footnote_4"&gt;4&lt;/a&gt;&lt;/sup&gt;. The last time I got brand-fucked was with a Panasonic DVR that proved barely usable and seemed to be the result of taking their DVD, HDR, and tuner products and then nailing them together. There were glaring discontinuities when switching it between its byzantine modal states.&lt;/p&gt;&#xD;
&lt;/div&gt;</content:encoded>
      <pubDate>Wed, 10 Feb 2010 11:46:45 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/unfit-and-finnish</guid>
      <dc:date>2010-02-10T11:46:45Z</dc:date>
    </item>
    <item>
      <title>Thinkpad R60e disk upgrade</title>
      <link>http://geeklondon.com/blog/view/inspecting-some-installers</link>
      <content:encoded>&lt;p&gt;I've been hearing good things about &lt;acronym title="Solid State Disks"&gt;SSDs&lt;/acronym&gt; for a while now. Now I've run out of space on the XP machine (a Thinkpad R60e) that I use for music and photos it seemed like a good time to go through the pain of an upgrade. I picked up a couple of 128Gig drives (CT128M225) from &lt;a href="http://crucial.com/"&gt;Crucial&lt;/a&gt;&lt;a href="#Footnote1"&gt;[1]&lt;/a&gt;, one for the crammed XP box &lt;s&gt;and another for the Linux box (a Thinkpad X40)&lt;/s&gt; &lt;i&gt;Oops. Wrong dimensions and connector for the X40 - an alternative is on order&lt;/i&gt;.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I also picked up a terrabyte external disk pack to back everything up to. I learn - slowly, but I do. There's nothing quite like the buzzing cold feeling of formatting the sole disk containing the last month's work to give you that zealous enthusiasm for data recovery. Backup done, off we go with the install. Not quite as simple as I hoped, but I got there:&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Remove old disk, insert new disk. Boot. BIOS recognises it. Hussah!&lt;/li&gt;&#xD;
&lt;li&gt;Insert XP installer CD. Reboot.&lt;/li&gt;&#xD;
&lt;li&gt;No dice; XP doesn't admit the existence of any such disk drive. Why do we still have BIOSes? Someone remind me. On second thoughts don't.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;After a bit of asking around, Googling, and so forth, it emerges that XP doesn't support SATA drives without external drivers. They have to be installed from a floppy disk. I don't have a floppy disk drive. Which is a bit strange because I know I installed it originally and I don't remember using a floppy disk at any stage in the process&lt;a href="#Footnote2"&gt;[2]&lt;/a&gt;.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Worried that I have a duff disk I decide to install Ubuntu (9.04) on it. Goes on like a charm in about 40 minutes, most of which I spend eating toast. Installers that ask all the questions up front make life so much easier. I start to see a possible glimmer.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I install &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. Well, "install" makes it sound more intrepid than it warrants:&lt;/p&gt;&#xD;
&#xD;
&lt;pre class="terminal"&gt;&#xD;
sudo apt-get install virtualbox&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;God I love aptitude. Anyway, that sorted out I install XP within VirtualBox. That boots and runs rather nicely. Interesting experiment - it looks to me like running Ubuntu as the "real" OS with VirtualBox is a real option if you only need a handful of Windows apps. Anyway, moving on:&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Using &lt;a href="http://www.nliteos.com/"&gt;nLite&lt;/a&gt; within the virtual Windows session I built a SlipStream ISO from my WinXP SP2 disk that includes the SATA drivers I need&lt;a href="#Footnote3"&gt;[3]&lt;/a&gt; for my chipset.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Drag the ISO out into the host Ubuntu OS and burn it to a CD. Reboot...&lt;/p&gt;&#xD;
&#xD;
&lt;pre style="background-color: blue; color: yellow; font-weight: bold;"&gt;&#xD;
Setup cannot find the End-User License Agreement (EULA)&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;WTF? Did I accidentally overwrite it or something? After a bit of Googling again, however, it turns out that this is possibly one of the least helpful error messages I've ever seen. That's actually quite a high bar&lt;a href="#Footnote4"&gt;[4]&lt;/a&gt;. Still, I suppose Microsoft can't be held entirely culpable for errors caused when a third party is cobbling a disk together like this. Anyway, the real problem seems to be related to this ticket: &lt;a href="http://support.microsoft.com/kb/326673"&gt;326673 Error Message: Setup Cannot Find the End-User License Agreement&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Despite the details described there that seems to also apply if you have a partition type that XP can't interpret. Ho hum. I could zap Ubuntu and have another go at booting, but if &lt;em&gt;that&lt;/em&gt; doesn't work I'm going to want to boot something and installing again seems a bit of a waste of time. Hmm, let's try it with SP3 as well:&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Reboot Ubuntu.&lt;/li&gt;&#xD;
&lt;li&gt;Boot into VirtualBox.&lt;/li&gt;&#xD;
&lt;li&gt;Download SP3 and rebuild the slipstream disk with that added.&lt;/li&gt;&#xD;
&lt;li&gt;Drag ISO out into Ubuntu.&lt;/li&gt;&#xD;
&lt;li&gt;Burn ISO.&lt;/li&gt;&#xD;
&lt;li&gt;Reboot.&lt;/li&gt;&#xD;
&lt;li&gt;Hallelujah.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;After the usual multi-hour install process&lt;a href="#Footnote5"&gt;[5]&lt;/a&gt; (well, XP is old, it's supposed to be better in Windows 7, we'll forgive it) and jiggling config to get XP to &lt;strong&gt;NEVER&lt;/strong&gt; give me another popup nag message &lt;strong&gt;EVER&lt;/strong&gt; under &lt;strong&gt;ANY&lt;/strong&gt; circumstances &lt;strong&gt;OR ELSE&lt;/strong&gt;, I'm up and running.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The verdict: damn, SSDs are nice. Ubuntu booted from cold in about 12 seconds. XP in about 20. That's to useful work mode. Application loads are distinctly snappy. We'll see how the currently clean install handles when it's had a bit of time to accumulate cruft (I'll update as and when). Running the laptop without any disk noise is just slightly creepy. But aside from that it's well worth the effort.&lt;a href="#Footnote6"&gt;[6]&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
I do like the way that this article has absolutely no topicality. Both Windows 7 and Ubuntu 9.10 came out a few weeks back and here I am installing an ancient copy of Windows and a mildly venerable version of Linux. But what the heck, I had to go through the pain so you can read it or shove off.&lt;/p&gt;&#xD;
&#xD;
&#xD;
&lt;h2&gt;Footnotes&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a name="Footnote1"&gt;1.&lt;/a&gt; I tried Dabs, but they played the in-stock-until-you-actually-order-it game again. I don't think I'll bother buying from Dabs in future.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a name="Footnote2"&gt;2.&lt;/a&gt; After a while I decided I must have used a Thinkpad floppy disk drive that I used to have kicking around to install XP.  Then after a bit more thought I realised that that drive required the ultrabay and the cheapo R60e (yes, the 'e' stands for "economy") I have now didn't have an ultrabay slot. &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a name="Footnote3"&gt;3.&lt;/a&gt; Downloaded from the IBM website - one of the nice things about Thinkpads is that there is or was great product support in the way of driver and reference manual downloads.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a name="Footnote4"&gt;4.&lt;/a&gt; My personal favourite is the eminently passive "There has been an error", but at least it doesn't mislead you.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a name="Footnote5"&gt;5.&lt;/a&gt; In the neolithic era when I did tech support for the dear departed ICL we used to tell people to reinstall Windows for Workgroups 3.11 if we couldn't figure out what the problem was. It didn't help, but generally they got so disheartened at the prospect that they gave up on whatever bit of flakey software we'd foisted upon them and never reappeared on our ticket queue. This is what happens when you use the wrong metrics to measure "quality".&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a name="Footnote6"&gt;6.&lt;/a&gt; I'm still perplexed about how I previously installed XP on the machine; there's no way I could have forgotten building a slipstream disk and I know I didn't use a dodgy 'warez' version.&lt;/p&gt;</content:encoded>
      <pubDate>Wed, 09 Dec 2009 18:15:50 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/inspecting-some-installers</guid>
      <dc:date>2009-12-09T18:15:50Z</dc:date>
    </item>
    <item>
      <title>Convergence</title>
      <link>http://geeklondon.com/blog/view/thump-thump-thump</link>
      <content:encoded>&lt;p&gt;I had a backpack stolen the other week - all very annoying. The mobile phone has probably been the most irritating loss as it doubles as my watch and alarm clock. I don't actually own a real alarm clock these days so I've had to make do with the laptop instead. Things to remember when using a laptop as an alarm clock:&lt;/p&gt;&#xD;
&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;Disable hibernation.&lt;/li&gt;&#xD;
&lt;li&gt;Plug it in.&lt;/li&gt;&#xD;
&lt;li&gt;Set it to play a noise not just display a dialog.&lt;/li&gt;&#xD;
&lt;li&gt;Do not pick "Tomorrow" when setting your morning call just after midnight unless you &lt;strong&gt;really&lt;/strong&gt; mean tomorrow.&lt;/li&gt;&#xD;
&lt;li&gt;There is no snooze button.&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&#xD;
&lt;p&gt;That last one's the deal breaker. I'm picking up a travel clock this evening.&lt;/p&gt;</content:encoded>
      <pubDate>Mon, 12 Oct 2009 17:13:34 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/thump-thump-thump</guid>
      <dc:date>2009-10-12T17:13:34Z</dc:date>
    </item>
    <item>
      <title>Chrome Server Launches</title>
      <link>http://geeklondon.com/blog/view/chromeserver</link>
      <content:encoded>&lt;p&gt;At last, &lt;a href="http://chromeserver.com/" title="Chrome Server - a site for building dynamic web apps"&gt;Chrome Server&lt;/a&gt; is live. We're in a Beta mode for the foreseeable future, but we're open to the public. Please create an account, login, and start creating cool stuff. Oh, you want to know what it is first? Luddite!&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Lots of hassle&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;Developing simple web applications is ridiculously difficult. You have to configure application servers, databases, and scripting modules. You need to know server-side scripting languages and database query languages. You need to set up file shares for the codebase and you need various code editors installed on your developers' machines.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;There are economies of scale, of course. If you're a big developer shop you have an arsenal of specialists to manage most of these tasks. Chrome Server is not for the big developers. Chrome Server is for the occasional developer who sometimes thinks: "wouldn't it be neat to have a little website that...?" Or the part-time game author who wants to put their work up on the web but doesn't fancy spending a couple of hours tweaking the Apache configuration files. Or for anyone who wants to prototype something before they invest any of that effort later on.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Interested?&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Hassle limited&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;For a one man show, putting a web application that runs a bit of server side logic generally requires you to know operating system basics, web server configuration basics, a scripting language (say PHP), a database language (usually SQL), HTML for the page layout, CSS for the styling, and Javascript for any dynamic stuff on the page (ActionScript used by Flash is basically another Javascript dialect).&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;To program Chrome Server you need to know HTML for the page layout (but we supply a basic template you can start with), CSS for the styling (but you can use our style sheets if you like), and Javascript for any dynamic stuff on the page &lt;b&gt;or&lt;/b&gt; for any server side or database code. That's a bit simpler isn't it?&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Oh and you don't need an editor. Just a web browser. The code for a Chrome Server site can all be edited through the browser.&lt;/p&gt;&#xD;
&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://chromeserver.com/images/screenshots/edit_script_512.png" width="512" height="384" title="Editing a page script" alt="Screenshot of Chrome Server IDE"/&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;So for a typical tool comparison:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;b&gt;Normal:&lt;/b&gt;&#xD;
&lt;ul&gt;&lt;li&gt;Browser&lt;/li&gt;&lt;li&gt;Eclipse&lt;/li&gt;&lt;li&gt;PHP&lt;/li&gt;&lt;li&gt;SQL&lt;/li&gt;&lt;li&gt;MySQL&lt;/li&gt;&lt;li&gt;Apache&lt;/li&gt;&lt;li&gt;Linux&lt;/li&gt;&lt;li&gt;HTML&lt;/li&gt;&lt;li&gt;CSS&lt;/li&gt;&lt;li&gt;Javascript&lt;/li&gt;&lt;/ul&gt;&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&#xD;
&lt;b&gt;Chrome Server:&lt;/b&gt; &#xD;
&lt;ul&gt;&lt;li&gt;Browser&lt;/li&gt;&lt;li&gt;HTML&lt;/li&gt;&lt;li&gt;CSS&lt;/li&gt;&lt;li&gt;Javascript&lt;/li&gt;&lt;/ul&gt;&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Personally I think that's quite the improvement&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Learn more&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;If you want to learn more about &lt;a href="http://chromeserver.com/"&gt;Chrome Server&lt;/a&gt; then I recommend &lt;a href="http://chromeserver.com/documentation/introduction/1.0-beta/abc/index.html"&gt;watching the ten minute walk through&lt;/a&gt; of creating an online todo list first, then have a &lt;a href="http://chromeserver.com/documentation/"&gt;browse through the API documentation&lt;/a&gt;, and then &lt;a href="http://chromeserver.com/admin/register"&gt;create an account&lt;/a&gt; and start playing.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Have fun! &lt;a href="mailto:dave@chromeserver.com?subject=Chrome Server Beta (Blog)"&gt;Drop me a line&lt;/a&gt; if you have any ideas for missing features.&lt;/p&gt;</content:encoded>
      <pubDate>Mon, 26 Jan 2009 13:17:49 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/chromeserver</guid>
      <dc:date>2009-01-26T13:17:49Z</dc:date>
    </item>
    <item>
      <title>If the shoe fits...</title>
      <link>http://geeklondon.com/blog/view/hoptastic-footwear</link>
      <content:encoded>&lt;script type="text/javascript" src="http://chromeserver.com/js/jquery/jquery-1.2.6.js"&gt;&lt;/script&gt;&#xD;
   &lt;script type="text/javascript" src="http://chromeserver.com/js/jquery/jquery-lightbox-0.5/js/jquery.lightbox-0.5.js"&gt;&lt;/script&gt;&#xD;
   &lt;script type="text/javascript" src="http://chromeserver.com/js/doc/doc_lightbox.js"&gt;&lt;/script&gt;&#xD;
   &lt;!-- Strictly speaking these are malformed, but failure mode will be benign: --&gt;&#xD;
  &lt;style media="screen"&gt;&#xD;
.screenshot_entry &gt; a.lightbox {&#xD;
   float: left;&#xD;
}&#xD;
&#xD;
a.lightbox &gt; img{&#xD;
   border: 5px solid #0F60A0;&#xD;
   border: 5px solid white;&#xD;
}&#xD;
a.lightbox:hover &gt; img {&#xD;
   border: 5px solid #0F60A0;&#xD;
}&#xD;
&#xD;
#lightbox-container-image-data-box {&#xD;
   font-size: medium;&#xD;
}&#xD;
&#xD;
#gallery ul a:hover { color: #fff; }&#xD;
&#xD;
.screenshot_entry {&#xD;
   padding-top: 0.25em;&#xD;
   padding-bottom: 1em;   &#xD;
   padding-right: 0.25em;&#xD;
   padding-left: 0.25em;&#xD;
   margin-right: 1em;&#xD;
   margin-left: 1em;&#xD;
   margin-top: 0.25em;&#xD;
   margin-bottom: 0.25em;&#xD;
   border-top: 1px dashed black;&#xD;
}  &#xD;
  &lt;/style&gt;&#xD;
   &lt;style&gt;@IMPORT url("http://chromeserver.com/js/jquery/jquery-lightbox-0.5/css/jquery.lightbox-0.5.css");&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;Last year I learned to dance. Probably not very well, but it's a hell of a departure for someone who notoriously feared and loathed any event where I might be called upon to jump up and down in a foolish manner in public.&lt;/p&gt;&#xD;
&#xD;
   &lt;div class="screenshot_entry"&gt;&#xD;
      &lt;a class="lightbox" title="The Jive Aces at The 100 Club" href="http://geeklondon.com/images/shoes/100_club_600.jpg"&gt;&#xD;
         &lt;img width="150" height="113" alt="Thumbnail of The Jive Aces at The 100 Club" src="http://geeklondon.com/images/shoes/100_club_150.jpg"/&gt;&#xD;
      &lt;/a&gt;&#xD;
      &lt;p&gt;I finally broke this particular phobia because a good friend had been drawn into the world of swing dancing (known as "Lindy Hop"). She constantly eulogized her new hobby and I finally got to see some of this first hand&#xD;
      at a party at her house attended by some of her dancing buddies. They were very obviously having enormous fun and so I decided with somewhat mixed feelings to go along to a beginners lesson at the Monday night session (called "Stompin") in &lt;a href="http://www.the100club.co.uk/"&gt;The 100 Club&lt;/a&gt; on Oxford Street.&lt;/p&gt;&#xD;
      &lt;p&gt;My reasoning was that if I hated the dancing (as I expected to) then I could at least skulk in a corner and watch the live band there. Even attending the lesson was well outside my comfort zone and I was ridiculously nervous beforehand. If you like dancing - or are ambivalent about it - then you probably won't get this, but even the very low commitment of going along for this lesson was quite a big deal for me.&lt;/p&gt;&#xD;
      &lt;p&gt;My phobia wasn't in quite the same league as &lt;a href="http://www.stephenfry.com/blog/2008/03/07/bored-of-the-dance/"&gt;Stephen Fry's&lt;/a&gt; loathing of dancing itself (I've always loved Fred Astaire movies) so the idea of being able to dance was appealing - it's just that I had never had a positive dance experience in practice.&lt;/p&gt;&#xD;
      &lt;p&gt;So I turned up to the lesson, hands shaking slightly, sat around feeling foolish as we waited for the lesson to start and... lost all self-consciousness and absolutely loved it. Which you probably were expecting, but I definitely wasn't.&lt;/p&gt;&#xD;
      &lt;p&gt;Unfortunately a single lesson wasn't enough for me to feel competent in the social dance with the live band. Even if I'd been a bit more adroit I'd still only have learnt enough steps for about ten seconds worth of any given song! It did give me a real taste for swing dance, however, and I started attending the Monday night lessons&lt;/p&gt;&#xD;
      &lt;p&gt;(This photo shows &lt;a href="http://www.jiveaces.com/"&gt;The Jive Aces&lt;/a&gt; performing at The 100 Club just before Christmas)&lt;/p&gt;      &#xD;
      &lt;div style="clear: both;"&gt;&lt;/div&gt;&#xD;
   &lt;/div&gt;&#xD;
&#xD;
   &lt;div class="screenshot_entry"&gt;&#xD;
      &lt;a class="lightbox" title="My new Black and Whites" href="http://geeklondon.com/images/shoes/shoes_y600.jpg"&gt;&#xD;
         &lt;img width="150" height="175" alt="Thumbnail of Black and White swing dancing shoes" src="http://geeklondon.com/images/shoes/shoes_150.jpg"/&gt;&#xD;
      &lt;/a&gt;&#xD;
      &lt;p&gt;That was back on the 18th of August. I quickly decided that Monday night lessons weren't enough and &#xD;
      started looking for other lessons. The same teacher (the excellent Simon Selmon &#xD;
      of &lt;a href="http://www.swingdanceuk.com/"&gt;The London Swing Dance Society&lt;/a&gt;) runs lessons in Holborn&#xD;
      on Tuesdays so I started going to those as well. Then I tried &lt;a href="http://www.jitterbugs.co.uk/"&gt;Jitterbugs&lt;/a&gt; over in Marble Arch on Wednesdays. Then I signed up for a basic ballroom class in Marylebone on Thursdays because any and all taught dancing was becoming an irresistible idea.&lt;/p&gt;&#xD;
      &lt;p&gt;It's fair to say that an obsession has taken hold. I go to Sunday lessons where available and while I haven't quite managed a full seven days in a row of dance just yet I fully expect that to be a highlight of 2009.&lt;/p&gt;&#xD;
      &lt;p&gt;So I had to get some special shoes. Obviously.&lt;/p&gt;&#xD;
      &lt;p&gt;I was ludicrously excited about these. I don't think I've ever been as excited about a pair of shoes. In fact I don't think I've ever been excited about a pair of shoes &lt;b&gt;at all&lt;/b&gt; before. It's quite embarrassing.&lt;/p&gt;&#xD;
      &lt;p&gt;After checking out the options I settled on a pair of black and white Oxfords. They have a metal reinforcing "tang" to give them a bit of extra spring, they are of a very supple leather so that your feet can move around in them flexibly and they're soled in suede so that you can slide around and spin nicely in them.&lt;/p&gt;&#xD;
      &lt;p&gt;As shoes go they're pretty cool.&lt;/p&gt;&#xD;
      &lt;div style="clear: both;"&gt;&lt;/div&gt;&#xD;
   &lt;/div&gt;&#xD;
&#xD;
   &lt;div class="screenshot_entry"&gt;&#xD;
      &lt;a class="lightbox" title="Freed's shop on St Martin's Lane" href="http://geeklondon.com/images/shoes/freed_shopfront_600.jpg"&gt;&#xD;
         &lt;img width="150" height="113" alt="Thumbnail of Freed's storefront" src="http://geeklondon.com/images/shoes/freed_shopfront_150.jpg"/&gt;&#xD;
      &lt;/a&gt;&#xD;
      &lt;p&gt;I bought the shoes at the &lt;a href="http://www.freedoflondon.com/"&gt;Freed&lt;/a&gt; shop on St. Martin's Lane in the west end of London. This is an experience in its own right. The shop's main focus is ballet shoes - it services ballet companies across the world - but they have a good range of other dance footwear and &#xD;
      while they only had one black and white shoe available I rather liked the design.&lt;/p&gt;&#xD;
      &lt;p&gt;I was also influenced by the fact that Freed's shoes would be available (hand made mark you!) in about a fortnight whereas the alternatives would take more like a month and the price was roughly the same at £80.&lt;/p&gt;&#xD;
      &lt;div style="clear: both;"&gt;&lt;/div&gt;&#xD;
   &lt;/div&gt;&#xD;
&#xD;
   &lt;div class="screenshot_entry"&gt;&#xD;
      &lt;a class="lightbox" title="Inside Freed's" href="http://geeklondon.com/images/shoes/freed_inside_600.jpg"&gt;&#xD;
         &lt;img width="150" height="113" alt="Thumbnail of Freed's interior" src="http://geeklondon.com/images/shoes/freed_inside_150.jpg"/&gt;&#xD;
      &lt;/a&gt;&#xD;
      &lt;p&gt;In fact my shoes were ready for a fitting (how many £80 shoes come with a fitting?) after a week so I dropped by to check that out and confirm the sole type that I wanted. The alternatives were leather or resin but I'm pleased with the suede option that I went for on the advice of my dancing friends.&lt;/p&gt;&#xD;
      &lt;p&gt;Inside and out the shop is rather old fashioned, up to and including the service which is excellent.&lt;/p&gt;&#xD;
      &lt;p&gt;Another week and my shoes were ready. They fit wonderfully, they feel lovely to dance in, and they improve my technique not one jot (but you can't have everything). I adore them.&lt;/p&gt;&#xD;
      &lt;p&gt;Shoes aside I've also started poking my nose into retro clothing stores to see if they have any 30s style clothing. I even went to the extraordinary &lt;a href="http://www.angels.uk.com/sale.html#images"&gt;Angels' sale&lt;/a&gt; to look through the costumes because I'm starting to think I should aquire some braces at the very least. There are quite a few dancers who really dress up in full period style and they look brilliant. For now I'm making do with chinos and a t-shirt (which are very practical at least) but I think it's only a matter of time.&lt;/p&gt;&#xD;
      &lt;div style="clear: both;"&gt;&lt;/div&gt;&#xD;
   &lt;/div&gt;&#xD;
   &#xD;
   &lt;p&gt;So those are my dancing escapades in 2008. I've also been to several four hour long workshops on Sundays, danced unofficially with others at a free event in &#xD;
   the Festival Hall's &lt;a href="http://www.freelondonlistings.co.uk/events-categories/venueevents/339-clore-ballroom-southbank-centre.html"&gt;Clore Ballroom&lt;/a&gt;, and whenever possible at every other Monday night event at The 100 Club. Last night I danced into the new year at "The Dancers' Own" New Year's Eve party. I don't know exactly what 2009 will &#xD;
   hold, but if there is not a lot of dancing I will sulk.&lt;/p&gt;&#xD;
   &#xD;
   &lt;p&gt;If you think you can't dance, try a lesson anyway. But be warned - it takes over your life like a cult and it's a lot more addictive than nicotine (healthier too though).&lt;/p&gt;</content:encoded>
      <pubDate>Thu, 01 Jan 2009 21:47:36 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/hoptastic-footwear</guid>
      <dc:date>2009-01-01T21:47:36Z</dc:date>
    </item>
    <item>
      <title>Happy Revels</title>
      <link>http://geeklondon.com/blog/view/2008-2009</link>
      <content:encoded>&lt;p&gt;A last note to round off a marvellous 2008 (and ensure that I have at least one post for December)...&lt;/p&gt;&#xD;
&lt;p&gt;I'm going to spend the evening having fun and thinking up new year resolutions to wince at this time next year.&lt;/p&gt;&#xD;
&lt;p&gt;Here's hoping that any and all of you have had an equally excellent 2008 and that you are about to have a magnificent 2009.&lt;/p&gt;</content:encoded>
      <pubDate>Wed, 31 Dec 2008 17:07:55 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/2008-2009</guid>
      <dc:date>2008-12-31T17:07:55Z</dc:date>
    </item>
    <item>
      <title>CSS Redux</title>
      <link>http://geeklondon.com/blog/view/godot_is_waiting_for_css3</link>
      <content:encoded>&lt;p&gt;I wrote &lt;a href="http://geeklondon.com/blog/view/float_like_a_wasp"&gt;my article on CSS&lt;/a&gt;, "Completely Sodding Stupid", back in August. Now it's November. This last year has gone past phenomenally quickly for me. I meant to write this follow up article about two months ago. Sorry about that!&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I think the first thing to say is that if you don't want to receive a few hundred emails beginning "Completely Sodding Stupid Article"&lt;sup&gt;&lt;a href="#footnotes"&gt;1&lt;/a&gt;&lt;/sup&gt; you should think more carefully when choosing a title.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;That was intended to be linkbait - but even so it grabbed far more attention than I had anticipated. In fact it has received about 40,000 visitors since I wrote it. Here are a few pertinent links to the discussions that arose around it:&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
 &lt;li&gt;&lt;a href="http://news.ycombinator.com/item?id=280324"&gt;News.YCombinator article&lt;/a&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;&lt;a href="http://www.reddit.com/r/programming/comments/70l67/you_are_not_alone_none_of_the_rest_of_us_can/"&gt;Reddit article&lt;/a&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;&lt;a href="http://ajaxian.com/archives/you-are-not-alone-none-of-the-rest-of-us-can-fathom-css-either"&gt;Ajaxian article&lt;/a&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;Of all the comments I think this observation is my favourite:&lt;/p&gt;&#xD;
&#xD;
&lt;blockquote&gt;&lt;a href="http://www.reddit.com/r/programming/comments/70l67/you_are_not_alone_none_of_the_rest_of_us_can/c05d7kw"&gt;I love CSS. Except when I want to stab it in the eye. Which is always.&lt;/a&gt;&lt;i&gt;- "Lukifer" on Reddit&lt;/i&gt;&lt;/blockquote&gt;&#xD;
&#xD;
&lt;p&gt;I had expected the majority of the discussions to amount to idiots disagreeing with me on ideologically pro CSS grounds or idiots agreeing with me on ideologically anti CSS grounds. I was completely wrong. The majority of the discussions were thoughtful and nuanced. While the quality of the discussion was high, the quality of the emails&lt;sup&gt;&lt;a href="#footnotes"&gt;2&lt;/a&gt;&lt;/sup&gt; I received was even higher. Go internet!&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Cautionary Note&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;I don't think that "let's go back to using tables" is a viable solution. I don't use tables in my site design (check the source to this article if you don't believe me) and I don't propose them as a general solution to anyone else.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;A handful of people managed to take away that interpretation from the original article, so I'll say it again just to be clear:&lt;/p&gt;&#xD;
&#xD;
&lt;p class="caution" title="Tables bad. Layout abstraction good."&gt;&lt;b&gt;I do not support the use of tables as a "solution" to CSS layout problems&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Just so you know where I stand. Tables are good for representing table based data. They are not good for layout in any other circumstances because they cannot easily be made accessible to users with visual impairments, and because they intrude into the semantic content of the document making re-styling of the page an intrusive manual process.&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Insights&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;While my article title was linkbait, this was not in order to raise advert revenue. I have no advertising on this site. It was purely intended as a mechanism for getting some feedback on aspects of CSS that I found inexplicable. I think I learned a lot from the responses, so the exercise was successful.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;Browser support&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;I consciously mixed together several flavours of whine under one complaint. While I acknowledged this in the original article, I shall reiterate it here. Some of the problems arise from browser bugs, the existence of legacy browsers, and lack of support for the full suite of CSS capabilities. If you are designing for a single modern browser platform you can disregard a lot of the points I complain about.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;If you are designing for the real world of the web where old and incapable browsers still thrive, there is nothing to be done about this save wait patiently for the quality of the browsers to improve and the legacy platforms to quietly expire. With IE6 holding a 20% market share there will be people like me whining for quite a while to come.&lt;/p&gt;&#xD;
&#xD;
&#xD;
&lt;h3&gt;CSS Version 3&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;A lot of the proposals for solutions to the problems I cited were, essentially, that I should use or wait for CSS3 features. I have a bit of a bee in my bonnet about this. Firstly, yes, CSS3 does fix some of the problems that I complain about. However, CSS3 is not a standard - it is still in development. It has been in development for &lt;b&gt;ten years&lt;/b&gt;. This is ludicrous - ten years prior to the beginning of the standardization process for CSS3 the world wide web didn't even exist!&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Because CSS3 doesn't yet exist as a standard the CSS3 attributes are not yet supported across browsers. I can use proprietary extensions to enable CSS3-like features in Firefox, Safari, and so on, but I have to assume that some of my users will be using browsers that use older features, and I have to assume that at some point those proprietary extensions will become deprecated, limiting their long-term utility.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Again I don't have a fix for this, except that perhaps we should perhaps have the CSS3 committees taken out and shot.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;For some purposes (see "&lt;a href="#curvy_corners"&gt;Curvy corners&lt;/a&gt;") CSS3 proprietary extensions are probably adequate because in their absence things degrade in a usable, if not aesthetically pleasing, manner. In general, however, CSS3 suggestions amount to a "nice try but I still need a &lt;string&gt;real&lt;/strong&gt; solution."&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;Style and Layout&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;This is the gut of the problem. It hadn't really occurred to me, but several respondents by email and in the discussion threads made the point:&lt;/p&gt;&#xD;
&#xD;
&lt;p class="caution" title="CSS is great. Also teh suck."&gt;&lt;b&gt;CSS is a great styling language and a horrible layout language&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;It's true. If you just want to make text look different - change the font, size, margins, weight, colours, and so on, CSS simply couldn't be easier. It makes absolute sense as a styling language. It allows you to keep these issues quite independent of the semantics of the content.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;On the other hand, if you want to change the layout of the content - move paragraphs around, align things next to each other, align things vertically on the page, calculate positions relative to other components on the page, and so on and so forth, then you will resort to positioning hacks&lt;sup&gt;&lt;a href="#footnotes"&gt;3&lt;/a&gt;&lt;/sup&gt;, compromise the semantic content by putting in a bunch of &lt;span class="code"&gt;&amp;lt;div&amp;gt;&lt;/span&gt; elements that have no intrinsic meaning, or both. Or you'll get fed up with the whole thing and start whining about how table based layout was much easier. Which it was. Not better - easier.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Several commenters pointed out that dynamic layout is a problem pretty much solved in application design but horribly botched in CSS. If you look at the &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/swing/index.html"&gt;Java Swing API&lt;/a&gt;, you will see &lt;a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html"&gt;support for numerous different layout managers&lt;/a&gt;, each capable of laying out a page in a sane manner and reacting politely to changes in the window metrics.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I think that the layout aspects of CSS should be deprecated and moved into another standard - Cascading Layout Sheets or somesuch - but given the glacial progress on CSS3 this is not a practical solution.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;CSS3 does include &lt;a href="http://www.w3.org/Style/CSS/current-work#layout"&gt;a table-like layout extension&lt;/a&gt; that shows some promise, but I'm not entirely optimistic that this will solve all our problems.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;In the following link someone makes the argument of CSS layout versus CSS styling far better than me: &lt;a href="http://news.ycombinator.com/item?id=282552"&gt;http://news.ycombinator.com/item?id=282552&lt;/a&gt;. An email from Stewart Stremler made similar points.&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Solutions&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;Here are the solutions that came up during discussion with respondents. Some of them I was aware of, some of them are simple fixes that I had no idea existed, some of them are hacky fixes that work but that I think support my point about the counter-intuitive nature of CSS. Some of them have no sensible solutions.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="curvy_corners"&gt;&lt;/a&gt;&lt;h3&gt;1. Curvy corners&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;No sane fix out side of CSS3.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;There are the various hacks that I alluded to in the original article, using absolute positioning of bitmaps, or the use of Javascript. Then there are the CSS3 solutions that have not yet been standardized.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Some users made the point that these are not a legitimate part of the CSS specification - they felt that accommodating curvy corners was silly; why not allow for bevelled edges and other ornamentation if you allow for curved corners? Good question. The answer, I think, is that CSS should make it easy to do the things that people generally want to do. There wouldn't be so many hacks for this effect if it weren't in demand. I would certainly prefer it if CSS was powerful enough to express arbitrary decoration on page elements - but it isn't and until it is specific support for common use cases is reasonable.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;To achieve curvy corners on most modern browsers (degrading to boring square corners on internet explorer) specify a border radius value for the element in question. For Mozilla and related browsers (Firefox etc) the proprietary attribute is &lt;span class="code"&gt;-moz-border-radius&lt;/span&gt;. For WebKit and related browsers (Safari etc) &lt;span class="code"&gt;-webkit-border-radius&lt;/span&gt;. The eventual standard attribute will (probably - that's the problem with unfinished standards) be &lt;span class="code"&gt;border-radius&lt;/span&gt;. There are other related attributes allowing finer control, but a typical usage in my CSS files is therefore:&lt;/p&gt;&#xD;
&#xD;
&lt;pre class="terminal" title="CSS3 and Proprietary Border Radius attributes"&gt;&#xD;
   border-radius: 6px;&#xD;
   -moz-border-radius: 6px;&#xD;
   -webkit-border-radius: 6px;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Note that in the above I take a gamble and assume that the CSS3 attribute will be finalized as it currently stands and exhibit the same behaviour as the proprietary attributes. If that assumption holds true my page will one day look ok in future versions of Internet Explorer.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="vertical_floats"&gt;&lt;/a&gt;&lt;h3&gt;2. Vertical floats&lt;/h3&gt;&#xD;
 &#xD;
&#xD;
&lt;p&gt;Several people pointed out that floats don't really have much to do with vertical positioning, which I suppose is kind of true. So strike float from that - I just want a sane way to do vertical positioning. It doesn't seem to exist.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Classic example of where it's deficient: I want to place a piece of text in the exact center of the browser page, adjusting nicely if the user re-scales the browser.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Note that I do not want to center the top of the text in the page - it's the center of the element that should be centred. Here's one user's suggestion, which epitomizes what I hate about CSS "solutions":&lt;/p&gt;&#xD;
&#xD;
&lt;pre class="terminal" title="How tall is 'Hello' in Zulu?"&gt;&#xD;
top: 50%; margin-top: negative half of the inner element's height.&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;That fails badly to my mind because it requires you to know the size of the inner element. If I have dynamic content (and I usually do) it's impossible for me to know this in advance. Again, CSS is generally ok for people working on static content and prepared to use absolute or pixel based positioning - however I'm a web &lt;strong&gt;application&lt;/strong&gt; developer however, and I almost never work with purely static content. At a bare minimum I expect text to be available in multiple languages.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;As far as I know, something that can be clearly and simply stated - "center text in the page" is insanely difficult to do with CSS as it currently stands. CSS3 may address this (or it may not) but it's just ridiculous that something so basic is so hard to do.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;One person actually suggested that centering the text on the page "ought" to be hard. Perhaps I failed to take into account the possibility of a sociopath element on the CSS committees?&lt;/p&gt;&#xD;
&#xD;
&lt;a name="form_formatting"&gt;&lt;/a&gt;&lt;h3&gt;3. Formatting for forms&lt;/h3&gt; &#xD;
&#xD;
&lt;p&gt;This element produced some interesting feedback, but I don't think any of the solutions offered were really satisfactory.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;One argument made was that forms were best handled with tables. I don't really agree with this. A form isn't a table; it just looks a bit like one. Here's where the analogy breaks down for me though - take a simple form field where the label appears above or next to the field:&lt;/p&gt;&#xD;
&#xD;
&lt;img src="http://geeklondon.com/images/css_redux/form_layout.png" title="Two equivalent form field layouts" style="border: 1px solid red; margin: 0.25em 0.25em 0.25em 2em;"/&gt;&#xD;
&#xD;
&lt;p&gt;Take a look at the markup for the first field:&lt;/p&gt;&#xD;
&#xD;
&lt;pre class="terminal" title="Table markup for a label and field in two rows"&gt;&#xD;
&amp;lt;table&gt;&#xD;
   &amp;lt;tr&gt;&amp;lt;td&gt;1. Name:&amp;lt;/td&gt;&amp;lt;/tr&gt;&#xD;
   &amp;lt;tr&gt;&amp;lt;td&gt;&amp;lt;input type="text" name="name" value=""/&gt;&amp;lt;/td&gt;&amp;lt;/tr&gt;&#xD;
&amp;lt;/table&gt;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Now compare the markup for the second field:&lt;/p&gt;&#xD;
&#xD;
&lt;pre class="terminal" title="Table markup for a label and field in one row"&gt;&#xD;
&amp;lt;table&gt;&#xD;
   &amp;lt;tr&gt;&amp;lt;td&gt;2. Name:&amp;lt;/td&gt;&amp;lt;td&gt;&amp;lt;input type="text" name="name" value=""/&gt;&amp;lt;/td&gt;&amp;lt;/tr&gt;&#xD;
&amp;lt;/table&gt;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;They're quite different - and yet the semantic content is identical; it's a field with an associated label. Of course we don't have to use tables; there's a label element specifically for identifying this sort of property, but regardless of how we annotate the semantic relationship we make one of those to layouts layouts difficult to express unless we're prepared to resort to absolute positioning.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="floats_within_elements"&gt;&lt;/a&gt;&lt;h3&gt;4. Floats within elements&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;I accept that this is just how float works, but what I don't accept is that there's no simple way to get the desired &lt;i&gt;behaviour&lt;/i&gt; any other way.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;One of the suggested solutions is "clearfix" - basically a hack that requires you to add structural markup (e.g. a &lt;span class="code"&gt;&amp;lt;div&amp;gt;&lt;/span&gt; with a &lt;span class="code"&gt;clear: both;&lt;/span&gt; CSS attribute) to force the element to contain its floated items. This solution is not very nice since it breaks the separation between content and styling.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Another is the use of the &lt;span class="code"&gt;overflow: auto;&lt;/span&gt; CSS attribute to contain floats, but that then causes problems if you want to have normal content extending beyond the borders of the element, giving it scrollbars. Adding a floating caption to pre-formatted code that overflows the containing element would be an example of this scenario.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;There do seem to be some hacky solutions to this problem, such as the "&lt;a href="http://www.positioniseverything.net/easyclearing.html"&gt;Easy Clearing&lt;/a&gt;" solution but none of them are what I would think of as intuitive - and there doesn't seem to be any clear reason for the deficiency.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;We'll call that one half-solved, ok?&lt;/p&gt;&#xD;
&#xD;
&lt;a name="graphical_buttons"&gt;&lt;/a&gt;&lt;h3&gt;5. Graphical Buttons&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;Two solutions were commonly offered here - one of them mediocre, the other excellent.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The mediocre solution is the use of the &lt;span class="code"&gt;&amp;lt;button&amp;gt;&lt;/span&gt; element. It looks like it ought to be what's wanted, but it has different semantics to the more commonly used &lt;span class="code"&gt;&amp;lt;input type="submit" ... &amp;gt;&lt;/span&gt; approach making it (generally) useless.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The good solution, and one I was completely unaware of, is to use, er, CSS stylings on the input element(s). In fact you can give the input element a &lt;span class="code"&gt;background-image&lt;/span&gt; property and even use the &lt;span class="code"&gt;:hover&lt;/span&gt; and &lt;span class="code"&gt;:active&lt;/span&gt; pseudo-classes to give it appropriate behaviour when you mouse-over and click it. Bad Dave for not knowing this.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;There's always a fly in the ointment of course - apparently you can't use the pseudo-classes on IE6, but that seems like a relatively minor failing; you can provide Javascript where it's enabled and the failure mode is at least reasonably benign. &#xD;
&#xD;
&lt;p&gt;Particular thanks to Jimmy Tang for some of the details on this.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="column_support"&gt;&lt;/a&gt;&lt;h3&gt;6. Column support&lt;/h3&gt;&#xD;
&#xD;
&lt;img class="image_left" src="http://geeklondon.com/images/css_redux/col_scroll_100.png" title="CSS3 style column support"/&gt;&#xD;
&#xD;
&lt;p&gt;My complaint about lack of column support was not just about the difficulty of positioning aligned blocks of text adjacent to each other (ridiculously difficult to start with) but also about managing the overflow of text between blocks in the manner that we see every day from newspaper articles. The Gutenberg bible was (beautifully) typeset in this manner; actually Johannes Gutenberg seriously over-engineered the whole thing but that's another story. CSS takes us back to a point in history prior to the arrival of moveable type! &lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I'm going to disregard the current hacks for managing columns - none of the non-javascript options manage the flow of text between columns. Let's take a look at CSS3 instead.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://www.w3.org/TR/css3-multicol/"&gt;The CSS3 spec&lt;/a&gt; allows for multi-column support in elements. I didn't acknowledge that in the original article and so far, so good. However, the implementations of this available in existing browsers shows a shocking usability flaw. I'm not sure whether this is innate to the standard or an artifact of those implementations, but for anyone planning to put dynamic content into form elements of this type they are practically unusable. I'm very worried that these are going to be locked into the standard as-is.&lt;/p&gt;&#xD;
&#xD;
&lt;img class="image_right" src="http://geeklondon.com/images/css_redux/Gutenberg_Bible_200.png" alt="The Gutenberg Bible" title="Multicolumn layout circa 1455"/&gt;&#xD;
&#xD;
&lt;p&gt;Text is allowed to overflow between columns, and with appropriate attributes set the browser will create and render additional columns to contain the extra text. So far so good. When the browser pane is full, however, the column elements are extended off the foot of the page. Aaargh! Look at the image to the left - this means an inordinate amount of scrolling is required as we follow the text between columns.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;This is a real usability problem as anyone who has read column-formatted PDF files on a small screen will attest. The scrolling rapidly becomes tiring and annoying. The natural direction for this extension of the columns would be to the right hand side (or the right for right-to-left languages) of the pane, adding columns as necessary. There are other ways the problem could be managed (something similar to the eminently sane default behaviour when handling overflow between pages when &lt;i&gt;printing&lt;/i&gt; these multi columns for example), but that seems to me the simplest.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I'd be interested to hear suggestions for how to bring this issue to the attention of the standards team - I assume it's not set in stone yet (if it is, why is the standard still a draft?)&lt;/p&gt;&#xD;
&#xD;
&lt;a name="order_independence"&gt;&lt;/a&gt;&lt;h3&gt;7. Order Independence&lt;/h3&gt;&#xD;
&#xD;
&lt;div class="sidebar_right" title="How often do you get to write a sidebar definining sidebars?"&gt;&#xD;
	&lt;p class="heading"&gt;Sidebar Example&lt;/p&gt;&#xD;
	&lt;p&gt;Usually a sidebar contains text that does not form a natural part of the main topic of discussion but which is in some way related to it. Definitions, anecdotes, and cautionary notes are typical contents.&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;The HTML markup should be independent of the layout. This means that for some elements their sequential order in the HTML shouldn't cause problems when you change the layout.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The sidebar given as an example here should certainly be associated with this section (7. Order Independence) of the document as a whole, but its specific position within this section is irrelevant. While changing the position from the right hand side to the left hand side is trivial, however, moving it from the top of the section to the bottom is a non-trivial exercise.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Another more fundamental example would be a chapter section within a book. Moving the glossary of a technical book from the front to the back is not something that the author would expect to be involved in - this would be the job of the layout artist or typesetter. However moving an entire section of content from one part of an HTML document to another requires serious mental fortitude for a CSS developer. Usually it is easier to manipulate the original content even though the change in position alters &lt;strong&gt;nothing&lt;/strong&gt; about the semantics of the document.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I believe that this is another example of CSS's limitations as a layout language - while it's easy enough to make the sidebar &lt;i&gt;look&lt;/i&gt; pretty, moving it around in the document will always cause problems. These problems are then compounded if you need to position elements relative to other elements which have themselves been moved around.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I hope that the changes in support for layout in CSS3 will start to make this sort of exercise somewhat simpler, but I have dark suspicions that it will always be problematic even in compliant browsers.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="width_on_inline_elements"&gt;&lt;/a&gt;&lt;h3&gt;8. Widths on inline elements&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;The good:&lt;/strong&gt; as innumerable people have now informed me, you can set the &lt;span class="code"&gt;display: inline-block&lt;/span&gt; attribute on an inline element, at which point you can specify its width attribute.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;The bad:&lt;/strong&gt; Nobody offered a good explanation of why you can't set widths on inline elements in the first place. You just can't.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;The ugly:&lt;/strong&gt;&#xD;
   &lt;blockquote&gt;IE7 will only render an element as 'inline-block' if it would normally default to 'inline.'&lt;i&gt; - Daniel Flaum&lt;/i&gt;&lt;/blockquote&gt;&#xD;
D'oh! But still better than nothing.&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;a name="addressing_text"&gt;&lt;/a&gt;&lt;h3&gt;9. Addressing text within textareas&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;Not really a CSS issue as such, having more to do with a limitation of HTML but this remained unaddressed. A few people pointed me towards &lt;span class="code"&gt;&amp;lt;div&amp;gt;&lt;/span&gt; based wysiwyg Javascript editors in place of &lt;span class="code"&gt;&amp;lt;iframe&amp;gt;&lt;/span&gt; based ones, but as far as I know it's not possible to make one from a plain old &lt;span class="code"&gt;&amp;lt;textarea&amp;gt;&lt;/span&gt;. Sometimes the web development experience feels seriously crippled compared to rich desktop environments and that's not always to do with the limitations of the client/server and statelesss aspects of the platform.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="omg_ponies"&gt;&lt;/a&gt;&lt;h3&gt;10. A pony (file upload)&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;I didn't get my pony. Nobody really addressed this point. I still don't understand why the browser teams can't provide a slicker file upload experience - the web standards aren't really the constraints here; the implementations are just horrible.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="conclusions"&gt;&lt;/a&gt;&lt;h3&gt;Conclusions&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;Here's how I would summarise the status of the main gripes I originally raised:&lt;/p&gt;&#xD;
&#xD;
&lt;table&gt;&#xD;
&lt;tr&gt;&lt;th style="text-align: left;"&gt;Gripe&lt;/th&gt;&lt;th style="text-align: left;"&gt;Status&lt;/th&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;1. Curvy Corners &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#curvy_corners"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#curvy_corners"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No nice solution until CSS3&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;2. Vertical Floats &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#vertical_floats"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#vertical_floats"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No nice solution (good discussion)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;3. Forms &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#form_formatting"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#form_formatting"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No nice solution (good discussion and may be fixed in CSS3)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;4. Floats within Elements &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#floats_within_elements"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#floats_within_elements"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No nice solution (good discussion)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;5. Graphical Buttons &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#graphical_buttons"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#graphical_buttons"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Simple CSS solution (yay!)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;6. Column Support &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#column_support"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#column_support"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No nice solution until CSS3 and some issues even then&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;7. Order Independence &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#order_independence"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#order_independence"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No nice solution&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;8. Widths on inline elements &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#width_on_inline_elements"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#width_on_inline_elements"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Nice solution&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;9. Addressing text in textarea &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#addressing_text"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#addressing_text"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;No solution&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td&gt;10. Ponies (file upload) &lt;a class="noprintlink" href="http://geeklondon.com/blog/view/float_like_a_wasp#omg_ponies"&gt;[Original]&lt;/a&gt; &lt;a class="noprintlink" href="#omg_ponies"&gt;[Redux]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Not really addressed&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;/table&gt;&#xD;
&#xD;
&lt;p&gt;Given the evidence I'd say that most of the complaints I raised were reasonable points, but not all were about CSS as such. Two of them had nice solutions that I'm happy with. I also got some insight into the nature of the problems with CSS (layout versus styling) and learned more about the nice features that aren't yet standard in CSS3. Will they ever be? Who knows.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;To the people who replied in the comment threads and by email: thank you very much. It was a fascinating discussion. As you may have noticed, this blog now has a comment feature enabled - further feedback is welcome there or by email to &lt;a href="mailto:dave@paperstack.com?subject=CSS Redux"&gt;dave@paperstack.com&lt;/a&gt;.&lt;/p&gt;&#xD;
&#xD;
&lt;a name="quotes"&gt;&lt;/a&gt;&lt;h2&gt;Quotes&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;I received quite a bit of direct email and admired the thought that went into many of them. Here are some quotes that I particularly enjoyed (there were lots, these are just my favourites).&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;As always the issue is not what should be possible but what is.&lt;i&gt; - Adam van den Hoven&lt;/i&gt;&lt;/li&gt;&#xD;
&lt;li&gt;[CSS] has always struck me as a poor implementation of a worthwhile ideal.&lt;i&gt; - Stewart Stremler&lt;/i&gt;&lt;/li&gt;&#xD;
&lt;li&gt;CSS is easy if you are a wiZZard and have absolutely zero design skills. &lt;i&gt; - Paul Watson&lt;/i&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;a name="footnotes"&gt;&lt;/a&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;&lt;sup&gt;1.&lt;/sup&gt; It also raised my article to unexpected prominence for UK googlers using the search term "sodding" but I'm hoping the bounce rate is fairly high for them.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;sup&gt;2.&lt;/sup&gt; The one low-quality theme that kept re-occurring was people suggesting "obvious" fixes to CSS problems that required absolute positioning. These all seemed to come from static site designers - for what it's worth, let me reiterate: I build dynamic sites. I can rarely guarantee that the content of an element on the page will remain the same. Since I can't say how much text will be in the element, measures that require me to know the "size" of the element for positioning are completely useless to me. If you don't build dynamic websites, your insights into CSS are not likely to be helpful to those of us who do &lt;i&gt;however useful&lt;/i&gt; they are in your personal circumstances.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;sup&gt;3.&lt;/sup&gt; By positioning hacks I mean absolute positioning, percentage based positioning, pixel based positioning, or anything else that will start to muck up the look of the page if the user does unexpected things to the browser pane, or uses a hand-held device, or does anything else that breaks the author's expectations. For example, a user with visual impairment elects to have a really big font and suddenly that 5em margin on the sides of the page leaves them with something like &lt;a href="http://bootless.net/mouse.html"&gt;the mouse's tale&lt;/a&gt; from Alice.&lt;/p&gt;</content:encoded>
      <pubDate>Wed, 19 Nov 2008 16:27:01 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/godot_is_waiting_for_css3</guid>
      <dc:date>2008-11-19T16:27:01Z</dc:date>
    </item>
    <item>
      <title>Remote Profiling with Eclipse and Java 6</title>
      <link>http://geeklondon.com/blog/view/death-by-acronyms</link>
      <content:encoded>&lt;blockquote&gt;&lt;i&gt;We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.&lt;/i&gt; (Knuth, Donald. &lt;a href="http://portal.acm.org/citation.cfm?id=356640" title="Structured Programming article by Knuth in the ACM journal"&gt;Structured Programming with go to Statements&lt;/a&gt;, ACM Journal Computing Surveys, Vol 6, No. 4, Dec. 1974. p.268.)&lt;/blockquote&gt;&#xD;
&#xD;
&lt;p&gt;The message here is that getting good performance is about picking the right data structures and using &lt;strong&gt;profiling&lt;/strong&gt; tools to locate and fix remaining performance bottlenecks when they occur. I recently encountered just such a bottleneck in my own application and wanted to get to the bottom of it; in order to do so I wanted to attach a remote profiler to my application. Unlike remote debugging, remote profiling is painful to configure for Java and this is compounded by some confusing documentation.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;I am not an expert in the various Java tooling and instrumentation &lt;acronym title="Application Programming Interface"&gt;API&lt;/acronym&gt;s but after hacking my way through to a working profiling environment, I have a general idea of what's what. For now, I just want to get this write up out of my queue so that nobody else has to go through this particular install hell and so that I can get on to the follow-up &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt; article that I've been promising for a few weeks. If you want to correct any mistakes please drop me an email and I'll amend this document accordingly.&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Choosing a profiling application&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;Initially I had planned to buy a profiling tool and use that, but the commercial offerings all suffered from some of the following:&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Required arcane registration processes&lt;/li&gt;&#xD;
&lt;li&gt;Not compatible with Linux&lt;/li&gt;&#xD;
&lt;li&gt;They used evil license management tools&lt;/li&gt;&#xD;
&lt;li&gt;Couldn't run remotely&lt;/li&gt;&#xD;
&lt;li&gt;Didn't support Java 6&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;Bad documentation&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;In view of these problems I decided my time was better invested in getting up to speed with one of the open source tools. &lt;a href="http://eclipse.org/"&gt;Eclipse&lt;/a&gt; is my preferred development environment, so some cursory research suggested that my best option would be to figure out how to use the Eclipse &lt;a href="http://www.eclipse.org/tptp/"&gt;Tracing and Profiling Tools Project&lt;/a&gt; (TPTP) which has all the features that I wanted.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The Eclipse side projects suffer from acronym explosions, most of the discussions seem to take place in mailing lists&lt;sup&gt;&lt;a href="#footnotes"&gt;1&lt;/a&gt;&lt;/sup&gt;, and the documentation is often out of date. Despite this, they are often distinctly superior to commercial solutions particularly when the commercial solutions are lacking in those areas too! So, after thrashing around for a bit, I managed to get things working. It was a combination of Could Do Better and Shows Promise on the report card for Eclipse TPTP today. Better than the commercial tools but still not great. Mind you, it's free software, so complaining is ungracious: don't complain; fix it. Hence my rough and ready walk through to help you out when the existing documentation is perhaps a little vague.&lt;p&gt;&#xD;
&#xD;
&lt;h2&gt;Technology&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;This document does not describe the &lt;i&gt;use&lt;/i&gt; of the Eclipse TPTP project once you have everything configured - the existing documentation for that is pretty good.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;This document does not describe the configuration of Eclipse TPTP for profiling local applications or profiling applications running from within the Eclipse environment. I haven't tried this but as I understand it the configuration is a far simpler matter - trivial even.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The following table summarises the hardware and software that I started out with. I specify the hardware - normally irrelevant for Java development - because the profiling configuration includes components implemented in native code. When I initially tried an install to an underpowered machine with a VIA processor instead of Intel I saw some crashes that I suspect were incompatibilities between the VIA processor and an Intel-specific binary that I was using.&lt;/p&gt;&#xD;
&#xD;
&lt;table style="background: white; border: 1px solid black; border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px;"&gt;&#xD;
&lt;tr&gt;&lt;td colspan="2" style="background: white; text-align: center; font-weight: bold;"&gt;Server&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;Hardware:&lt;/td&gt;&lt;td style="background: white;"&gt;Intel Core 2 Duo CPU E4500 @ 2.20GHz)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;&lt;acronym title="Operating System"&gt;OS&lt;/acronym&gt;:&lt;/td&gt;&lt;td style="background: white;"&gt;Debian Edgy (4.0)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;&lt;acronym title="Java Virtual Machine"&gt;JVM&lt;/acronym&gt;:&lt;/td&gt;&lt;td style="background: white;"&gt;Sun Java SE 1.6.0_06&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;App Server:&lt;/td&gt;&lt;td style="background: white;"&gt;Apache Tomcat/5.5&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td colspan="2" style="background: white; text-align: center; font-weight: bold;"&gt;Client&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;Hardware:&lt;/td&gt;&lt;td style="background: white;"&gt;Intel Pentium M @ 1.60GHz&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;OS:&lt;/td&gt;&lt;td style="background: white;"&gt;Kubuntu Hardy (8.04)&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;JVM:&lt;/td&gt;&lt;td style="background: white;"&gt;Sun Java SE 1.6.0_06&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&lt;td style="background: white; text-align: right;"&gt;&lt;acronym title="Integrated Development Environment"&gt;IDE&lt;/acronym&gt;:&lt;/td&gt;&lt;td style="background: white;"&gt;Eclipse&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;/table&gt;&#xD;
&#xD;
&lt;p&gt;In addition to the existing software, I installed version 4.5.1 of the Agent Controller for Linux on IA32 to the server and the same version (4.5.1) of the TPTP plugins via the Eclipse update manager to my Eclipse client.&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;Background and Concepts&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;So why is the profiling configuration so complex when setting the JVM up for remote debugging is a matter of adding a few command line flags&lt;sup&gt;&lt;a href="#footnotes"&gt;2&lt;/a&gt;&lt;/sup&gt; to the JVM invocation? In this section I'll outline some of the causes of this complexity and list the APIs and components required to carry out profiling with Eclipse TPTP in Java 6.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;Causes of Complexity&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;The old profiling API (&lt;acronym title="Java Virtual Machine Profiling Interface"&gt;JVM PI&lt;/acronym&gt;) and debugging API (&lt;acronym title="Java Virtual Machine Debugging Interface"&gt;JVM DI&lt;/acronym&gt;) were deprecated as of Java 5 and removed as of Java 6. So if you have an old profiling tool you simply can't use it with the latest versions of the JVM. This makes a lot of older documentation misleading.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;With Java 5 the new &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/jpda/architecture.html"&gt;Java Platform Debugger Architecture API&lt;/a&gt; (JPDA) was introduced. The advantage that this has over the older APIs is that it is extensible - plugins can be added to JVMs that support JPDA without requiring intrusive changes to the JVM's implementation. The disadvantage is that by loosening the coupling between the JVM implementation and the instrumentation support a host of new APIs is introduced.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Profiling should not unduly influence the behaviour of the program being profiled - otherwise the developer will optimise their application for the special case of running under the profiler, perhaps missing pathological cases that do not arise in these circumstances. To avoid this problem, the profiler hooks should run as native code rather than running as Java code within the JVM itself - this adds another set of tools to configure; Java developers who are normally insulated from raw operating system differences by the JVM - or an application server environment built upon it - suddenly have to deal with installing native tools and libraries.&#xD;
&#xD;
&lt;h3&gt;JPDA and TPTP&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;The basic technologies involved in our profiling scenario are therefore the standard JPDA APIs and the Eclipse and TPTP specific support hooking into them. On the server side, the TPTP support consists of a native code shared library plugin to the JVM and a server process that communicates with it. On the client side, the TPTP support consists of a Java library to talk to the TPTP server process over &lt;acronym title="Transport Control Protocol/Internet Protocol"&gt;TCP/IP&lt;/acronym&gt; and a set of normal Eclipse plugins that communicate with this library. The relationship between these various components is illustrated in the following figure:&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/TPTP_Arch_600.png" style="margin-left: 5em;" title="The TPTP Architecture for remote Java 6 Profiling from Eclipse"/&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;strong&gt;Native Back End&lt;/strong&gt; is the native code plugin to the JVM that gathers the performance information from the JVM and passes it to the Agent Controller Server. The Native Back End is implemented as a shared library - a &lt;span class="code"&gt;so&lt;/span&gt; file on Unix systems or a &lt;span class="code"&gt;dll&lt;/span&gt; file on Windows systems.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/jvmti/index.html"&gt;Java Virtual Machine Tool Interface&lt;/a&gt; (&lt;strong&gt;JVM TI&lt;/strong&gt;) is the standard API built into the JVM that allows the Native Back End to instrument the JVM and acquire data from it.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;strong&gt;Agent Controller Server&lt;/strong&gt; is a stand-alone process that communicates (usually via shared memory) with the Native Back End. It moves such concerns as managing network connections and marshalling instructions from the profiling client out of the process space of the JVM. This decouples the metric gathering from the other concerns and improves the resilience of the Native Back End (fatal errors in the Agent Controller Server will not normally crash the JVM).&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html"&gt;Java Debug Wire Protocol&lt;/a&gt; &lt;strong&gt;(JDWP)&lt;/strong&gt; is a standard protocol for communicating instructions from clients, such as debuggers and profilers, to their implementations in a JVM. The communications channel used to convey the JDWP commands is not specified, but it is typically TCP/IP and that is the case with the Eclipse TPTP implementation. In principle a client other than Eclipse TPTP could control the Agent Controller client without needing to be specially written for it.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;strong&gt;Front End&lt;/strong&gt; is a Java client application that communicates with the native back end. In this scenario it is an Eclipse TPTP plugin component and communicates with the Agent Controller server over TCP/IP using the JDWP. Its purpose is to provide an implementation of the standard API that profiling and debugging tools use to communicate with the back end.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;a href="http://java.sun.com/javase/6/docs/jdk/api/jpda/jdi/index.html"&gt;Java Debug Interface&lt;/a&gt; &lt;strong&gt;(JDI)&lt;/strong&gt; is the standard API provided by the Front End for use by client profiling and debugging tools.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The &lt;strong&gt;TPTP Client&lt;/strong&gt; shown in the diagram is in fact the suite of graphical Eclipse plugins that hook into the JDI API provided by the Front End. They are somewhat independent of the rest of the configuration as an appropriate Front End implementation would allow them to communicate with profiling implementations from other providers (such as commercial vendors or future standardized parts of the JVM). With a few byzantine configuration tweaks it ought to be possible to persuade the TPTP Client to talk to any other vendor's Front End.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Of these, the standard APIs and protocols are JVM TI, JDWP, and JDI, all of which are part of the JPDA. The Eclipse TPTP components that hook into or provide concrete implementations of them are the Native Back End, the Agent Controller Server, the Front End, and the TPTP Client (in fact this last consists of several Eclipse plugins).&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;The server installation&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;This is essentially a view over my shoulder as I carried out the installation, with some minor extra commentary. &lt;strong&gt;You are expected to understand what my command prompt is, what is the output of the commands issued, and how to adjust the commands issued for your own system's configuration&lt;/strong&gt;. If you're not comfortable with that, then I'm sorry, but you're going to need some help with this - find a colleague or friend who is familiar with Unix and get them to lend a hand. This is not a nice clean automated install process. I wish it was.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;If the remote application that you will be testing doesn't run on Tomcat on a Debian derived Linux (this includes the various Ubuntu projects) then you will have some major changes to make and won't be able to follow the script particularly closely. If it's a Windows platform then you will have a lot of them! Sorry, but again, you're on your own here - however you should definitely skim through this as some of the environment variable that need to be configured are &lt;b&gt;required&lt;/b&gt; and were not conspicuously documented.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;Get the agent controller&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;From the download site&#xD;
&lt;a href="http://www.eclipse.org/tptp/home/downloads/?ver=4.5.1"&gt;http://www.eclipse.org/tptp/home/downloads/?ver=4.5.1&lt;/a&gt; pull down a copy of the Agent Controller runtime for your platform (LINUX-IA32):&#xD;
&lt;a href="http://www.eclipse.org/downloads/download.php?file=/tptp/4.5.1/TPTP-4.5.1/agntctrl.linux_ia32-TPTP-4.5.1.zip" title="Agent Controller runtime for Linux on 32 bit intel processors."&gt;http://www.eclipse.org/downloads/download.php?file=/tptp/4.5.1/TPTP-4.5.1/agntctrl.linux_ia32-TPTP-4.5.1.zip&lt;/a&gt;&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;pre class="terminal" id="terminal_oversize"&gt;&#xD;
dcminter@IS-5285:~$ wget &lt;a href="http://www.mirrorservice.org/sites/download.eclipse.org/eclipseMirror/tptp/4.5.1/TPTP-4.5.1/agntctrl.linux_ia32-TPTP-4.5.1.zip"&gt;http://www.mirrorservice.org/sites/download.eclipse.org/eclipseMirror/tptp/4.5.1/TPTP-4.5.1/agntctrl.linux_ia32-TPTP-4.5.1.zip&lt;/a&gt;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Unpack the Zip to a suitable directory - yes, it's one of those annoying Zip files that has lots of files and directories in the root of the archive instead of stashing everything in a nice versioned subdirectory.&lt;/p&gt;&#xD;
&lt;pre class="terminal"&gt;&#xD;
dcminter@IS-5285:~$ mkdir agntctrl&#xD;
dcminter@IS-5285:~$ cd agntctrl/&#xD;
dcminter@IS-5285:~/agntctrl$ unzip ../agntctrl.linux_ia32-TPTP-4.5.1.zip&#xD;
Archive:  ../agntctrl.linux_ia32-TPTP-4.5.1.zip&#xD;
   creating: Resources/&#xD;
  inflating: Resources/filters.txt&#xD;
  inflating: Resources/jvmpi.pro&#xD;
  inflating: about.html&#xD;
...&#xD;
  lib/libjavaBaseAgent.so -&gt; libjavaBaseAgent.so.4&#xD;
  lib/libhcthread.so     -&gt; libhcthread.so.4&#xD;
  lib/libnamedPipeTL.so.4 -&gt; libnamedPipeTL.so.4.5.0&#xD;
  lib/libtptpClient.so.4 -&gt; libtptpClient.so.4.5.0&#xD;
  lib/libprocessControlUtil.so -&gt; libprocessControlUtil.so.4&#xD;
  lib/libtptpConfig.so.4 -&gt; libtptpConfig.so.4.5.0&#xD;
  lib/libhcbnd.so        -&gt; libhcbnd.so.4&#xD;
  lib/libtptpLogUtils.so.4 -&gt; libtptpLogUtils.so.4.5.0&#xD;
dcminter@IS-5285:~/agntctrl$&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;h3&gt;Configure the agent controller&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;The configuration of the agent controller is specified in the file &lt;span class="code"&gt;config/serviceconfig.xml&lt;/span&gt; relative to the root of the unpacked zip file. You may want to change the port numbers that the agent controller will listen on, but even if you don't you will almost certainly want to change the hosts that are allowed to connect. By default, only local hosts are permitted. For the sake of simplicity I have changed this to "all" in the (abbreviated) configuration file shown, but for a more secure solution&lt;sup&gt;&lt;a href="#footnotes"&gt;3&lt;/a&gt;&lt;/sup&gt; you should use specific host names or IP addresses instead.&#xD;
&lt;pre class="terminal"&gt;&#xD;
&amp;lt;AgentControllerConfiguration&amp;gt;&#xD;
...&#xD;
        &amp;lt;Connection&amp;gt;&#xD;
...&#xD;
                &amp;lt;TransportLayer loadlib="tptpCCTL" type="TPTP_CCTL"&amp;gt;&#xD;
                        &amp;lt;Configuration&amp;gt;&#xD;
                                &amp;lt;!-- OPTIONALLY CHANGE THESE PORTS! --&amp;gt;&#xD;
                                &amp;lt;Port&amp;gt;10002&amp;lt;/Port&amp;gt;&#xD;
                                &amp;lt;SecuredPort&amp;gt;10003&amp;lt;/SecuredPort&amp;gt;&#xD;
                                &amp;lt;FilePort&amp;gt;10005&amp;lt;/FilePort&amp;gt;&#xD;
                                &amp;lt;IsDataMultiplexed&amp;gt;false&amp;lt;/IsDataMultiplexed&amp;gt;&#xD;
                                &amp;lt;ProcessPolling&amp;gt;true&amp;lt;/ProcessPolling&amp;gt;&#xD;
                                &amp;lt;Version&amp;gt;4.4.1&amp;lt;/Version&amp;gt;&#xD;
                                &amp;lt;SecurityEnabled&amp;gt;false&amp;lt;/SecurityEnabled&amp;gt;&#xD;
                                &amp;lt;Hosts configuration="default"&amp;gt;&#xD;
                                        &amp;lt;!-- Changed from "LOCAL" to "ALL" : -- &amp;gt;&#xD;
                                        &lt;b&gt;&amp;lt;Allow host="ALL"/&amp;gt;&lt;/b&gt;&#xD;
                                &amp;lt;/Hosts&amp;gt;&#xD;
                        &amp;lt;/Configuration&amp;gt;&#xD;
...&#xD;
                &amp;lt;/TransportLayer&amp;gt;&#xD;
...&#xD;
        &amp;lt;/Connection&amp;gt;&#xD;
...&#xD;
&amp;lt;/AgentControllerConfiguration&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;With the appropriate configuration file you might expect to be able to start the client, but it turns out that it has a dependency upon a specific libc version as the error in the following attempt to start it shows:&lt;/p&gt;&#xD;
&lt;pre class="terminal" id="terminal_oversize"&gt;&#xD;
dcminter@IS-5285:~/agntctrl/bin$ ./RAStart.sh&#xD;
Starting Agent Controller.&#xD;
ACServer: &lt;b&gt;error while loading shared libraries: libstdc++-libc6.2-2.so.3:&lt;/b&gt; cannot open shared object file: No such file or directory&#xD;
ACServer started successfully. &lt;i class="note"&gt;This is a lie!&lt;/i&gt;&#xD;
dcminter@IS-5285:~$&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;D'oh! So, we need to install the library. You can't easily install just this shared library, but you can pull in a specific glibc version that seems to supply it as a dependency. I'm not completely sure if this is a sensible solution, but it does work. The origin of this tip is &lt;a href="http://ubuntuforums.org/archive/index.php/t-1879.html"&gt;http://ubuntuforums.org/archive/index.php/t-1879.html&lt;/a&gt;)&#xD;
&lt;pre class="terminal"&gt;&#xD;
dcminter@IS-5285:~$ sudo apt-get install libstdc++2.10-glibc2.2&#xD;
Password:&#xD;
Reading package lists... Done&#xD;
Building dependency tree... Done&#xD;
The following NEW packages will be installed&#xD;
  libstdc++2.10-glibc2.2&#xD;
0 upgraded, 1 newly installed, 0 to remove and 16 not upgraded.&#xD;
Need to get 330kB of archives.&#xD;
After unpacking 1356kB of additional disk space will be used.&#xD;
Get: 1 http://ftp.uk.debian.org etch/main libstdc++2.10-glibc2.2 1:2.95.4-27 [330kB]&#xD;
Fetched 330kB in 0s (5685kB/s)&#xD;
Selecting previously deselected package libstdc++2.10-glibc2.2.&#xD;
(Reading database ... 19093 files and directories currently installed.)&#xD;
Unpacking libstdc++2.10-glibc2.2 (from .../libstdc++2.10-glibc2.2_1%3a2.95.4-27_i386.deb) ...&#xD;
Setting up libstdc++2.10-glibc2.2 (2.95.4-27) ...&#xD;
&#xD;
dcminter@IS-5285:~$&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;...and now you should get a clean start:&lt;/p&gt;&#xD;
&lt;pre class="terminal"&gt;&#xD;
dcminter@IS-5285:~/agntctrl/lib$ cd ..&#xD;
dcminter@IS-5285:~/agntctrl$ cd bin&#xD;
dcminter@IS-5285:~/agntctrl/bin$ ./RAStart.sh&#xD;
Starting Agent Controller.&#xD;
Creating default Agent Controller configuration file.&#xD;
Security is turned off.  Access is set to Local.&#xD;
Run the SetConfig script to change the default settings.&#xD;
&lt;b&gt;ACServer started successfully.&lt;/b&gt; &lt;i class="note"&gt;This time it's not a lie!&lt;/i&gt;&#xD;
dcminter@IS-5285:~/agntctrl/bin$&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Check your process list to make sure that it really started up and didn't fail silently for some reason:&lt;/p&gt;&#xD;
&lt;pre class="terminal"&gt;&#xD;
dcminter@IS-5285:~/agntctrl/bin$ ps -Af&#xD;
UID        PID  PPID  C STIME TTY          TIME CMD&#xD;
...&#xD;
dcminter  6143     1  0 00:00 pts/1    00:00:00 &lt;b&gt;ACServer&lt;/b&gt;&#xD;
dcminter  6174  6143  0 00:00 pts/1    00:00:00 &lt;b&gt;/home/dcminter/agntctrl/bin/tptpProcessController&lt;/b&gt;&#xD;
...&#xD;
dcminter@IS-5285:~/agntctrl/bin$&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;h3&gt;Configure Tomcat to run with the agent controller&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;Now you need to edit Tomcat's configuration to allow the JVM to talk to the agent controller. Fire up your preferred editor and for Edgy you can make changes to the &lt;span class="code"&gt;/etc/default/tomcat5.5&lt;/span&gt; configuration file to make a system-wide change to Tomcat's environment.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Amend the &lt;span class="code"&gt;CATALINA_OPTS&lt;/span&gt; environment variable to load the Native Back End (known here as the &lt;acronym title="Java Profiling Interface"&gt;JPI&lt;/acronym&gt; agent) by adding the following flag: &lt;span class="code"&gt;-agentlib:JPIBootLoader=JPIAgent:server=enabled;CGProf&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;In my configuration I have headless mode set, a 256M PermSize (to avoid PermGen errors after numerous webapp reloads - a memory leak but a fairly benign one), and a 512M heap, so the resulting configuration line reads:&lt;/p&gt;&#xD;
&lt;pre class="terminal" id="terminal_oversize"&gt;&#xD;
CATALINA_OPTS="-Djava.awt.headless=true -XX:MaxPermSize=256m -Xmx512M &lt;b&gt;-agentlib:JPIBootLoader=JPIAgent:server=enabled;CGProf&lt;/b&gt;"&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Add also the following entries to locate and configure various libraries needed by the JPIAgent. &lt;strong style="color: red;"&gt;This is probably the missing step for a lot of people&lt;/strong&gt; because it's required but doesn't seem to be in the Eclipse documentation. I found it lurking in a mailing list discussion.&lt;/p&gt;&#xD;
&lt;pre class="terminal"&gt;&#xD;
&lt;i&gt;# Make the native code TPTP libraries available to Tomcat&lt;/i&gt;&#xD;
export LD_LIBRARY_PATH=/home/dcminter/agntctrl/lib:/home/dcminter/agntctrl/plugins/org.eclipse.tptp.javaprofiler/&#xD;
&#xD;
&lt;i&gt;# Specify a directory for logging output. This IS required - I write it &#xD;
# to the normal Tomcat log directory on Edgy. Martini is an Eclipse technology name.&lt;/i&gt;&#xD;
export MARTINI_LOGGER_DIRECTORY=/var/log/tomcat5.5&#xD;
&#xD;
&lt;i&gt;# But unless I'm trying to debug the configuration I turn off most profiler debugging output.&lt;/i&gt;&#xD;
export MARTINI_LOGGER_LOG_LEVEL=0&#xD;
&#xD;
&lt;i&gt;# Make the Java code TPTP libraries available to the profiler backend&lt;/i&gt;&#xD;
export JAVA_PROFILER_HOME=/home/dcminter/agntctrl/plugins/org.eclipse.tptp.javaprofiler&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;As always, note that &lt;span class="code"&gt;/home/dcminter&lt;/span&gt; should be replaced with your real install directory. This may be your own home directory (in which case &lt;span class="code"&gt;$HOME&lt;/span&gt; can generally be used) or perhaps somewhere below &lt;span class="code"&gt;/usr/share&lt;/span&gt; or &lt;span class="code"&gt;/opt&lt;/span&gt; that will be accessible to multiple users on a shared machine.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Restart Tomcat to re-read the settings from the default config.&lt;/p&gt;&#xD;
&lt;pre class="terminal"&gt;&#xD;
dcminter@IS-5285:~/agntctrl/bin$ sudo /etc/init.d/tomcat5.5 stop&#xD;
Password:&#xD;
Stopping Tomcat servlet engine: tomcat5.5 . . . .&#xD;
dcminter@IS-5285:~/agntctrl/bin$ sudo /etc/init.d/tomcat5.5 start&#xD;
Starting Tomcat servlet engine: tomcat5.5.&#xD;
dcminter@IS-5285:~/agntctrl/bin$&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;That's all for the server-side components; at this point you should be able to connect once you have configured the Eclipse TPTP client machine.&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;The TPTP Profiler Client&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;The client installation process is a great deal simpler than that for the server. &#xD;
&#xD;
&lt;h3&gt;Installing the client&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;Load the workbench project for the application that you wish to debug. You will then need to go to the &lt;b&gt;Software Updates/Find and Install&lt;/b&gt; dialog on the Eclipse's Help menu. Select &lt;b&gt;Search for new features to install&lt;/b&gt; and then click the &lt;b&gt;New Remote Site&lt;/b&gt; button. Add a &lt;b&gt;Test and Performance Tools Platform (TPTP) Updates&lt;/b&gt; site with URL &lt;a href="http://eclipse.org/tptp/updates/"&gt;http://eclipse.org/tptp/updates/&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Check the resulting entry in the list of update sites and click the finish button. You will be presented with a list of components to install (possibly after clicking through a few dialogs). I'm hazy about the exact meaning of the various component names, but I have the following:&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;TPTP Monitoring Tools Project&lt;/li&gt;&#xD;
&lt;li&gt;TPTP Platform Project&lt;/li&gt;&#xD;
&lt;li&gt;TPTP Profiling for Web Applications&lt;/li&gt;&#xD;
&lt;li&gt;TPTP Reporting with BIRT&lt;/li&gt;&#xD;
&lt;li&gt;TPTP Testing Tools Project&lt;/li&gt;&#xD;
&lt;li&gt;TPTP Tracing and Profiling Tools Project&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;It's also possible to download and install the components manually from the website but I don't normally do this. Even without adding components manually, the petulant update manager seems to encounter lots of dependency problems - but that's a rant for another time.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;Configuring the client&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;&lt;i&gt;Since this part will be somewhat unfamiliar I'll provide it as a screenshot walkthrough, but probably this is overkill - the configuration process is very simple as long as the agent controller server has been correctly configured.&lt;/i&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Once the TPTP tools have been installed you should see the profiler icon on the Eclipse workbench toolbar.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profiler_tool_button.png" title="The Profile tool icon (circled)" title="*** TODO ***"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;Right click the icon, and from the resulting context menu select the Open Profile Dialog option.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_menu_1.png" title="The profile tool context menu"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;You should now see the profile launch-configuration dialog shown below. This provides options for connection to various server types - although it is possible to set up connections to servers where Eclipse is managing the server deployment process, my assumption is that like me you are connecting to a completely "external" server such as a production environment.&lt;/p&gt;&#xD;
&lt;p&gt;Right click on the Attach To Agent option from the list on the left and select "New" from the popup context menu.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_1.png" title="The profile launch-configuration dialog"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;This will create a new set of named profiler configuration parameters. The details will be displayed on the right hand side with a name such as "New_configuration" at the top. To change this name edit the text at the top of the page and select apply.&lt;/p&gt;&#xD;
&lt;p&gt;By default the configuration parameters assume that you will be connecting to a profiling agent on the local machine (localhost) on port 10002. This cannot be removed, but remote hosts can be added to the list of places that agents can be found. Select the Add button to do so.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_2.png" title="The default launch-configuration"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;Selecting the Add button pops up a dialog (shown below) prompting for a server name and port. Put in the connection details of the server running the agent controller - the port is the one specified in the value of the &lt;span class="code"&gt;Port&lt;/span&gt; element from the &lt;span class=""&gt;serviceconfig.xml&lt;/span&gt; file - unless changed it will be port 10002.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_add_host_1.png" title="Adding a profiling host"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;Once you click OK you should be returned to the profile dialog with the new server's details in the list.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_3.png" title="The populated list of hosts"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;Select the newly created connection details and click the Test Connection button. If the agent controller is correctly configured and running on the remote server you should see the dialog below confirming that a connection was successfully established to the listening agent controller.&lt;/p&gt;&#xD;
&lt;p&gt;If for some reason the configuration test cannot connect to the agent controller an error message will appear with some limited explanatory text. If this is the case, check the connectivity to the server (including any firewall/port settings and other network infrastructure) and that the agent controller is correctly configured.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_connection_ok_1.png" title="The successful test confirmation dialog"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;Once you have a successful connection to the agent controller, switch to the Agents tab (shown below) to select the items that will be profiled. Press F5 to refresh the list if the list has not yet been populated (the details of the available agents are retrieved by Eclipse from the remote server).&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_agents_1.png" title="Configuring profiling agents"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;Drill down the list of available profiling agents and select any and all that are of interest - in our case we have only configured the Call Graph agent, so only one option is listed. Others such as the heap profiler (to check for memory leaks) can be added during the server configuration.&lt;/p&gt;&#xD;
&lt;div&gt;&lt;img style="margin-left: 5em;" src="/images/profiling/eclipse_profile_dialog_agents_2.png" title="Selecting profiling agents to launch"/&gt;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;With the specific agent(s) selected you have completed the necessary details of the launch configuration and should apply all the changes. Click the "Profile" button and off you go!&lt;/p&gt;&#xD;
&#xD;
&lt;h2&gt;&lt;a name="footnotes"&gt;Footnotes.&lt;/a&gt;&lt;/h2&gt;&#xD;
&#xD;
&lt;p&gt;&lt;sup&gt;1.&lt;/sup&gt; I &lt;strong&gt;hate&lt;/strong&gt; mailing lists. Email in my opinion is the wrong tool for this sort of thing. It should be managed using &lt;acronym title="Network News Transport Protocol"&gt;NNTP&lt;/acronym&gt; or forum software. Just my personal gripe, but searching online-archived mailing lists for archived conversations usually makes me want to pluck my eyes out.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;sup&gt;2.&lt;/sup&gt; Search engines being what they are, I think it's only right to supply the debug flags just in case you got here looking for that and don't give a fig about profiling. For a typical Tomcat server, running on the default port of 4142 you would add the following to the &lt;span class="code"&gt;CATALINA_OPTS&lt;/span&gt; environment variable:&lt;/p&gt;&#xD;
&lt;pre class="terminal"&gt;&#xD;
-Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4142,suspend=n &#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;sup&gt;3.&lt;/sup&gt; For a truly secure solution you would want to configure the agent controller and client to use SSL and certificate exchange, but I haven't investigated that as yet so you're on your own there!&lt;/p&gt;</content:encoded>
      <pubDate>Tue, 14 Oct 2008 17:27:28 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/death-by-acronyms</guid>
      <dc:date>2008-10-14T17:27:28Z</dc:date>
    </item>
    <item>
      <title>Framing the question</title>
      <link>http://geeklondon.com/blog/view/not-invented-heretics</link>
      <content:encoded>&lt;blockquote&gt;&#xD;
&lt;i&gt;Coming soon, honestly, thoughts and reflections upon the excellent feedback from the CSS article. It was all much more thoughtful than the all-out flamewar I was expecting!&lt;/i&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&#xD;
&lt;p&gt;Recent discussion on the &lt;a href="http://forums.sun.com/"&gt;Java Forums&lt;/a&gt; about the &lt;a href="http://hibernate.org/"&gt;Hibernate&lt;/a&gt; framework got me thinking about attitudes to frameworks in general.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;The right way to use a new framework:&lt;/h3&gt;&#xD;
&#xD;
&lt;ol&gt;&#xD;
   &lt;li&gt;Already know underlying techologies.&lt;/li&gt;&#xD;
   &lt;li&gt;Read the feature list and confirm that it provides benefit to your project.&lt;/li&gt;&#xD;
   &lt;li&gt;Read the documentation in detail.&lt;/li&gt;&#xD;
   &lt;li&gt;Build your application.&lt;/li&gt;&#xD;
   &lt;li&gt;Profile your application.&lt;/li&gt;&#xD;
   &lt;li&gt;Analyse and fix problems arising in use of the framework.&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&#xD;
&lt;p&gt;If you don't know the underlying technologies properly you won't be able to fix problems resulting from the &lt;a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;Law of Leaky Abstractions&lt;/a&gt;. For example, if you don't know &lt;abbrev title="Structured Query Language"&gt;SQL&lt;/abbrev&gt; you won't be able to diagnose the annoying cases when a badly phrased &lt;abbrev title="Hibernate Query Language"&gt;HQL&lt;/abbrev&gt; query slips through the parser and generates syntactically invalid SQL.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Know the features. This ought to be obvious but it does happen that people elect to use a tool because they've &lt;i&gt;assumed&lt;/i&gt; that it has some particular feature.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Read the documentation. You can't wield a framework properly unless you know how it's supposed to work. For example if you're trying to use Hibernate and you don't know the meaning of association directionality, cascade rules, or about the existence of the action queue, you are going to cause all manner of havoc.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Once you have built an application it will, typically, contain a few performance glitches. The right way to fix these is to profile the application, find out where they are, and address them. The wrong way is to hypothesize a rationale ("Hibernate is crap") make a fix ("replace it with straight JDBC") and then find you still have the problem ("Hibernate made our code slow even when we removed it !")&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Frameworks do have bugs in them sometimes. If you're using the framework in an unusual way, or more extensively than is usual, you might brush up against some of its limitations. If you do so, find and fix them. It's rarely as difficult as you might expect and it's almost always better to do this than try and create equivalent code from scratch while building in your own unique set of limitations.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;The wrong way to use a new framework:&lt;/h3&gt;&#xD;
&#xD;
&lt;ol&gt;&#xD;
   &lt;li&gt;Decide that it can save you from learning the underlying technologies.&lt;/li&gt;&#xD;
   &lt;li&gt;Build your application.&lt;/li&gt;&#xD;
   &lt;li&gt;Be baffled when behaviour and performance are erratic.&lt;/li&gt;&#xD;
   &lt;li&gt;Badmouth the framework.&lt;/li&gt;&#xD;
   &lt;li&gt;(Optional) Castigate anyone who likes the framework.&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&#xD;
&lt;p&gt;Frameworks can't substitute for knowledge. Hibernate is not a replacement for understanding JDBC and SQL.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;If you haven't understood the tools you were using to build your application, and if you don't use profiling to investigate any unanticipated performance problems, your problems can be fairly and squarely blamed on your own complacency, not the choice of framework.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Slagging off the framework as the cause of all your problems merely highlights your own incompetence to those who have had success with the same system. It's not a great idea to advertise that you're a bad workman.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Some people, especially those who read an enthusiastic review on one of the skimpier "technical" sites flip from evangelist to zealous enemy as soon as they're bitten by their over confidence. On the basis that the friend of my enemy is my enemy they'll attack anyone who supports the tools they despise. This is a useful trait because it makes them easy to spot for exclusion from your team.&lt;/p&gt;&#xD;
&#xD;
&lt;h3&gt;In summary:&lt;/h3&gt;&#xD;
&#xD;
&lt;p&gt;Coding the tools from scratch is almost always more fun. Using someone else's system is often frustrating because you have to adopt their design philosophy when interacting with their framework. Nonetheless the &lt;abbrev title="Not Invented Here"&gt;NIH&lt;/abbrev&gt; attitude has proven time and time again to be the downfall of projects. Professionals use frameworks instead of coding from scratch. Remember not to whine too much when the bastard thing gives you a class cast exception for reasons that are an affront to humanity.&lt;/p&gt;</content:encoded>
      <pubDate>Mon, 06 Oct 2008 15:11:40 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/not-invented-heretics</guid>
      <dc:date>2008-10-06T15:11:40Z</dc:date>
    </item>
    <item>
      <title>What's in a name?</title>
      <link>http://geeklondon.com/blog/view/gnus-not-linux</link>
      <content:encoded>&lt;p&gt;I hereby propose that the &lt;a href="http://www.fsf.org/"&gt;FSF&lt;/a&gt; stop the &lt;a href="http://www.gnu.org/gnu/why-gnu-linux.html"&gt;petty naming argument&lt;/a&gt; and just give in to the linguistic inevitability of calling operating system platforms built upon the &lt;a href="http://en.wikipedia.org/wiki/Linux_kernel"&gt;Linux kernel&lt;/a&gt; "Linux" instead of demanding that we call them "GNU/Linux". I for one have a lot of &#xD;
&lt;a href="http://www.opensource.org/licenses/mit-license.php"&gt;MIT&lt;/a&gt;, &#xD;
&lt;a href="http://www.apache.org/licenses/"&gt;Apache&lt;/a&gt;, and&#xD;
&lt;a href="http://www.opensource.org/licenses/bsd-license.php"&gt;BSD&lt;/a&gt; licensed software on my machine, as well as a bunch of proprietary stuff that is decidedly not "GNU" software.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;The gamut is know as Linux because that's the luck of the draw. &lt;a href="http://en.wikipedia.org/wiki/Linus_Torvalds"&gt;Linus Torvalds&lt;/a&gt; created the first successful free unix-like kernel and so the operating systems based upon that became known as Linux. People using GNU tools on Solaris don't call it "GNU/Solaris". People (like me) using commercial Java tools on Linux don't call it "Java/Linux" for much the same reason.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;So, to the vote Let's have a look at the list of &lt;a href="http://en.wikipedia.org/wiki/Linux_distribution#Popular_distributions"&gt;popular distributions&lt;/a&gt; (whether you want to call them Linux or GNU/Linux) listed in the Wikipedia currently:&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://www.archlinux.org/"&gt;ArchLinux&lt;/a&gt;, &#xD;
   &lt;a href="http://www.centos.org/"&gt;CentOS&lt;/a&gt;,&#xD;
   &lt;a href="http://www.debian.org/"&gt;Debian&lt;/a&gt;,&#xD;
   &lt;a href="http://fedoraproject.org/"&gt;Fedora&lt;/a&gt;, &#xD;
   &lt;a href="http://www.gentoo.org/"&gt;Gentoo&lt;/a&gt;, &#xD;
   &lt;a href="http://www.knoppix.org/"&gt;Knoppix&lt;/a&gt;, &#xD;
   &lt;a href="http://www.mandriva.com/"&gt;Mandriva&lt;/a&gt;, &#xD;
   &lt;a href="http://www.pclinuxos.com/"&gt;PCLinuxOS&lt;/a&gt;, &#xD;
   &lt;a href="http://www.redhat.com/"&gt;Red Hat Enterprise Linux&lt;/a&gt;, &#xD;
   &lt;a href="http://www.slackware.com/"&gt;Slackware&lt;/a&gt;, &#xD;
   &lt;a href="http://www.novell.com/linux/"&gt;SUSE&lt;/a&gt;, &#xD;
   &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;So what do they call themselves?&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
 &lt;li&gt;ArchLinux - &lt;i&gt;a lightweight and flexible &lt;b&gt;Linux&lt;/b&gt; distribution&lt;/a&gt;&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;CentOS - &lt;i&gt;an Enterprise-class &lt;b&gt;Linux&lt;/b&gt; Distribution&lt;/a&gt;&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Debian - &lt;i&gt;uses the Linux kernel (the core of an operating system), but most of the basic OS tools come from the GNU project; hence the name GNU/Linux&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Fedora - &lt;i&gt;a &lt;b&gt;Linux&lt;/b&gt;-based operating system&lt;/a&gt;&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Gentoo - &lt;i&gt;a special flavor of &lt;b&gt;Linux&lt;/b&gt;&lt;/a&gt;&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Knoppix - &lt;i&gt;eine komplett von CD oder DVD lauffähige Zusammenstellung von GNU/Linux&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Mandriva - &lt;i&gt;The &lt;b&gt;Linux&lt;/b&gt; desktop that's easy to try and easy to keep"&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;PCLinuxOS - &lt;i&gt;a free, easy-to-use &lt;b&gt;Linux&lt;/b&gt;-based operating system&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Red Hat Enterprise &lt;b&gt;Linux&lt;/b&gt; (they are no more specific than in the name)&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Slackware - &lt;i&gt;the Slackware &lt;b&gt;Linux&lt;/b&gt; distribution&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;SUSE - &lt;i&gt;this enterprise grade &lt;b&gt;Linux&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&#xD;
 &lt;li&gt;Ubuntu - &lt;i&gt;a community developed, &lt;b&gt;Linux&lt;/b&gt;-based operating system&lt;/i&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;Votes in favour: 10&lt;/p&gt;&#xD;
&lt;p&gt;Votes against: 2&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;b&gt;Motion carried.&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Language is a juggernaut. Step in its way and you'll be crushed utterly - far better to go with the flow. Stallman and the FSF can be proud of creating the environment that allowed Linux to flourish; trying to change the name to garner a bit more praise is futile and unattractive.&lt;/p&gt;</content:encoded>
      <pubDate>Tue, 02 Sep 2008 15:52:59 GMT</pubDate>
      <guid>http://geeklondon.com/blog/view/gnus-not-linux</guid>
      <dc:date>2008-09-02T15:52:59Z</dc:date>
    </item>
  </channel>
</rss>

