Marc, himself, his blogs, and you reading them.

April 28, 2004
Kids' Art.
Fien's drawing

You don't need to tell me: I know proud parents are utterly obnoxious. We have this one up in the living room, it just needed to be ligned-up today, so I took the opportunity to scan it in for you all.

# Posted by mpo at 09:54 PM | Comments (1) | TrackBack (0)

April 27, 2004
Productivity tools!

Sorry for not warning you properly. Enjoy the chasm.

# Posted by mpo at 09:40 PM | Comments (1) | TrackBack (0)

April 23, 2004
Nearest book, page 23, sentence 5.

This is a fun and mild way of wasting your time I'ld say, I'm in for sure!

The enclosing instance stores the sole reference to its finalizer guardian in a private instance field so the finalizer guardian becomes eligible for finalization at the same time as the enclosing instance. -- from Effective Java, Joshua Bloch.

Damn, this makes me look like a nerd again, just because Bruno asked me to bring this book along to the office.

It gets marginally better if I interpret 'nearest' not in the physical but the mental distance. This is my current bed-time read:

Geen twee waren er ooit precies gelijk, vertelde ze, en het besef dat er binnen een zeshoekig basispatroon zoveel variatie kon zijn was een openbaring voor me. -- from 'Oom Wolfraam en mijn chemische jeugd' i.e. the Dutch Translation of Uncle Tungsten: Memories of a Chemical Boyhood, Oliver Sacks.
# Posted by mpo at 08:03 AM | Comments (1)

April 19, 2004
The butterfly...

Here is a butterfly taking off

As you may know or not know, I've been doing some initial work on implementing a proof-of-concept of the form-handling ideas I shared in an earlier RT. I've just committed this code to CVS, in a "scratchpad" block named "woody". (don't be overwhelmed by the amount of classes: many of them are quite small) -- Bruno Dumon (22-04-2003)

Less then a year later there is a storm causing people to meet.

P.S. One gets so used to corresponding with people all over the world on these lists, so when I saw that you're in Seattle, it felt like we're practically neighbors (I'm in Portland)... "tell you what, forget the email, I'll hop on I-5 and come up and just come up and look at your code..." :-) -- Mark Lundquist. (17-04-2004)

You're on! The beer fridge is stocked... -- Joel McConaughy.

Finally some proof that software can make a difference :-)

Enjoy those beers dudes! We'll have some extra to celebrate.

# Posted by mpo at 01:09 PM | Comments (0) | TrackBack (0)

April 16, 2004
Morse

For this years anual friends-and-kids-weekend (somewhere in June) I'm supposed to make the parents-evening-quiz. They'll hate me for introducing old times memories. Hah, that should teach them not reading my blog :-)

# Posted by mpo at 01:00 PM | Comments (0) | TrackBack (0)

April 15, 2004
Exceptional bonus track

Here is a little trick I recently used to 'lift an exception over an interface'. A showing example of exception handling getting a bit hacky sometimes.

The interface at hand provides a call-back for processing a specific entry in a list. The list is type-aware, and the internal processAll avoids having the iterator and type-cast logic duplicated over all processors.


public class MyList {
    private final List entries= new ArrayList();

    public Entry get(int index) { return (Entry)this.entries.get(index); }
    public void add(Entry entry) { return this.entries.add(entry); }

    public static class Entry {
         // whatever builds up an Entry...
    }


    public static interface EntryProcessor() {
         public void process(Entry entry, int index);
    }

    public void processAll(EntryProcessor proc) {
        Iterator iterator = this.entries.iterator();
        int ndx=0;
        while (iterator.hasNext()) {
            Entry entry = (Entry) iterator.next();
            proc.process(entry, ndx++);
        }
    }
}

The EntryProcessor interface is lean and mean, nothing can go wrong can there? Well, I had to change my mind on that when I wanted to use the EntryProcessor approach to generate an XML listing (through SAX) of all the entries, by repeatedly calling a method that generates the SAXEvents for one entry... Something along these lines:


    ContentHandler ch;
    MyList allEntries;
...

    public void generateEntriesDocument() throws SAXException {
        ch.startDocument();
        generateAllEntries();
        ch.endDocument();
    }
   
...
    public void generateEntry(Entry entry) throws SAXException {
        ch.startElement(.....);
        ...
        ch.endElement(.....);
    }


In the listing above the generateAllEntries is missing since it's the actual subject of this posting. Let's try to see the challenge first. If I start iterating over the call to generateEntry() then I can get some SAXExceptions. And that's not a real problem since I do this in the context of the generateEntriesDocument() which declared the same exception so it can easily propagate onwards up the stack.

The problem comes however that when I use the processAll() and EntryProcessor interface to handle that iteration. Logically my process() implementation would just be a call to generateEntry(). Helas: given the no-exceptions-on-process() I'm obliged to choke up my SAXException from generateEntry(). Bummer.

I got out of the dillema by using an inner classes to (quite) easily lift the exception over the interface:


    public void generateAllEntries() throws SAXException() {
        final SAXException[] lifty = new SAXException[1];
        this.allEntries.processAll( new MyList.EntryProcessor(){
            public process(Entry entry, int ndx) {
                try{
                    generateEntry(entry);
                } catch (SAXException e) {
                    lifty[0] = e;
                }
            }
        });
        if (lifty[0] != null) throw lifty[0];
    }

And then I had a colleague pointing out the serious flaw in the above. This lifty guy is quite nifty, but he doesn't stop the interator that is running through the entries! We actually do need a RuntimeException to that goal


    public void generateAllEntries() throws SAXException() {
        try {
            this.allEntries.processAll( new MyList.EntryProcessor(){
                public process(Entry entry, int ndx) {
                    try{
                        generateEntry(entry);
                    } catch (SAXException e) {
                        throw new MyRuntimeException(e);
                    }
                }
            });
         } catch (MyRuntimeException re) {
              throw new (SaxException)re.getCause();
         }
    }

And given it some more thought in the end, I can't help thinking that some (checked) InterupptedProcessingException on the level of the process() and processAll() wouldn't have been all that bad.

# Posted by mpo at 02:05 PM | Comments (0) | TrackBack (0)

Exceptional wisdom (long)

Yesterday Ugo started an interesting new thread -[RT] Checked exceptions considered harmful- on the cocoon-dev mailing list. Included is some recommended reading:

With the above links Ugo calls upon some 'authority' to ban checked exceptions from our Java code:

For me this was not only a revelation, but after giving it some thought also an unquestionable case of 'het kind met het badwater weggooien'
That is dutch literally saying 'throwing away the baby together with the water that washed him' and proverbally means: 'when cleaning out you shouldn't let your enthousiasm get the better of you. Before you know it you've thrown away the real valuables along. The challenge is to keep seeing clear even if those so-called real valuables were somewhat the cause of you needing to clean up in the first place. (Having a saying like that kinda makes us carefull people, no?)

Looking for the value of things: Checked Exceptions are quite essential in my view of a design-by-contract approach. Taking the anology with real life contracts: Writing down that "I'll deliver this service for this price". We get for method signatures:

  • Service == return value and/or accountable state changes. (The guaranteed post-condition)
  • Price == valid input arguments and/or a predescribed orchestration between methods. (The expected pre-condition)
If the price is not paied (pre-conditions are not met) there is a programmig error. This is simply not what we agreed to do here, the caller defied the whole existence of the contract, he deserves no better then to get some RuntimeException. Translating this to code you get (often upfront) in your method a number of checks on the 'price' paid:

  if ( arg1 > something  )  
    throw new IllegalArgumentException("arg1 shouldn't be this and that");
  if ( badCurrentState() )  
    throw new IllegalStateException("Not ready to deliver service ABC." +
                                     "You should call/prepare XYZ first.");
  
  // what follows is the actual service code, below this point you have to live up to your end of the deal.
  // deliver the service!

Now we are in the situation where the caller lived up to what he needed to provide (the money) and there is nothing left but deliver as promised. There is a small nuance to make: We're expected to do a best effort (to counter for his effort). However the limitations of reality enforces some upfront decissions (foreseen memory space, foreseen file location and availability, foreseen/acceptable network delay,...) that might backfire during our best effort.
The challenge is to realize these limitations (decissions) and to openly communicate them to the customer during contract negotiation. Some of those problems he'll take away for you, adding it to his 'price' to pay and putting the responsibility to decide and handle on his side. For some of the problems you'll just agree upon some 'now this is a bit unlikely, isn't it?" to cover up for the "It's way to silly if I start checking all of that upfront: the price would be to high." And you settle for the opposite approach: "It's quite safe to assume all is well, instead of paying the price upfront." Which doesn't make you blind for the problems since we did acknowledge that things could still go wrong. So the settlement gets written down in the (typically called 'small print') exceptional cases part of the contract: We have just introduced checked excpetions.

So I have to agree with Ugo: checked exceptions are not a replacement for a good testing harnass. However that doesn't mean they have no value at all: I see it more a replacement for special case documentation that never got read. It's the machine enforced way to make you read the small-print sections of the contract, and provide some active way of dealing with them. On the same base, I don't see a conflict with what Leo entered into the discussion: Exceptions are (also) a signalling mechanism which are part of the normal execution. Just like small-print sections are a normal part of real life contracting.

Too bad, the story doesn't end here. Things get more complex, as they do in real life: enters 'SUBCONTRACTING'

As in real life, contract negotiations get more interesting when intermediaries are added to the mix: the clear communication between provider and beneficiary is fractured. The opportunity to easily look over the fence and see both sides of the issue, and find the optimal balance is dropped and replaced by the stress to do well for all, without actually having the time to consider all. Java interfaces are in this difficult position.
What goes on is this: a general (abstract) service contract is conceptualized (by an independant 3rd party?) even without actual users or providers for it in the neighborhoud. The stress is there to find a balance between:

  • 1/ Long lists of meaningless exceptions refering to endless deep implementation details as this results in needless long lists of handling code at the caller side.
  • 2/ Too little exceptions, because that leaves the subcontractor (implementation) in the frustrating position of needing to disguise his actual problem as a wrapped exception or a runtime exception.
Searching for some guidance in the search for this optimal balance it's nice to understand the implicit 3rd party communication and expectations behind the abstract interface:
To the consumer of the service it looks like the contract-designer had strong negotiations with (all potential) providers. And they've agreed to classify and group all possible detail thingies that can go wrong into those that need to be destinctly handled by him when 'normally' calling upon the service.
Reversely, to the provider of the service this same contract indicates that the customer explicitely negotiated with the contract-designer that he wants to be notified of certain meaningfull exceptional cases.

Assuming these considerations were made during the design of the contract I'ld have to conceed that the implementation frustration (what to do with all these exceptions) seems to naturally relieved in Leo's proposal (slightly rephrased)

  • If the encountered problem during your best-effort-try to deliver the service naturally matches the 'meaning' of one of the declared exceptions in the contract, then you use that.
  • If the encountered condition is proven 'big enough' for either side of the contract: throw an error.
  • Else, make it a RuntimeException. (possibly wrapped)

# Posted by mpo at 01:14 PM | Comments (0) | TrackBack (0)

April 10, 2004
Happy Easter!

Wish I could give you all real belgian chocolate easter eggs, but this seems a nice alternative. Enjoy!

# Posted by mpo at 07:55 PM | Comments (0) | TrackBack (0)

April 09, 2004
Family history

A nice read about how Apache works. Nicer then reading is just joining in the fun of course...

# Posted by mpo at 08:51 AM | Comments (0) | TrackBack (0)

April 07, 2004
Cocoon @ TSS

By now the recent TSS article on Cocoon is old news, but I just came across Rik's invitation to explain, so here goes...

(1) Rik observes that the world is still divided into adepts and adverts
Sigh, the division is all too often indeed between the enthousiastic people that use it and the sceptical people that never do. My question can only be: why is it that the second group has an equal weight in the discussion?

(2) The main reaction over in Cocoon land was that the article is outdated at the time of going public: Cocoon is now at 2.1.4 (in stead of the covered 2.0.4) which results in missing out on the most important new additions in the field of web app development (see an old posting of mine on those)

(3) Pro's and Con's ?
I think the discussion on TSS following the article should give a fair view. The biggest sweat-spot that keeps returning is 'Cocoon's sharp learning curve...' And it's hard to deny it as a pure and tangible fact of live (I remember struggling too). Yes, the documentation can always improve, but often the people asking for that don't know about the existance of the wiki which is actively helping out to a large extend... The fastest way over the curve (shameless plug for our teaching services) is often just having an expert over that takes you through a sample so you actually get to use it and feel for yourself.

(Even in these digital times, physical presence seems to make a difference)

Coming back on the believer/disbeliever, while trying to show this is NOT a religion (but quite the opposite): Using Cocoon is about allowing yourself to think different about your web apps. Consider it like the copernican revolution: letting go of the old view of the world; you'll see that the sun still goes up. So yeah, you'll probably never think about web applications in the same way again, that's the danger. In return you might discover a pleasant new programming model for your apps that scales up from simple and stupid to quite elaborate and otherwise hard to manage.

# Posted by mpo at 12:07 PM | Comments (0) | TrackBack (0)

April 04, 2004
Books for kids (and their parents)...

They deserve to get translated, but untill then you'ld have to learn some dutch to get into the depths of these two extraordinary books for kids (and their parents)

For those that require some more 3rd hand comments, the first one recently got some media attention on various places: 1, 2, 3, 4.

Enjoy.

# Posted by mpo at 09:15 PM | Comments (0) | TrackBack (0)

April 01, 2004

Keys over Mouse

Aargh, each one of these much reffered to lists of eclipse-shortcuts:

is telling me that [CTRL] [/] means 'comment selected block', but my eclipse 3.0 M7 seems to be missing the point. Am I the only one?

In case the regular reader was wondering: yes, I have a new keyboard plugged into the laptop :-)

Oh and very nice shorthand tip for cygwin users which I got from Karel the other day: add a alias e='explorer .' to your .bashrc, jummy!

*update* There is a 3M08 update of the shortcuts-sheet from the eclipse-tools project at sf.net.

# Posted by mpo at 04:16 PM | Comments (3) | TrackBack (0)

Amsterdam!
XMLEurope 2004

Just wrapped up my tutorial for the anual XMLEurope gathering. Uhuh, another JIT delivery. And not in the least cause there is again a lot to tell about what happens in the border-region of Java and XML lands. Innovation surely hasn't dried up yet.

Having the conference so close to home probably will account for a higher percentage of known faces, specially since we've been rather active in Holland lately. Not that you need to know a lot of people before attending. The last two editions I've attended there was just a great ambience of introducing/being introduced, extending the network of geek talk partners and freely sharing refreshing ideas.

The other things I'll be looking out for this year are:

Well, hope to see you there...

# Posted by mpo at 11:06 AM | Comments (0) | TrackBack (0)