Archive for February, 2005

Idea license

Thanks to the great guys at Jetbrains, Apache committers are entitled to a free IntelliJ IDEA license for their Open Source development. Today I found my license in the inbox, and I rushed to an install: I remember trying out Idea a few years ago and being more than impressed at how cool the product was.

Mind you, I'm not an IDE guy: possibly the most used software on my powerbook is Terminal.app and Vim. Vi is just faster than everything else (Emacs lovers don't need to comment, I really did try to use it, but it just gets way too mych on my way): since most of my time is spent fixing problems and finding issues on other's code, I'm much more productive with ten fingers and a shell rather than with a mouse and a (bloated?) IDE. However, IDEs are unvaluable when I'm starting from a clean slate and I have to actually code some stuff: whenever I start missing code completion, TDD tools, remote debuggers and the like, I understand it's time to go grab a coffee while Eclipse starts up.

With my fresh Idea license, I started playing around with the IDE. After a few hours (and an overly annoying amount of "force quit"), my first impression is that Idea is definitely cool stuff, but in the past few years Eclipse has played the catch-up game pretty well: I would say that Idea is still ahead of the pack (refactoring is sweet, code folding works well, the UI is snappy despite being Swing), but they basically don't have the killer features monopoly anymore. So far I tend to say that Idea outperforms Eclipse more or less on everything, but only of a slight bit. Whether that bit is worth the price tag is still something to consider: for now, I'm stuck in trying to make Subversion work, then I plan to give Idea a serious try trying to accomplish some of my geeky objectives for 2005.

Medal maledetta...

Oggi ho avuto la mia prima esperienza medal in una garetta a quattro in quel di Tolcinasco, insieme ad alcuni amici del forum di lezionidigolf.it. Ottima compagnia, tempo tutto sommato clemente, campo un po' pesante. Ma, porca paletta, quanto è dura giocare medal: rivoglio le mie X!

Oh, d'altro canto uscire dalla prima volta in cui si contano tutti i colpi con 108, che fa esattamente il mio handicap (senza contare che il campo mi dava quattro colpi in più, quindi ai fini dell'hcp ho giocato -4), non dovrebbe essere poi così male. Il problema è che al tee della buca 17 i colpi erano... 88.

Segue la ricetta per fare venti colpi in sole due buche e garantire buone dosi di risate in club house per qualche settimana. E' sufficiente al par 3 della diciassettesima buca, ossia la 8 del percorso giallo di Tolcinasco, seguire la seguente strategia vincente:

  • tee shot: tirare il primo e unico toppino orrendo della giornata, con palla che fa pluf a cinque metri di distanza (si raccomanda di non superare il tee delle donne nel contempo, così da dover pagare una bevuta);
  • rifare il teeshot assicurandosi di andare lunghi e agganciati nel laghetto dietro al green;
  • flappare il quinto colpo droppato dal laghetto, finendo in bunker;
  • fare non più di tre metri (totali, mi raccomando) con due colpi consecutivi dalla sabbia;
  • per salvare la faccia di fronte al gruppo irridente, immaginarsi di essere un caterpillar e tirare un colpo modello "te la do io la benna", assicurandosi di spizzare la palla e vederla rotolare per venti metri di green fino a cascare, lenta e inesorabile, nel laghetto di fronte;
  • di qui è tutta discesa, un banale approccio come decimo colpo e due putt canonici garantiranno ampie dosi di ilarità e sfottò per i secoli a venire.

Una volta assommati dodici colpi in questo modo, il resto è banale: in fondo si tratta solo di fare un par cinque in otto colpi. Ma anche qui c'è modo e modo. Se si vuole fare schifo con stile, una buona possibilità è arrivare in tre colpi nel bunker lato green, e quindi mettercene altrettanti per uscire. Si sa di avere raggiunto l'obiettivo quando ci si guarda indietro e sembra che nel bunker ci abbiano appena fatto le sabbiature John Daly e Giuliano Ferrara. E, mi raccomando, mai meno di due putt.

Seguendo queste semplici istruzioni, accompagnandole con peperoni e salame piccante a cena, gli incubi sono garantiti. Probabilmente anche con semolino e tisana.

Alessandro Baricco - Omero, Iliade

Se mi serviva un'ulteriore riprova che i classici vanno fatti leggere con moderazione durante l'adolescenza, questo libro mi ha definitivamente convinto. Baricco mette in prosa una traduzione moderna dell'Iliade, testo che ho discretamente odiato durante il ginnasio al punto che di fatto mi limitavo a sapere che parlava della guerra di Troia e che a un certo punto c'entrava il cavallo di legno. Forse ma forse mi ricordavo qualcosa su Achille, Ettore e Patroclo, ma allo stesso modo in cui ricordo che in greco ci sono l'aoristo e il duale o che l'orbitale P2 ha la forma di una scamorza (o era il P1? Giusto per fare capire a quale livello si studia scienze al liceo). Però sono tuttora in grado di recitare a memoria e in greco le prime righe dell'Encomio di Elena che mi ero preparato per la maturità: direi che è un evidente indizio di arteriosclerosi incipiente.

Oh, d'altra parte io sono sempre stato per il massimo risultato con il minimo sforzo: dopo che avevo capito che il professore di italiano non aveva cuore di interrogare la gente su Dante, ho pensato bene di toglierlo dall'imbarazzo e andare volontario per tutto il liceo sulla Divina Commedia. Complice la sua lentezza, da una interrogazione all'altra avevo al massimo uno o due canti da preparare, e a momenti ne sapevo più io di lui: una buona memoria e una discreta faccia da culo facevano il resto, e mi conquistavo il mio sette e mezzo declamando a memoria terzine dantesche. A tutto c'è un contrappasso però: non chiedetemi cosa sia successo nella letteratura italiana dopo l'Ariosto: nonostante la maturità classica, penso che confonderei con leggerezza non solo Pascoli e Carducci, ma probabilmente anche Cecco Angiolieri e Moravia.

Ma torniamo al libro: ben scritto, anche se come per tutti gli autori "televisivi" nel leggerlo ti figuri Baricco a leggerlo alla sua maniera affettata, il che comporta una certa sensazione di fastidio. Sulla storia c'è poco da dire, è immortale quanto basta, e Baricco ne evidenzia alcuni punti estremamente interessanti e che fanno pensare. Come minimo, direi che "Omero, Iliade" dovrebbe diventare una alternativa ufficiale al bignami di turno, ma se si vuole capire perché a distanza di millenni stiamo ancora leggendo i versi di un vecchio greco cieco, beh, il libro di Baricco è un ottima risposta.

Firefox and OS X 10.3.8

Is it only me having issues with Firefox after updating to 10.3.8? All of a sudden (I can't think of any other cause) Firefox randomly (but annoyingly often) takes forever after loading a page to return control to the UI: the page is rendered just fine, I see no signs of activity, yet the beach ball keeps spinning, and it takes more or less a minute to be able to use the browser again.

I also tried to move my Library/Mozilla directory away, but that didn't change much (actually it wasn't even re-created), and I tried reinstalling Firefox as well... of course to no avail: I'm forced to use Safari and try googling for a solution, but after getting used to Firefox it feels quite bad to be back on Apple's browser. Since I can't find many people complaining, I assume it's me having done something wrong, but at the moment I'm out of ideas to sort myself out...

Update: a few hours of painful ktrace, tcpdump and lsof earnt a few suspects but didn't nail the issue down. However, I discovered that the correct profile to delete was Library/Application Support/Firefox, so I reset my browser to factory defaults and now it seems to work (finger crossed). The issue seems to lie with some Firefox extension fighting with the latest OS update rather than on the browser itself, but I currently lack time to discover what went wrong. I have my Firefox back, and I'm happy with it.

6 hours, 32 minutes...

... and counting. This is another snippet of my life that went down the drain thanks to Microsoft (not to mention how my candidate sleepy snowy sunday afternoon turned into a living hell).

Today my parents asked for some assistance, again due to their smart card woes I've been muttering about already. This time they had a brand new, and assumingly supported, SC reader, but they were unable to install it. I logged in via VNC and started uninstalling previous versions of various softwares, in order to start from the cleanest possible situation. I was asked to reboot, and I did: in a couple of minutes my parents were on the phone screaming about a BSOD. The computer wouldn't boot anymore, all we got was a STOP error with a very informative "c000021a" cause.

From there, we were stuck. Safe mode boot was unavailable, and there was no way on earth to obtain even the simplest command line to attempt a manual rescue. Browsing the web brought a whole wealth of panicking information, not to mention a couple of official Microsoft statements along the lines of "er... yeah, you know, we must have screwed something up with dependency management: would you mind reinstalling the whole thing? Sorry about that and, by the way, where do you want to go tomorrow?". Well, I don't know where I want to go, but I'm pretty certain on a number of places I would like to send the whole Redmond team responsible for such a gross mistake: isn't it time you just start behaving like a normal operating system that dumps on a console (no, COM2 doesn't qualify, sorry) what's going on with the boot process so that diagnosis and rescue can be available even to those poor guys who don't happen to have a lab on their desk? Or, even better, isn't it time you make sure that a mundane task such as removing software isn't allowed to screw the whole computer making it not only unusable but even unable to boot?

I'm actively looking for a country in the world where I could sue companies for wasting my time in such a stupid way. If anyone happens to know, I'd love to share thoughts, real estate estimates and immigration plans.

Open Source and flat tyres

Today I had the bad surprise of finding a flat tyre on my car. It pissed me off quite a bit because it's saturday and me and my wife were supposed to drive to a few shopping places this afternoon: my replacement tyre is a provisional one, you're supposed to use it just to drive to the near tyre shop to have it replaced, so our weekend seemed to be totally ruined.

While driving back home I passed by a tyre shop. It was well after 1PM, and the sign at the entrance stated they were indeed open on saturdays, but only up to 12. I drove inside just to have a look, and found out they were still open: a pleasant guy welcomed me and told me they could have fixed it in a few minutes. Well, not only they did, but when they finished they didn't want any money: they were about to close the shop, the accountants weren't there and "the work wasn't worth the fuss": they just invited me to come back when I'll need to perform maintenance on my tires. Now, of course not only I will now and forever be a loyal customer of that station, but of course I will suggest those guys to everyone needing assistance (they don't have an Internet site, so I can't link directly to them, but if you happen to have a tyre issue in the Desio area, check out the "Centro gomme brianzolo"). However, there is more to that than just a flat tyre.

Since this afternoon I just can't stop thinking about this guy and how he managed to have more marketing sense than a whole bunch of MBA-graded CMOs. What they did cost them little or nothing: with the right tools and the required experience, fixing a tyre is really just a matter of ten minutes or so, doesn't require any consumables and doesn't wear the machinery. However, the value to me was much bigger: they could have extorded me a generous amount of money and still see me leaving with a smile on my face. By solving my problem for free, they won a new loyal customer and, even more important, a nice word of mouth effect.

The real point of this story, though, is that I don't think I have been the objective of a sound marketing strategy: I just think that those guys have been honest and that their business is driven by costs rather than by values: it costed them very little to help me out and they didn't feel like exploiting the situation. This isn't what happens in the traditional computer industry, where price tags are based on perceived customer values rather than on the real costs of the business: the old story of a computer technician asking 1000$ for hitting a computer with a hammer and splitting up the bill in 1$ for the hammer job and 999$ for being the only one knowing where to hit the machine has always been the meme in the IT pricing industry.

Now, I'm not saying that competence (and the associated costs to attain it) shouldn't be considered in a pricing model, but I definitely do feel that there are quite a few business in the IT industry that are leveraging a dominant position and providing a pricing model for services based on lock in strategies ("dear customer, you can't go anywhere else") and perceived values ("no matter how much it costs, I'll get from you as much as you are able/willing/forced to pay").

Enter Open Source: lock-in is, at least in theory, a non-issue, and the pricing model has to be derived on costs rather than on values, since your competitor will be able to get a better quote to your customer. The healthy competition in the Open Source market has the nice side effect of promoting honesty as a value that can be part of the negotiation again: this is of course what would happen just in the ideal world, but still it's worth considering. Not to mention that honesty has to be part of your DNA if you happen to be part of an active Open Source community (and if you're serious about Open Source, you just have to): everyone is friendly and trusts you, but try to misbehave and you will be nailed.

I might also arrive to say that the availability of Open Source software has a parallel with the guy fixing my tyre for free and winning myself as a permanent customer in exchange: yeah, I'm stretching it to the limit, but I still feel that there is something in common. It feels good to imagine that honesty, cluefulness and competence can be key drivers again and a foundation for a business model in the software services industry: I'm sure this can be one of the reasons of success of Open Source and it will pay off in the end. And hey, if I'm wrong I can always apply for a job at the tyre shop!

Hardcore unit testing in Swing

I'm doing some Swing stuff in my Copious Free Time, basically for fun but also to scratch an old itch. I'm committing myself to high percentages of test coverage (ideally 100%, but I'd sign up for everything above 80%), and this is a good exercise for my rusty Swing skills.

Tonight I spent more than a fair amount of time trying to test a JTextField on which I'm attaching a custom key listener (I want it to accept just digits): of course setText() doesn't work since it bypasses the key listener code, so I figured out I had to basically emulate the keyboard behaviour. From a first cursory look I thought it would be as easy as sending the key events to the widget via Component.dispatchEvent(), but I found out the hard way that this wasn't the case, since my widget wasn't receiving anything. A googling session showed me what my mistake was, and in the end I had to enter the treacherous hallways of AWT focus management, having learnt that a Component won't receive any key events unless focused (well, I assume that's just fair enough).

Unfortunately I have been unable to programmatically set the focus on the component I wanted to test: a Component won't receive any focus unless it's displayable, and setting displayability on a widget by hand is not an easy task. Ultimately I had to pack my widget into a frame in order to have AWT do the gruntwork for me: the good news is that my textfield works as expected and my bar is green again, but still I don't like having a Swing window popping up on every test run. Sure, I could probably use headless AWT to hide it, but if any Swing savy geek drops by this entry I could definitely use some assistance in solving this issue in a better way.

Update: thanks to Adrian Sutton I have a much better solution now. The only problem with Adrian's solution was the focusManagerIsDispatching field belonging to AWTEvent and being private, so the revised solution is:

    public void simulateKey(KeyEvent e, Component c) throws Exception {
        Field[] fields = AWTEvent.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
           if ("focusManagerIsDispatching".equals(fields[i].getName())) {
              fields[i].setAccessible(true);
              fields[i].set(e, Boolean.TRUE);
              c.dispatchEvent(e);
           }
        }
     }

Thanks so much Adrian!

A sad day for web standards in Italy

Today Repubblica, the largest online italian newspaper, launched a huge site reorganization, with new graphics, revamped content and a new structure. I have fond memories of Repubblica, since it has been the first serious Internet experiment in Italy, and since I have been so lucky to maintain their servers for a while (yeah, root password included :-)) back in the Old Days and to work for them on a number of occasions afterwards.

However, their new home page just plain sucks. And I'm not talking about aesthetic, since everyone has his own taste. However, 119 validator errors are really too much to digest, not to mention that their pages render poorly on Firefox and are completely unreadable on Safari (just click past the home page): I wonder who has been responsible for what seems a standards massacre and a community suicide. To add insult to injury, an article on the home page talks about the new graphics and mentions how the the users forum contains some critiques but also a lot of praises: the actual ratio is more or less 20 very upset people to 1 who can basically live with the new setup. So much for listening to your readers and providing unbiased information, uh?

Everyone is moving through WAI, cross-browser compatibility, Web standards and so on: the leading italian site is out with an IE only design definitely looking like nephew art (you really don't want to see the HTML source). Oh well, this is Italy after all... it's just that over time I tend to forget.

8 simple rules for building a manageable Cocoon application

A few notes to self to learn from my own mistakes and avoid spending endless hours next time trying to clean things up when you're close to production. Some of these rules are of course already part of our internal Cocoon development process, but I thought I could share them online and see if someone has better approaches to suggest to a few simple but cumbersome issues when starting a Cocoon-based project:

  • Don't even start any development before customizing the Cocoon environment for the project needs. This boils down to "cut the crap": be ruthless in excluding blocks, don't enable any of them "just in case". Unnecessary stuff will clutter at best and bite you at random times in most cases. Do version-control your local.build.properties and local.blocks.properties.
  • Using Cocoon's xconf tool, have a set of files ready to further edit the Cocoon configurations, cutting even more crap. The block system still has some quirks, and you end up with unnecessary stuff such as JMS or XSP when you don't need it and really don't want it around.
  • Always take relocability of your Cocoon application into account, from the very beginning of your project. Your application should work from the webapp root (mounted as /), under a context path (/whatever) or as a sub-sitemap (/whatever/the/user/wants). This means that you should always pass a "mount-point" attribute within your rendering pipelines and components, calculating where your application has been mounted, and building paths accordingly. Unfortunately the current Cocoon API will only tell you the full request path and the URI handled by the sitemap, so you need to mangle those data by substracting (string-wise) the sitemap URI from the request URI in order to obtain the path you're looking for. That is, if your sitemap is mounted on /context/foo and your request is for /context/foo/bar/baz, the sitemap URI will be bar/baz, while the data you need is actually /context/foo to build your links properly: yeah, that gives me headaches as well, and I have an overdue patch to provide this location in an easier way. But please tell me if I'm just missing an obvious solution.
  • Don't ever rely on Cocoon samples for functionality. If you need any feature such as XSLTs, JS files or sitemaps, import it into your project right away. Do it now, or you will regret it in the future. A lot.
  • The above note has a special meaning for form handling. The impressive and powerful Cocoon Forms resources are part of the samples. Since you probably want to reuse them, to avoid any temptation, just package everything up in a JAR file and use resource://whatever as your $resources-uri parameter in your forms stylesheets. the following Ant task might come handy:
   <target name="pack-cforms-resources" depends="jar"
      description="package all the CForms resources">
      <jar jarfile="${dist.dir}/cocoon-forms-block-resources.jar"
         basedir="${cocoon.home}/src/blocks/forms/samples">
          <include name="resources/**"/>
          <exclude name="**/.svn"/>
      </jar>
   </target>

and, later on:

      <map:transform type="forms"/>
      <map:transform
          src="resource://resources/forms-samples-styling.xsl">
        <map: parameter name="resources-uri"
          value="resource://resources"/>
      </map:transform>
  • Keep a very strict separation between application files and resources that a user might want to customize. This is expecially true for stylesheets and client-side javascripts/images/icons. Consider using the xsl:import feature in your stylesheets, providing an empty user-oriented version of your stylesheets, where templates can be overridden. Might hurt performance a bit, but sure helps tremendously for real life scenarios, where your customer is supposed to customise files and you're supposed to provide updated versions of your applications. If you don't, every deployment after the first one becomes an incredibly painful process.
  • Ideally, package the whole application as a jar file: remember that Cocoon can easily access jar-packaged resources with the resource: protocol, and this holds true even for that overrideable XSLT who can import from your jar files. You can even package your root sitemap inside a jar and reference it with the resource:// protocol.
  • Don't forget error and logging management. There is nothing worse that the default Cocoon error page popping up in front of your customers, so plan for a sensible handle-errors section right from the beginning of your project. Also, don't forget to customise your logkit.xconf file. These resources can be easily part of a shared project codebase, so there is no excuse for preparing them in advance.

Pete Dexter - Train

Un bel regalo di mia moglie come compagno di un viaggio imprevisto e delle relative 4+4 ore di treno si è rivelato una piacevole sorpresa. Train è un romanzo un po' fuori dal comune, ben scritto e avvincente: richiede quel tanto di attenzione nella lettura da meritare Einaudi, ma la trama è interessante e i personaggi sono molto ben delineati. Ricorda un po' Lansdale e un po' lo Steinbeck di "Uomini e topi".

L'atmosfera golfistica ovviamente fa piacere a un appassionato me, ma il libro è gradevole anche per chi non ha mai visto un driver o pensa che il birdie sia solo un passerotto zampettante. Vale una visita in libreria per vedere se è stato tradotto qualche altro titolo: Pete Dexter è il prossimo in wish list.