Lies, damned lies and statistics.

Matt Raible has a post asking people for various statistics about their web framework of choice. He’s asking for numbers for the following:

  • How many tools (i.e. IDE plugins) are available for your web framework?
  • How many jobs are available for your framework on Dice.com? What about Indeed.com?
  • How many messages where [sic] posted to your user mailing list (or forum) in March 2007?
  • How many books are available for your framework?

What on earth does he intend to do with them, I wonder? All of these numbers superficially look like they should be “more is better”. On second glance, they’re anything but:

  • If you have lots of IDE tooling available, it probably means the configuration for the framework is overly complex and unmanageable without it.
  • The framework with the largest number of jobs available is probably Struts 1. Enough said.
  • People only post to user lists when they are stuck. If the framework is hard to use, there will be lots of e-mails. If it has a steep learning curve, and/or the documentation is poor, this will be particularly so. On the other hand, an active list might point to a large active user base. Who knows which is which from a raw figure? It might be better to find the number of posters, not the number of messages.
  • If your framework is fairly stable, and someone has written a fabulous tome on it that is universally acknowledged as “the bible”, few people would bother writing another book for it. Niche books usually only get written if there is no book currently in that space or if the existing books are rubbish and the author(s) think they can do better. How many books are written is therefore a function of the number written on the subject before a good one arrives, and how stable your framework is. The first is a small random number, probably. The second number is “more is worse”, assuming you don’t like frameworks that change under you all the time.

So, I guess I’m curious what extrapolations Matt intends to make from these figures.;-)

Variable node-height CSS trees (a work in progress)

I’ve been playing with CSS trees lately, but all the existing solutions I can find don’t quite do what I want. The requirements are:

  • Support for variable-height nodes (this seems to be the real killer).
  • Plus/minus icons to expand/collapse nodes.
  • Support for scaling the tree with font size, preferably including the padding around the lines and things.
  • Standard tree lines to link nodes together.
  • Fairly clean HTML, although I’m willing to sacrifice this for something that actually works.

Sounds impossible? Well, it’s not: Have a look at what I’ve come up with so far (doesn’t work in Internet Explorer quite yet).

View source to see how it works. Essentially, I nest everything deeply, and use the borders of the nodes to draw the tree lines. I then shift the plus/minus icons and the actual nodes with negative margins so everything lines up. This has the side effect of only requiring two images (one for the plus icon, and one for the minus).

Unfortunately, it currently uses nested CSS child selectors, which of course Internet Explorer doesn’t support (even IE7 doesn’t do this right for multiple concatenated selectors). I’ll try to make this work with IE shortly, but in the meantime, use Firefox. If I can make it fly in IE6/7 then needless to say, I’ll package this up into a Wicket component at a later date (possibly even in time for wicket-extensions 1.3.0 final).

If anyone has seen a better way of doing this, please shout.

More on java.io.NotSerializableException debugging

Eelco took my original ten minute hack and ran with it, and has produced something that covers a lot more edge cases. It handles anonymous inner classes, externalizables, things with custom writeObject() functions and a bunch of other stuff. It also plays nicely with SecurityManagers. You can find the code in Wicket 1.3’s SerializableChecker.java. It has a couple of custom Wicket bits, but would be completely trivial to strip those out if you wanted to use this somewhere else. At about 700 lines, it’s a bit more complicated than we both expected it to be, but it’s pretty robust. Good work Eelco!;-)

— UPDATE —
Bob Lee has a different way of doing this.

java.io.NotSerializableException in your HttpSession

Ever had a java.io.NotSerializableException in your code and found it very hard to debug? The JVM stack trace is nearly useless, telling you which code triggered the serialization, but not what it is trying to serialize.

Particularly tedious are HTTP sessions that refuse to serialize. In Wicket we store detached components in the session between requests. If you run a clustered app-server with session replication and add objects to your components that don’t implement Serializable, you’re toast. To avoid you deploying something with this issue and getting fired, we have a setting in development mode that tries to serialize the session on every page request. Unfortunately, although it helps you spot this problem early, it’s lumbered with the same unhelpful java.io.NotSerializableException as everything else in the world.

How do we make these issues easier to debug? Well, I’ve just written an ObjectOutputStream subclass which produces output like this:

java.lang.RuntimeException: Unable to serialize class: com.foo.C
Field hierarchy is:
  Class com.foo.A
    public com.foo.B myFieldForB
      public com.foo.C myFieldForC < ----- field that is not serializable
	at DebuggingObjectOutputStream.writeObjectOverride(DebuggingObjectOutputStream.java:105)
	at DebuggingObjectOutputStream.writeObjectOverride(DebuggingObjectOutputStream.java:96)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:298)
	at DebuggingObjectOutputStream.main(DebuggingObjectOutputStream.java:28)
Caused by: java.io.NotSerializableException: com.foo.C
	... 4 more

Continue reading java.io.NotSerializableException in your HttpSession

DSPAM with VExim and folder-based training using Courier IMAP

Spam is getting worse, so I’m trying out DSPAM. I’ve added it into my vexim set-up and although it’s early days, things are looking promising.

I run various accounts with IMAP/POP3. For the POP3 users, there are training aliases to forward incorrectly-classified mail to. For IMAP users, it would be much more convenient to have DSPAM learn from a folder instead – drag and drop is easier than click, click, type, click.

I found a bash script which does nearly the right thing (using Postfix). Here’s the tweaked version for VExim/Courier.
Continue reading DSPAM with VExim and folder-based training using Courier IMAP

Using a servlet filter for 404 error-page

The upcoming Wicket 1.3 and 2.0 versions intercept their requests using a servlet filter to provide more flexible resource mapping and nicer URLs. Your Wicket pages no longer need to live at foo.com/app/PageName and can instead be rooted properly at foo.com/PageName.

This is now working well. I did, however, come up against a small issue, which is how you serve custom error pages for your 404 or 500 responses. It’s nice to render these like any other pages, so you can use your branding and whatnot. This used to work fine with Wicket as a servlet, but switching to a filter broke things. I did some digging around before reading the servlet spec in more detail and finally realising you need a Servlet 2.4 spec container and web.xml config file, with some <dispatcher> elements in your filter mapping.
Continue reading Using a servlet filter for 404 error-page

More on boilerplate and IoC

Java has lately been seriously annoying me in this regard. Why do I have to write getters/setters for beans? Why can’t we just have a property keyword instead that does it automatically? Why does everyone insist on using getters/setters in the first place rather than public fields anyway? What’s the point? Ah, yes, we need to be able to proxy the methods through cglib for Hibernate, or via Spring’s IoC/AOP stuff, so we can write “better” code with fewer dependencies.
Continue reading More on boilerplate and IoC