October 2003

« September 2003 | Main Index | Archives | November 2003 »

30
Oct

The Hacker Emblem is a black-and-white rendition of the ‘glider’ from Conway's Life, with black circles in a 3x3 board Well, I first saw it on Slashdot, but it's been popping up elsewhere. Eric 'ESR' Raymonds wants hackers to have their own emblem.

  1. It's dull. It's just a bunch of black blobs on a tic-tac-toe board. Who would want to identify with that?
  2. It's a static representation of something that only has meaning when it is animated.
  3. It's ambiguous. "Why have you got that picture of the checquers board again?"
  4. It's from ESR. If Thinkgeek came out with an “Eric Raymonds Does Not Speak for Me!” t-shirt, I'd buy it immediately.
  5. It captures nothing about what it means to be a hacker. Worse, its drab nature captures every misconception we'd rather get away from. It's the logo equivalent of "You sit in front of a screen all day typing? And you enjoy it?"
  6. Notably, it even fails to capture the one thing that every widely-adopted hacker-created logo has in common: an amused disrespect for the concept of the logo. (Think of Tux the Penguin, the BSD Daemon, SSH blowfish...)
  7. It's an attempt to impose culture from above. If one claims to be an historian, one should observe and record history, not be so presumptious as to try to write one's own role in it.

Over the weekend, I did PragDave's Kata 19: Word Chains. I like the kata. After spending most of my day dealing with framework this, architecture that and library the other, it's nice to dive down and deal with something small and concrete.

There’s a type of puzzle where the challenge is to build a chain of words, starting with one particular word and ending with another. Successive entries in the chain must all be real words, and each can differ from the previous word by just one letter... The objective of this kata is to write a program that accepts start and end words and, using words from the dictionary, builds a word chain between them. For added programming fun, return the shortest word chain that solves each puzzle.

I highly recommend you pull out your language-of-choice and play around with this problem yourself. The idea of the exercise is to do, after all, rather than to read how someone else did it.

I did the kata in Ruby, because that seems to be my spare-time language of choice these days. I finally ended up with this little library. You can use it like this:

load "kata19-cm.rb"
dict = Dictionary.load(4)
from, to = dict.find_word("ruby"), dict.find_word("gold")
puts dict.find_path(from, to).join(" -> ")

And it will print out this:

ruby -> rubs -> cubs -> cues -> cued -> coed -> cold -> gold

If you're feeling more complicated, you could do this:

load "kata19-cm.rb"
dict = Dictionary.load(4)
dict.calculate_all_paths(dict.find_word("ruby"))
longest_word = nil
touched = 0
dict.each_word do |word|
    longest_word = word if 
       !longest_word or 
       longest_word.fwd_path.length < word.fwd_path.length
   touched += 1 if word.fwd_path.length != 0
end
puts "longest 'shortest path' from ruby is %d words, e.g. %s" %
    [longest_word.fwd_path.length, longest_word.fwd_path.join(" -> ")]
puts "there are %d words reachable from ruby" % (touched - 1)

Which prints out1:

longest 'shortest path' from ruby is 13 words, e.g. 
  ruby -> rubs -> dubs -> dues -> dyes -> ayes -> aces -> 
  ices -> ires -> Ares -> Ames -> Amos -> Abos
there are 1915 words reachable from ruby

The search is pretty simple: the trick is to stop thinking of them as words, and just deal with it as a shortest-path problem for a graph. The word to word search is breadth-first, starting at both ends and working towards the middle until they meet (or run out of places to go). For the calculation of every path from a single word, it's an exhaustive breadth-first search.

The problem is that in this form, it takes bloody ages. The graph-traversal part happens in 0.01s, but it takes several seconds to build the graph from the word-list. There are several ways this could be done faster (see here for some ruminations on that subject in Python by Ian Bicking), but in the end, I decided not to bother with any of them. From reading Ian's notes this turned out to be a good decision: it looks like it took a long time to optimize, and the attempt topped out at 3.5s.

Instead, I just pre-compiled the dictionaries for the word-lengths I needed.

dict = Dictionary.load(4)
File.open("dictionary-4.dump", "w+") do |f|
    Marshal.dump(dict, f)
end

It takes about 0.35s to un-marshall the dictionary from disk, then you're ready to rumble.

dict = nil
File.open("dictionary-4.dump") do |f|
    dict = Marshal.load(f)
end

I think the moral of the story here is that optimization is sometimes the judicious application of brute force. Identify those things you only ever have to do once, do them once, and don't bother optimising them further. The time you spend running the un-optimised code once is probably far less than the time you'd spend trying to get it to run faster.

1 The dictionary is deliberately case-sensitive: 'a' and 'A' are considered to be different letters.

The other day I had to mess around with struts-menu. struts-menu is a neat little Struts plugin that draws drop-down Javascript menus on web pages. It's been quite useful thankyou very much, if a little sparsely documented.

I needed to make certain menu options disappear based on who was logged in. There's some example code for menu permissions provided with the struts-menu download. Matt Raible has a demo of it online. I couldn't find anything that vaguely resembled task-focused documentation, though.

Eventually, I worked out how it's done. Mostly by reading the source-code. Hence this write-up. I hope Google will make sure the next person with the same problem finds their way here, so they don't have to repeat the mild discomfort I had to go through to gather this information.

Goal

To limit access to particular menu items based on the application's security configuration.

Background: PermissionsAdapter

Checking the Javadoc, you'll find the PermissionsAdapter Interface. This interface has one method: "isAllowed(MenuComponent)" that is called for each menu and menu item when the menu is being drawn. If it returns true, the item is drawn, if it returns false, the item is not drawn. (Some menu implementations may draw, but disable disallowed menu items)

struts-menu comes with a single concrete implementation of the PermissionsAdapter, called RolesPermissionsAdapter. This adapter maps the user's security roles as defined in the application/appserver configuration against a list of permitted roles defined for each menu/menu item in menu-config.xml

Step 0: Define your roles

This is part of your general J2EE/JAAS/etc security configuration. Each user or group will be allocated roles. Those roles are mapped to role definitions in the application's configuration. It's a very good idea to sit down at a whiteboard with your use cases and map out what the various roles are and what they're allowed to do before implementing anything.

Step 1: Define a PermissionsAdapter for the menu

The JSP tag you use to display the menu, <menu:useMenuDisplayer/> has an optional property: "permissions". If this property is present, it's used as the key with which to look up an instance of PermissionsAdapter in the application/request/session/page scope. It will then apply that adapter to the menu.

There is, however, a "magic" value for this property, "rolesAdapter". This magic value tells the menu displayer that instead of looking for an adapter in scope, it should instead create a new instance of RolesPermissionsAdapter and use that instead.

So, step 1 is to go through all your invocations of <menu:useMenuDisplayer/> and add permissions="rolesAdapter" to the tag.

Step 2: Map roles to menu items in menu-config.xml

The <Menu/> and <Item> tags in your menu configuration file (which is variable, but I shall refer to as menu-config.xml) have an optional "roles" attribute. This attribute, when used in conjunction with the RolesPermissionsAdapter, is a space-separated list of all the roles that will be permitted to use a particular menu or menu-item.

RolesPermissionsAdapter works by splitting the list, and calling request.isUserInRole() for each one. If any of them come back true, the menu or menu item is displayed.

So, for the following menu item definitions:

<Menu name="PrefsMenu" title="Preferences" roles="User">
    <Item name="UserPrefs" title="User Preferences" page="prefs.do"/>
    <Item name="ModPrefs" title="Moderator Preferences"
             page="modPrefs.do" roles="Moderator System"/>
    <Item name="AdminPrefs" title="Site Preferences"
             page="sitePrefs.do" roles="System"/>
</Menu>

The menu is visible to anyone in the User role, who then get access to User Preferences automatically. Anyone in the System or Moderator roles can access the moderator preferences, but the site preferences are limited only to System-level users.

Of course, this doesn't prevent people accessing the page in ways other than using the menu, but it's polite not to present people with options that you know they can't take advantage of.

Anyway, I hope this is of some use to someone other than me.

class.class

  • 11:45 AM

A while back, I wanted to demonstrate to somebody on a mailing-list that the restrictions of the Java programming language and those of the Java Virtual Machine were not the same thing. Namely, that reserved keywords in the Java language are not reserved by the JVM.

Hence: class.class is a Java class called, well, 'class'. It has a main method, so if you put it in a directory and run 'java class', it'll instantiate an instance of itself and print out that instance's getClass().getName().

I could have used a fancy Java assembler, but an existing class and a hex-editor was quicker. :)

Epiphany:~ cmiller$ java class
this object's class is: class


Epiphany:~ cmiller$ javap -c class
Compiled from Class.java
public class class extends java.lang.Object {
    public class();
    public static void main(java.lang.String[]);
}

Method class()
   0 aload_0
   1 invokespecial #9 <Method java.lang.Object()>
   4 return

Method void main(java.lang.String[])
   0 new #2 <Class class>
   3 dup
   4 invokespecial #16 <Method class()>
   7 astore_1
   8 getstatic #22 <Field java.io.PrintStream out>
  11 new #24 <Class java.lang.StringBuffer>
  14 dup
  15 ldc #26 <String "this object's class is: ">
  17 invokespecial #29 <Method 
       java.lang.StringBuffer(java.lang.String)>
  20 aload_1
  21 invokevirtual #33 <Method java.lang.Class getClass()>
  24 invokevirtual #39 <Method java.lang.String getName()>
  27 invokevirtual #43 <Method 
       java.lang.StringBuffer append(java.lang.String)>
  30 invokevirtual #46 <Method java.lang.String toString()>
  33 invokevirtual #51 <Method void println(java.lang.String)>
  36 return

Have I mentioned recently that Redhat sucks?

A while back, I had a problem with Redhat, whereby RPM wasn't warning me that a particular upgrade would render my whole system unbootable. Today, I got this official Redhat reply to the bug report I submitted on the subject:

Because Unix always gives the sysadmin enough rope to shoot him/herself. If you administrate a system you are supposed to know what you do.

Ignoring for a moment, the disgusting word 'administrate' (what's wrong with 'administer'?), I would like to draw attention to the concept of the "package manager". The package manager is the reason we use modern Linux distributions instead of just unpacking tarballs, Slackware-style. The whole point of having a package manager is so that it will ensure that software installations and upgrades are performed cleanly: that upgrading from A to B doesn't break C (or in this case, that upgrading from A to B doesn't break B).

When a package manager, in this case Redhat's 'rpm' can not handle the task it was meant to perform, that distribution is broken. Turning around and blaming the victim for the heinous crime of trusting the package manager to do what it was supposed to do is just... totally wrong.

Suffice to say, from this day henceforth, I will do my utmost to convince any client, customer, employer, friend, neighbour, or anyone I overhear discussing Linux in the pub that Redhat is a useless pile of fetid dingo's kidneys, and that you'd be more productive having someone beat you over the head with a large block of wood than attempt to use it.

Quote of the day, from Alan

Through the modern miracle of defenestration, the programmer is relieved of the drudgery of Javadoc.

Les Pecheurs de Perles, Sydney Opera House, 2003-10-23

It must have kinda sucked to be Georges Bizet. But not much.

When you're 25 years old, you write The Pearl-Fishers. All in all, it's a pretty average opera. The plot's shonky, and most of the music isn't particularly memorable. As first major efforts go, though, it's not bad.

A third of the way into the first act, though, you write Au Fond du Temple Saint, one of the most sublime moments opera has, or will ever see. This eight minutes makes your otherwise forgettable first attempt immortal. This isn't so bad. With something like Au Fond du Temple Saint in the first act, it would have been downhill from there anyway. It's not like Turandot, where the audience at least have to wait two acts for Nessun Dorma.

Later, you'll write Carmen, which has so many memorable tunes back to back that even non-opera-goers whistle them without knowing it. But none of them are quite as good as that duet you wrapped The Pearl-Fishers around.

Elliott Smith, August 6, 1969 – October 21, 2003

I don't know much of his work, but XO has been my constant companion for about four years now. If you look at my "most played" list in iTunes, that album accounts for six out of the top ten slots.

When I was happy, I marvelled at the artistry of the album, the way the pieces blended together. They were songs that made me wish I had even a tenth of the talent that went into writing them. Tomorrow, Tomorrow inspires me to practice my guitar, and then taunts me because I'll never come up with something that magical. Independence Day was my whimsical optimism.

When I was sad, I dove into its melancholy, and found somewhere warm to hide and lick my wounds. I Didn't Understand followed me on a train from Santa Barbara, leaving Danna behind. Everybody Cares, Everybody Understands was the controlled bitterness that I had to harness to stop Candi destroying me.

I never dared buy any of his other albums, lest they taint XO by being not as good.

And now, it seems, he's killed himself.

Everybody Cares, Everybody Understands

everybody cares, everybody understands
yes, everybody cares about you
yeah and whether or not you want them to
it's a chemical embrace that kicks you in the head
to a pure synthetic sympathy that infuriates you totally
and a quiet lie that makes you wanna scream and shout

so here I lay dreaming looking at the brilliant sun
raining its guiding light upon everyone

for a moment's rest you can lean against the banister
after running upstairs again and again
from wherever they came to fix you in
but always fear the city's finest follow right behind

you got a pretty vision in your head
a pencil full of poison lead
and a sickened smile illegal in every town

so here I lay dreaming looking at the brilliant sun
raining its guiding light upon everyone
here I lay dreaming looking at the brilliant sun
raining its guiding light upon everyone

you say you mean well
you don't know what you mean
fucking ought to stay the hell away
from things you know nothing about

Name: Noun-Verb

Context:

Your application1 has a significant number of command or action classes, for which a consistent naming scheme should be chosen.

Forces:

  • Command classes generally perform an action (verb) on a thing (noun)
  • The natural ordering in the English language is verb-noun. i.e. "Create user" or "Change address". By default, English-speaking programmers will default to this ordering
  • Most development environments sort class names alphabetically
  • It is easier to locate classes when they grouped near related classes.
  • The relation between two actions with the same noun: "Create User" and "Update User" is far more significant than that between those with the same verb: "Update User" and "Update Shopping Cart"
  • Given a use-case, it is much easier to find classes grouped by noun rather than verb. For example, if the use case is "changing a user's details", it is easier to scan through all the commands that affect a User than it is to try to work out if the applicable verb is "update", "change", "alter" or "modify".
  • Because command classes are often referred to outside the main body of the code (for example in configuration files), this can complicate refactoring the class names.

Therefore:

Early on, require that command or action classes are named by their noun first. then the verb: i.e. "UserCreateCommand", or "UserUpdateInformationAction".

This advice can also be applied to related artifacts such as JSPs.

Examples of Use:

Every project I have been personally involved with where command-like objects (Servlets, the Struts framework) have been involved.

Almost inevitably, English speakers default to the common verb-noun ordering, which causes no problems when the project is young. Later, when the action classes fill an entire page, a significant effort is required in order to refactor to the noun-verb ordering, but that refactoring is almost always worthwhile.

And you always wish you'd thought of it earlier.

1 This may also apply to other languages, but I encounter it most often, and in fact almost inevitably, in Java webapps.

After the great brouhaha last week over Joel's essay on exceptions, I feel the need to write an article or two that clarifies, at least to myself, what I think on the subject. That's one of the cool things about weblogs: they're a great excuse for forcing one's self to think through an issue.

Due to time and length constraints, I might have to break this into multiple postings. And you know how reliable I am at that.

Note also, since I do most of my Real Hacking in Java, this will be a very java-centric essay. If you have relevant1 points of view that are provided by other languages, feel free to mention them in comments or trackback.

Myth: "Exceptions force you to handle error conditions, while error codes do not."

Well, it's not really a myth. It's more a misunderstanding, or perhaps just a misstatement of the truth. Anyone who has dealt with the result of casual or inexperienced Java programming will have come across mountains of evidence of exceptions being ignored. For example:

  • Exceptions that are just not handled anywhere in the call-stack.
  • Exceptions that are caught and swallowed
  • Exceptions that are caught, but have no associated error handling more complex than logging the exception's contents and returning from the method.
  • Exceptions that are the victims of too-broad catch statements that should not apply to every error condition. (A common problem in Java because unchecked exceptions are subclasses of the checked exceptions)

Some of these things require conscious effort (but very little effort, and they become second nature to programmers who are not taught better), others are common mistakes. Sometimes it may even be the correct thing to do in that circumstance.

A more accurate restatement is to say that "Exceptions change the default behaviour on an error from being unpredictable, to being fail-fast". If an exception occurs that you were not expecting or that your code was not set up to handle, the exception will cause the operation to fail immediately. It will fail without causing any further damage, and without moving the observed error any further from its root cause.

This is valuable. Failing fast is the only valid response to an unexpected error. There's no way forward, because the system is no longer in a predictable state. There's no way back, because without having anticipated the problem, you don't have any way to fix it. So you just have to stop.

This is one reason that returning null from a method is generally a bad idea. null is usually a disguised error code. It means "you expected something to be here, but it really isn't". Worse, in Java a null is a time bomb, waiting to be dereferenced and blow up the code far from the original problem. If there being nothing to return is unexpected, consider throwing an exception. If it is expected, consider a null object refactoring, or changing the method to return an array or collection that can be empty.

You may mistakenly interrupt the fail-fast behaviour using any of the techniques described above. You may deliberately interrupt the failure to handle or correct the error condition. The important thing is that the default behaviour is an improvement over just dropping the problem on the floor.

If your system's operations are isolated and atomic, or if they simply have no side-effects, you can take advantage of the broad control that exceptions give you, by catching all problems, expected or not, at the operation's boundary. At this boundary, any failure that has not already been dealt with can be cleaned up by the generic isolation mechanism. This can be used to clean up after both the unexpected errors, and also those errors you deliberately allow to pass through to the keeper.2

This is usually how we deal with the whole class of errors (usually endemic to application servers) that have no better classification than "Oops, something broke"3. What can the user do if the server runs out of database connections? Bugger-all really. All you can do is catch the exception at the transaction boundary, roll everything back, raise the problem for an operator to deal with, and apologise profusely to the user for being broken.

To be continued (if I'm not sidetracked): flow of control and loose coupling.

1 Relevant as in "relevant to the content of the article", not just relevant to exceptions in general, or why they're superior in one language compared to another.
2 A cricket reference. The "wicket-keeper" is the fielder positioned behind the batsman. Since there are no "strikes" in cricket, when you face a ball that does not threaten the stumps, but that you do not wish to play at, you raise your bat and let the ball pass through to the keeper. In cricket-playing nations, you can signal that you are ignoring something you do not wish to deal with by arranging your hands as if they were holding a cricket bat, and then lifting them backwards and towards your shoulder.
2 On one web application project, the default error page for the system used during development used wording close to "Oops, something went wrong". When it came time to deploy, the customer liked it so much that they asked that it not be replaced with something more professional-sounding.

These are some bits from the play I went to see over the weekend, Stoppard's The Real Thing. Mark Pilgrim has a more complete transcript of the scene, if you find you want to read more. Which you should, especially for the bit about the cricket bat.

The situation: Henry is a playwright. Annie is an actor. They are in love. Annie has adopted the cause of a soldier who was arrested taking part in a peace demonstration, and who has written a play about it. A very bad play which Annie wants Henry to help with.

HENRY: Or perhaps I’d realize where I’m standing. Or at least that I’m standing somewhere. There is, I suppose, a world of objects which have a certain form, like this coffee mug. I turn it, and it has no handle. I tilt it, and it has no cavity. But there is something real here which is always a mug with a handle. But politics, justice, patriotism—they aren’t like coffee mugs. There’s nothing real there separate from our perception of them. So if you try to change them as though there were something there to change, you’ll get frustrated, and frustration will finally make you violent. If you know this and proceed with humility, you may perhaps alter people’s perceptions so that they behave a little differently at that axis of behaviour where we locate politics or justice; but if you don’t know this, then you’re acting on a mistake. Prejudice is the expression of this mistake.

ANNIE: Or such is your perception.

HENRY: All right.

ANNIE: And who wrote it, why he wrote it, where he wrote it—none of these things count with you?

HENRY: Leave me out of it. They don’t count. Maybe Brodie got a raw deal, maybe he didn’t. I don’t know. It doesn’t count. He’s a lout with language. I can’t help somebody who thinks, or thinks he thinks, that editing a newspaper is censorship, or that throwing bricks is a demonstration while building tower blocks is social violence, or that unpalatable statement is provocation while disrupting the speaker is the exercise of free speech... Words don’t deserve that kind of malarkey. They’re innocent, neutral, precise, standing for this, describing that, meaning the other, so if you look after them you can build bridges across incomprehension and chaos. But when they get their corners knocked off, they’re no good any more, and Brodie knocks corners off without knowing he’s doing it. So everything he writes is jerry-built. It’s rubbish. An intelligent child could push it over. I don’t think writers are sacred, but words are. They deserve respect. If you get the right ones in the right order, you can nudge the world a little or make a poem which children will speak for you when you’re dead.

I like that. “I don’t think writers are sacred, but words are. They deserve respect. If you get the right ones in the right order, you can nudge the world a little or make a poem which children will speak for you when you’re dead.”

A "Threat Model" is the enumeration the threats to a particular system's security. For example, if you keep your money locked up in a safe, your threat model might include the safe being forced open, the safe being cracked, somebody finding the code to the safe, somebody forcing the code from an employee, or an "insider job" by someone who knows the code.

There is no security without a threat model. Without a threat model, you risk wasting time and effort implementing safeguards that do not address any realistic threat to the system. Or, just as dangerously, you run the risk of concentrating your security measures on one threat while leaving yourself dangerously exposed from others.

From BoingBoing comes a link to a mailing-list post by Ian Grigg that challenges the threat-model we use far too often for Internet security. To paraphrase, the threat model that informs SSL, the technology we throw like pixie-dust over web servers to make them "safe" is this: "Assume the end-points of any transmission are trusted. Assume the network in between is under the complete control of some malicious attacker". As Grigg notes:

It's a strong model: the end nodes are secure and the middle is not. It's clean, it's simple, and we just happen to have a solution for it. Problem is, it's also wrong. The end systems are not secure, and the comms in the middle is actually remarkably safe.

While a lot of the specific points Grigg makes in his email could be considered overstated for the sake of his thesis, (for example, the interception of plain-text passwords was a problem before SSH) he is largely correct. Almost all security breaches over the Internet occur not due to the interception or alteration of secrets over the wire, but through the compromise of end-points: buffer overruns, backdoors, trojans and of course, social engineering.

We pay so much attention to making sure web browsers communicate with webservers in unbreakable cryptograpic magic. We pay enormous attention to even the most theoretical attack against that cryptography. And meanwhile, nobody ever steals credit-card numbers on the wire. They hack into net-accessible databases, or set up dummy websites to grab them en masse. We can install a blast-proof foot-thick concrete door, but that doesn't fix the flimsy bars on the window.

This isn't just because we've tightened up the transport-level security so much that the end-points are the only thing left to attack. As Eric Rescorla notes in this 2003 Usenix Presentation, The Internet is Too Secure Already, most products that were devised to protect the transport of messages: SSL, S/MIME, IPSec, WAP are either under-utilised, completely ignored, or don't work. SSH is really the only useful encrypted transport that has successfully replaced its clear-text counterpart.

Even when the transport protocol is broken, the result is underwhelming. Rescoria notes a timing attack against OpenSSL over which much fuss was made, but for which no exploit tool was ever developed. Far more telling, though: for years the worst-case scenario envisioned for SSL/TLS was the compromise of a trusted CA signing key. Such a breach would render every HTTPS website certificate invalid. When, in 2002, a bug in Internet Explorer made this a reality for every Windows user... nothing happened.

Grigg points the finger at the Demon convenience:

Well, in a nutshell, we won't protect against the end system attack, because its really difficult. And we'll ignore DOS because that's too difficult too. But we'll cover the entire on-the-wire threats... because, as the book goes on to show, we can!

Once again, he's mostly correct. Protecting the end-points, especially with the human factors involved, is hard. The extent to which we protect the transport layer, while not a useless exercise, is excessive given the vulnerability of each end, and the threats that exist in the real world.

Going back to Rescoria's presentation: much of the problems with the deployment of the cryptographic transport of data may actually be solved by compromising perfect end-to-end security in exchange for making it easier for users to simply slot it in as a replacement solution.

For example. When SSH was first introduced, it was criticised because for the way it handled host authentication. When you first connect to a new host with ssh, the host's public key is delivered to you.1 You then keep using that key from then on (and are warned if it changes). This is open to a Man in the Middle attack. If, the first time you connect to a host, an attacker is in the right place, they can intercept the host's public key, and own the connection (and any subsequent connections).

This "flaw" in SSH's security helped its adoption. If you had to arrange some alternate secure channel for the delivery of a server key, this would make setting up SSH that much harder for both server and client.

If "Perfect" isn't going to be adopted, but "Pretty Good" is still worthwhile protection, (especially when considering the threat model as a whole) the latter becomes a worthwhile goal.

1 You are given the opportunity to check the key's fingerprint, but nobody ever does.

Broken Promises

  • 5:10 AM

One of the problems with writing is that sometimes you have an idea that is very clear in your head, but that for some reason you just can't ever quite manage to turn into a coherent article. In rare cases I'll run with the idea anyway and publish something I'm not entirely happy with, but that's the exception rather than the rule.

At other times, I've had an idea for a blog post, but it's just ended up on the back-burner because while I think it's a good idea, I'm not quite inspired enough by the topic to turn it into real words.

Previous blog posts in which I have—explicitly or implicitly—promised a follow-up article but have not delivered (probably not an exhaustive list):

Current list of items in my VoodooPad "BlogIdeas" page that have been sitting there for more than a month without becoming a weblog post:

  • AHandfulOfVulnerabilities
  • IRCAsTheThirdPlace
  • HeldBackByPlainText
  • OptimiseLaterVsDesignForScaleability
  • StealTheseButtonsConsideredHarmful
  • ReplacingEmail
  • BugtraqWankers
  • JavaAndTheOperatingSystem

Addendum: A few of the items on the above list are things that I can talk about, and have explained in the past to cow orkers, but can't seem to write about. Perhaps I could get some of them out of my system by doing more video posts, and just talking about it; not worrying about the problem of prose. I would, of course, have to call it FishTV.

From the front page of Apple's website today: The blunt art of hyperbole, and how to get everyone talking about you.

Banner text: &ldquo;Hell Freezes Over. Introducing iTunes for windows. The best Windows app ever.&rdquo;

Sure, they'll piss people off with that. But when it blows over, is there going to be anyone who isn't going to know iTunes for Windows is out? :)

Defrosting...

  • 11:29 PM

(All images are linked to larger versions)

The office fridge is small, and has a freezer compartment encased in ice anything up to four inches deep.

I'm pretty sure the fridge in the office hasn't been defrosted since I started working there, three and a half years ago. In that time, it's managed to gather up a healthy collection of ice which, amongst other things, rendered the freezer compartment inaccessible.

Today, David Pinn decided to do something about it, rigging together an impressive contraption of plastic bags and buckets to stop the water destroying the carpet.

After a while, and after some amount of hacking by the aforementioned David with knife and screwdriver, he was finally able to open the freezer compartment. We all gathered around to see what might have been trapped inside all these lonely months...

You guessed it. The freezer compartment is packed solid with ice.

If you're working in Hollywood, and planning on making it big with stylish gratuitous violence, give up now. You'll never top Kill Bill.

Kill Bill has been widely criticised as the triumph of style over substance. The movie says nothing. Sure enough, they're right. This movie goes absolutely nowhere, but then again, neither does a rollercoaster. You go up and down, get spun around and exhilarated, but in the end you come to a stop exactly where you started.

Kill Bill is pastiche from start to finish: an homage to genre. It's an homage to genres where the plot and characters were always secondary to style and atmosphere, and where the script was always just that little bit hokey. Tarantino's script is pared back, abandoning the crafted dialogue that made his earlier movies. Instead, he adopts stilted, vaguely uncomfortable cliches that along with the Sergio Leone-inspired music capture almost perfectly the tone of the movies he is imitating. Like all in-jokes, I imagine if you're not part of it, it could be very grating.

The body-count in Kill Bill is high, but only so high as to be comparable to the Stallone or Schwarzennegar vehicles of the 80's. What Tarantino excels at, however, even delights in, is showing you that death is messy. Mr Orange, shot at the start of Reservoir Dogs, and spending the rest of the movie dying painfully. Marvin has his head blown off in Pulp Fiction, and somebody has to clean the blood and brains out of the car.

Nobody dies cleanly in Kill Bill. The bodies don't fall out of frame with a minimum of mess. They fountain unnatural torrents of blood and stay where they lie, or they crawl out desperately with what limbs they have remaining. There is no sanitized violence, there is only brutality. Tarantino's most impressive accomplishment with Kill Bill is that we're never allowed to identify with Uma Thurman's character's revenge. We're allowed to sympathise, sometimes, but the road she travels is so drenched in blood that we can't ride it with her.

If that doesn't bother you, go see this movie.

I'm blaming David Pinn. At some point late in the afternoon he said (or possibly even sang) "I've got the power". To which I replied, "Oh, I've got that on mp3 around here somewhere". And I did.

See also: a previous project and Barry Manilow's Copacabana.

Anyway, I didn't just have Snap's The Power on my Powerbook. I also had Reason, and a software MIDI keyboard

Once you can reach across your desk and play that sample at any pitch you desire, it's hard to stop. Even though you know you're sending your co-workers insane.

I've got the power.

ph34r.

Andrew Orlowski has written yet another rant about how blogs are ruining Google. Currently to blame is Trackback, the protocol many weblogs use to create back-links automatically when one blog links to another. While the practical merit of trackback can be debated, many people find it a useful addition to the blogging toolkit, and it ain't going anywhere in a hurry.

Orlowski, on the other hand, describes it in terms usually reserved for the Nuclear Bomb: a catastrophic invention that should never have been allowed to escape, damn those scientists for not thinking of the consequences!

When the old longhair database people, now barely remembered, went off and designed information systems, they thought of values such as data integrity and resilience. This created a rigorous and unforgiving peer-review culture, but the values survived. Lacking such peer review, today's wiki-fiddlers can create such catastrophes as Trackbacks with apparent impunity.

I've probably said this before, but it bears saying again. It is not the job of the Web to conform to Google's search algorithms. In fact, that bears saying once more, with feeling.

It is not the job of the Web to conform to Google's search algorithms!

The World Wide Web is not the carefully measured, centralised system of the 'longhair database people'. The Web is Small Pieces, Loosely Joined. It is, and always has been an anarchy of links, and has taken over the world because anyone, anywhere on the web can innovate, and build on top of it.

Read any history of the Web, and it'll tell you that the WWW succeeded where previous attempts at Hypertext failed, precisely because nobody was caring about data integrity or resilience. Something breaks? Bah, just throw out a 404. The cost is that things fall apart every so often. The pay-off is explosive growth, and the ability to become everything to everybody.

Google has been wildly successful so far because its indexing and searching algorithms have been very good at letting people find what they want to find on the Internet. They did that by examining the shape of the web, and building a search engine that used the shape of the web to rank search results.

The rise of weblogging, and the use of things like Trackback have changed the shape of the web. This is nothing new. The shape of the web has changed a lot since the days you could find every interesting site on the NCSA's What's New page.

Even the presence of Google itself has changed the shape of the web through people attempting to manipulate their search rankings, Google-bombing, setting up link-farms and comment-spamming on high-pagerank blogs.

Everybody who takes part in the web changes it somehow. That's why it's so damn cool.

The web does not exist to serve Google. The web should not stay stagnant so as not to break its search engine. The web evolves continuously. It is up to Google to change itself to adapt to what people want to do with the Web. If Google can not adapt, then one day we will talk of it in the same way we speak of Altavista, Metacrawler, Excite or Hotbot: search engines we used to rely on, but that were each eclipsed by something better.

Like quite a few people, I'm going to add my voice to the throng and say that Joel Spolsky's latest essay, Exceptions, is the first of his writings that I can remember looking at and thinking, “Man, that's just wrong.”

The reasoning is that I consider exceptions to be no better than "goto's", considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto's

I could go into what is good about exceptions at great length, but it's already been well dealt with elsewhere in great detail.

  • C2 Wiki: Use Exceptions Instead Of Error Values

    The only alternative I know of to exceptions is to wrap every function in an if statement and either return with an error code or completely exit the program. The result is code whose purpose is more focussed on returning error codes than performing its desired function. I've had to work with well written code that was written in this style and it becomes very difficult to understand the code. When needed (which is not that often), exceptions provide an excellent alternative way of returning errors and they do not lead to clutter throughout the code.

  • Ned Batchelder

    OK, so usually Joel Spolsky is a pretty bright guy, and even when his ideas seem wacky or overstated, there's something true and useful about them. But he's dead wrong about exceptions.

  • James Robertson

    Bleah . I've seen code written using that theory. It very, very quickly becomes an unmaintainable nightmare, and has errors being propagated from deep in the bowels of the application up to a level where they can be handled. This is clean how?

  • Ben Poole

    OK, so I know I'm a newbie at this object oriented thang, but I remember when I first learned about exceptions in Java, and how they work. As someone who was getting pretty tired of On Error Goto lblErrs..., it struck a chord let me tell you!

  • Keith Pitty

    As a counterpoint, I think Rebecca Wirfs-Brock's article entitled "What It Really takes to Handle Exceptional Conditions", presented at the forUSE 2002 conference, makes worthwhile reading.

  • Various Posters on Joel's Message-Board

    The problem with return codes is it's just SO easy to forget to check them. You forget to check a return code even once, and you've got a big fat hole in your program...

    ...I must say also, this is first thing I strongly disagree with Joel on. I do abhor checked exceptions as the ivory tower approach. But unchecked exceptions make code far easier to write and read....

    ...Joel's site must have been hacked. Either that or he's being sarcastic.

After seeing both X-Men 2 and League of Extraordinary Gentlemen this year, I have come to the conclusion that Hollywood has great difficulty writing a script for an ensemble superhero movie. As a theatre patron, I would like to suggest the following script guidelines for anyone attempting such a movie in the future.

  1. If you can, make the back-story implicit.

    We don't need to see how these five people came together to fight crime. Or if we do, it can fit in the prologue. Details can be fleshed out through well-chosen dialogue and interwoven with the relationships between characters.

    If you can put this exposition into an exchange between characters during an action sequence, even better. The fewer ‘one character just randomly deciding to talk to another about how he or she had a tragic childhood’ scenes you have, the better.

  2. Have at least one scene in the first act with all the heroes working together.

    Before you start tearing them apart in the second act, the audience need a sequence that shows how powerful the heroes are as a team. If you can fit this into a prologue, even better. You need to make the audience respect what the heroes are capable of before you start weakening them. Think of the James Bond movies, and how the prologue for each one establishes Bond's competence before the main plot has even kicked in.

    And no, the fact that they did it in the last movie doesn't count. Don't count on your audience having seen the last movie in the last year. Or even at all.

  3. The more characters you have, the shallower they've got to be. Live with it.

    There's only so much you can fit in a movie. X-Men 2 was very obviously edited to ribbons because it tried to give every character depth, and couldn't fit it all into the allotted time. Peter Jackson can almost manage it for most of the Fellowship of the Ring, but then he has ten hours in which to do it.

    Pare down the characterisations and relationships that don't directly affect the plot. If you still have too many, lose the associated plot-points as well. Feel free to leave some of your ensemble shallow and under-exposed. If the movie is successful, you can always focus on them in the sequel.

  4. Limit yourself to three threads

    You're probably going to split your characters up near the end. Never ask the audience to follow more than three groups of characters at the same time. This includes the bad guys. The audience can follow more, but you end up with the action so diffuse that the movie loses focus, usually at the time when it should be at top momentum.

    If you have three groups of good guys fighting or chasing three groups of bad guys, that's fine. But the moment one of those fights splits up far enough that you need two separate points of view, you're over the limit.

  5. Don't cut away from a thread without having advanced the story

    If you have two narrative threads going on at once, you're going to cut between them. If you cut to one, you mustn't leave it until something has happened that either advances the plot or affects the audience. Don't just cut to thirty seconds of fighting to remind the audience it's happening, and then cut back.

As a final note, something that isn't script-related at all. An action sequence is a narrative.

You wouldn't have a scene where all the characters were shouting at each other so loud you couldn't work out what anyone was saying, yet that seems to be de rigeur for action sequences at the moment. An action sequence must tell a story, and it is incredibly important that even in the midst of chaos, it is obvious who is doing what to whom, and why.

Haven't we learned from Hong Kong action movies yet? Pull the cameras back a bit, and space out the edits. Let us see the shape of the scene, and linger long enough on each event that it melds into the choreography.

Conversation from IRC:

Charles
Oh dear... I just took one of those "Which Sci Fi character are you?" quizzes, and I was... Wesley Crusher.
Charles
Should I go shoot myself now?
Lonita
No, go back to the quiz and lie.
Charles
But that would be dishonest!
Lonita
So?
Charles
OK. I changed the answer to the one question I wasn't sure about. Now I'm Picard. Yay.
Lonita
Now don't you feel better?
Charles
To be honest, I still feel a little dirty.
Lonita
Go take a sonic shower.

One of my favourite cautionary tales about the Internet, and the assumptions nerds like myself make about it, comes from when I was working for an ISP.

The web-pages for this ISP were first put together in 1995 and not really changed substantially since. For a company that, at the time, was trying to sell web design services, this wasn't really a very good look. Eventually, Tom was given the job of redesigning them from scratch.

Quite a bit of attention was paid to the information design of the site. The ISP's installation pack set the site front page as the user's homepage, so most of our users were going to see this page every day they logged in.

One of the things the old site had was a "Search engines" page. This page was a simple list of links to each major search-engine via a centred column of their logos. It was really quite ugly and we weren't really sure of its utility: too many choices, not enough context. A new user coming to the page would have no idea which they should click on or why. So we decided to scrap it. As a replacement, Tom wrote a search-box for the site's front page that could be used against any of the previously listed search-engines, with whichever one we thought was best at the time (this may have been long enough ago that HotBot was the winner) being the default choice.

Eventually, the site went live. We got lots of compliments about the design. And we got lots of complaints about the missing search-page. The complaints were inevitably from people who had been with the ISP more than six months, and they said with one strong voice: "HEY! I can't find Yahoo any more!"

This is when I realised how little the average user knows about using the World Wide Web. We had all assumed that the search-engine page was there for new users. Once somebody had found an engine they liked, they would bookmark it or remember its URL. We were completely wrong. Some of the people complaining had been regularly using the Internet for years. All of them had been using it long enough to complain when Yahoo! went missing. And all of them had learned this, and only this way of finding their favourite site:

  1. Open Netscape
  2. Click on "Search Engines"
  3. Click on Yahoo

URLs. Bookmarks. Changing your homepage. All of these things were voodoo. There was just Netscape, which you open, and you go clicky-clicky until you get where you want.

I like to keep this story floating somewhere in the back my head. It's my own little reality-check. Needless to say, we re-introduced the search-engines page rather quickly.

The RubyForge description of the project is:

Whizzbot is a fully featured IRC-bot implemented in Ruby. Whizzbot can be easily configured to work with a wide range of topics and has a plugin architecture allowing limitless expansion.

Given the use of the phrases "is ... fully featured", "can be easily configured", and "has a plugin architecture", what stage of development would you assume the project is in?

  1. Planning
  2. Pre-Alpha
  3. Alpha
  4. Beta
  5. Production/Stable
  6. Mature

If you answered: "1 – Planning", you would be correct.

AUGH!

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." – Brian W. Kernighan

'Just' is quite rightly included amongst the C2 wiki list of Alarm Bell Phrases. It's a dangerous word that should be used as sparingly as possible. As a developer, it's a word you hear far too often: "this will just take a few days", "it's just a couple of web-pages", and of course the ultimate: "it should just work."

'Just' is a vague, almost condescending diminutive. Nine times out of ten, it means this:

I do not know, but it is in my interest to estimate optimistically.

Generally, you'll find that if you have a definite idea of the size of something, or the amount of effort required, the word 'just' quickly vanishes from your vocabulary. Not because the thing is necessarily large, but because even being certain that something is small removes the need to qualify its smallness: it becomes what it is, no more, no less, no 'just' required.

I keep hearing how wonderful Visual Studio .NET is, and how it kicks the ass of any Java IDE. Unfortunately, I mostly hear this from people who haven't used a Java IDE in the last three years, and I haven't used Visual Studio in about... er... five. So I just grit my teeth and say "Yes, whatever you say".

As such, it's nice to hear from a generally level-headed source like Martin Fowler that JetBrains' .NET IDE will be a welcome improvement.

I know lots of ThoughtWorkers who are dying for this tool. While Visual Studio has a lot of nice features, the programming capabilities seem primitive when you've used a tool like IntelliJ or Eclipse. Of course, I find I really miss the refactoring capabilities, but there's much more than just the refactoring that makes IntelliJ such a stunning tool. Having a tool like this as a plug in to Visual Studio will make .NET programming much better.

So, like, nyeah!

One of my possibly annoying habits is inserting pop-culture references into random conversation. I have a large store of song lyrics and movie quotes swimming around in the back of my head, and they have a tendency to pop out when they seem vaguely relevant. A lot of the time I don't even realise I'm doing it until too late.

This can be particularly annoying on IRC, where I am quite capable of spending hours doing nothing but interjecting the occasional line from a song into the conversation.

Paradoxically, when that meme was going around a few years ago where you had to answer a series of questions about yourself using only lyrics or quotes, I was unable to do it. I guess that has something to do with how much I suck at improvisation when I'm put on the spot. I can free-associate when the pressure's off, but sit me down and order me to think of a relevant quote for something specific, and my brain seizes up.

By far my favourite, and most common quote, however, has to be this (although I usually misquote it slightly):

I say we take off and nuke the entire site from orbit. That's the only way to be sure.

It's applicable to so many different situations.

NetNewsWire has an interesting feature whereby it highlights changes that have been made to an RSS feed since it was first downloaded. (Just enable "Highlight differences" in the General preferences pane). If you think about it, it's quite an interesting effect, because it draws more emphasis to corrections than, perhaps, they deserve.

(And I apologise in advance to Dave, he was just the most recent example, and thus gets picked on here. The referenced post is here)

Now that the Roller software that drives the site has proven itself, JavaLobby is stepping in to support, administer, and nurture the JRoller community. JavaLobby is putting in place scheduled backups, issue tracking (via everybody's favorite: JIRA), and customizations to tie JRoller into the JavaLobby community. I'm going to continue to support JRoller and take an active rolerole, along withside other JavaLobby volunteers tovolunteers, in the support of JRoller.

The transparency of weblogging can be quite daunting sometimes.