Archive for June, 2003

Things your mother didn't tell you about Eclipse

Friday, June 13th, 2003

A lot of people seem, bizarrely enough, to think that Eclipse and SWT are a great idea. As far as I can tell, there are two main arguments that the SWT bigots like to wave about. Firstly, that it’s portable, so you lose none of the advantages of swing, and gain native power. Secondly, that it performs better. Of course, being the marketoid hungry lemmings that they are, they fail to think past those two mantras to question the underlying assumptions behind those two seemingly innocent ‘facts’.

Let us examine these claims. Yes, it can’t be denied, you can write swt code and have it run on virtually any platform! Oh wait, if you mean ‘run’ in any sense more vigorous that the ‘gee whiz ma, lookie at how cute this looks! It’s java n’all!’, then you’re out of luck unless you’re a windows weenie. I realise that linux zealots are now squirming uncontrollably and have their panties bunched up beyond all belief. Keep in mind that these are the same people who will, with a straight face, tell you that linux is more usable than windows. They’ll also tell you that linux is faster than windows, and that it has no security holes, and is prettier than anything else out there. I think we can safely ignore these people and hope they quietly commit themselves to appropriate institutes.

Back to Eclipse! I urge anyone who thinks that it is indeed a portable library to test against its intended nemesis, Swing, on various platforms. While the UI performance does win out in windows, in OSX Eclipse is downright hilarious. I’m firmly convinced that OSX users who do say they use Eclipse on a daily basis are either lying, or type and think slower than Christopher Reeve in a 100m sprint.

Oh yes, but at least it looks native, right? Actually, quite wrong. Eclipse on OSX is the stuff of nightmares. All the windowisms that OSX switchers have run away from come back to haunt them. Bizarre toolbars, inexplicable floating windows, and a UI almost determined to flout every single rule in the Aqua human interface guidelines.

The sad fact of the matter is that, like any project which is primarily Windows based, all other platforms are inferior second or third class citizens. So use Eclipse if you’re a windows developer, more power to you. However, save the world from your bigotry and stop preaching cross platform anything to anyone.

Ohyeah, and if you’re convinced that the beauty that Eclipse provides outweights the disadvantages of being platform specific, have a look at the jgoodies metamorphosis demo (fakelipse), where someone using pure swing shows how easy it is to look good without inventing square wheels.

XDoclet: beauty is very skin deep

Friday, June 13th, 2003

Don’t get me wrong, I like xdoclet. I use it in a number of fairly large projects (100+ ejbs). It gets the job done, slowly, but it works. I’ve had nothing but pleasurable dealings with Ara and Aslak. In fact it was Ara’s speedy responses and acceptance of patches that made me feel that it’s worth sticking with xdoclet. I do not regret that decision at all.

However…all is not well in the xdoclet world. XDoclet suffers from a number of fairly serious problems. I realise that xdoclet2 addresses a number of these, but for now xdoclet2 is nowhere near release, so I can pour my vitriol on xdoclet without feeling too guilty.

First of all, xdoclet suffers from astounding amounts of bloat. Picture IBM Websphere scale bloat. Picture TogetherJ (or TCC for the newer kids on the block). As much as I like hurling about abuse without substantiating it with much evidence, xdoclet luckily (for me at least) provides plenty of ammo. Let’s start with the ingenious plan of internationalising build messages. Yes folks, you heard it right. The XDoclet team has spent much effort in ensuring that their BUILD MESSAGES are internationalised. What is even more astounding is that some people have the gall to say that this is a great idea and a wise investment of time. No big deal, most of you shrug away and think, so what if they use a bunch of localised bundles and use keys off of them to output their build messages. Hardly a huge cost or that much trouble. I mean, resource bundles degrade nicely into the default locale anyway.

Haha! Fools! XDoclet uses its own, invented from scratch obscene monstrosity and dares call it a translator tool. What this ingenious little subsystem does is…well….it’s complicated, but lets just say it works exactly like MessageFormat. Yes, the very MessageFormat that comes for free in every JDK. Oh, the keys are also all hardcoded into some class too. So if you ever feel like adding a more helpful error message somewhere, you have to change 2-3 files at least. Needless to say, it’s impossible to actually identify if this new error message you want to throw is something someone already thought of. Either you’re the lucky chap who wrote all the keys in the first place and knows where they are, or you’re doomed to a) duplicate keys, or b) spend a few hours trying to track down the appropriate key to use. If you choose option b, you will start to hate your life and want to commit random acts of violence, so I’d advise against it.

Still, someone already did all the work, it’s all done now, it works, there’s no problem. Ha! wishful thinking. Let me just run an xdoclet build now and see what fun stuff shows up….Oh look: [xdoclet] RUNNING_TASKNAME arguments: [Ljava.lang.String;@e99fb6. Ah well, one rogue key isn't such a big deal. Oops, no, here comes: [xdoclet] GENERATING_TEMPLATE_OUTPUT_SINGLE_FILE arguments: [Ljava.lang.String;@988f4b. Lest you start making the ‘it’s CVS, it sometimes is messy’ excuse, I’ll have you know that these kind of messages have been there for months. In fact, ever since this wonderful new Translator subsystem was vomited into CVS.

Still, overall, it’s a good thing right? XDoclet is a truly international tool. All the languages it supports must mean it has a much lower barrier to entry. Err, wrong again. For all that fuss, the only translations available that I can see are English and Brazilian Portugese.

Moving on swiftly, let us consider the error reporting. If by some unhappy chance you stumble upon a problem in a template, then you have two choices. The first is to try and figure out which of the 10 pages of stacktrace has the secret info you seek, and the other is to beg and plead for someone to fix it. The first option requires a lot of spare time and patience. Especially as there are no tools to make the process vaguely comfortable. You need to invoke ant for everything. The second option is laughable, given that chances are,the person who wrote the template has now moved onto bigger and better things and will gleefully tell you it’s no longer maintained. Oh, and if you find the first option too easy, xdoclet will spice up your life by providing completely incorrect and random line numbers for the templates.

Still, it’s a heavily used tool, with a big developer community right? Many submitted patches and suchlike. Yep, that’s certainly true. However, it’s still a crapshoot whether anyone bothers checking your testcase and/or bugreport and/or patch. If you’re lucky some kind developer might take pity on you one day and commit it. If you’re unlucky it’ll be assigned to someone who finds the whole thing rather irritating and deals with it by pretending to be an inanimate object. Of course, if you’re stupid enough to report a bug without a testcase or a fix, everyone will just laugh and point.

Of course, you could be one of the lucky ones who happens to use the latest fashionable technology. If you use hibernate for instance, you’re in luck because it’s very much a flavour of the month. God help you in six months time though when all the cool kids have moved onto the next great thing and you’re stuck maintaining an unfashionable dependency that nobody cares about anymore.

Another problem with xdoclet is that it gives you enough rope to hang both yourself and a small village from the third world nation of your choice. Suddenly it’s become reasonable to embed datasources in java source code. Suddenly people want to configure their clustering from inside of java code. All the advantage of deployment time configuration wiped out by some thoughtless module writers. Just look at all the filthy things the struts people are adding, it’s enough to make one cry hot tears of shame into one’s soup.

Having said all that, it’s still a tool I use on a daily basis, so go out and use it and don’t be put off by these minor quibbles.

About that clover tool…

Thursday, June 12th, 2003

Clover seems to have become the long lost lovechild of all the TDD freaks. All good and well, it isn’t such a bad tool all in all. Needless to say though, it comes with its own brand of braindamageness. For example, why must there be a new testcoverage db file generated on every run? How hard can it be to use one file, like poor old unfashionable jcoverage does? Must some poor directory be littered with clover droppings?

Secondly, and this bit is against ant as much as it is against clover…why does one have to dump clover.jar into ant’s lib dir? Ant has a mildly functional classloader, so why doesn’t clover define a custom task that extends the javac task and so allows itself to be used as the compiler?

Of course, this wouldn’t be necessary if ant’s classloader wasn’t the ugliest stupid pile of code I’ve had the misfortune to lay eyes on in a very long time. I’d be amazed if there are uglier classloaders out there. I had the misfortune of having to look over this monstrosity a year or two ago when fixing a bug in it, and I hope for ant developers’ sake that people just use the damn thing and never peek inside.

All this could be forgiven if ant could be civilised enough to use its classloader on something more than a whimsical basis. Why should certain tasks get the benefit of it, and others not? Why can’t I specify a classpath(ref) for the compiler property, for example?

All this pales in comparison though to the severe braindamage that some ant users seem to be suffering from. Look over your projects, does the user have to do anything other than type ‘ant’ to build? he does? BZZZZT, you lose, here’s your village idiot hat. If by some chance you happen to require things like clover in your projects, then for the love of god, don’t just blow up with it isn’t present. Give the user a gentle and loving message as to how they may proceed. the <available> task is your friend, it’ll help if only you let it. Your users should not be exposed to pages of stacktraces. It’s unprofessional and stinks of OSS. Show a stacktrace only and only if it is helpful and not utter gibberish to the user. A well constructed coherent sentence can say a lot more than a stacktrace.

Finally, all you folks using build.sh and build.bat files to run ant, please find the nearest firing squad and ask them to put you out of your misery. If you want to use platform specific crap, then you should at least have enough shame to keep that kind of thing limited to your day job, and not proclaim your ineptitude to the potential tens of OSS developers who might find your project worth building.

Oh and those of you who feel that disagreeing with me automatically means I’m stupid, ignorant, and incompetent, well…I suggest you find a collection of sharp objects and insert them post-haste into a collection of orifices.

SAAJ ruined

Thursday, June 12th, 2003

A while back, we need an extremely lightweight SOAP client that would work in applets and rather thin clients. High performance was also pretty important. After some looking around, I couldn’t find anything that fit the bill. Everything out there wants to be both client and server. GLUE, while a nice product, comes with very mean licensing and its embedded version is still a staggering 300k. Not good.

I decided to implement my own soap library. Being the spec loving guy that I am, I decided to follow the SAAJ spec (soap api with attachments for java, or somesuchlike, version 1.1 at the time). The spec seemed pretty nice. A nice 15k jar with NO impl, leaving plenty of room for cleverness and fun.

I had a very fun week or two of writing my implementation. It worked, it followed the spec to the letter, nothing more nothing less. It also had rather good performance. 5-10ms average for SOAP call (not including server processing, but including networking). It allowed for BASIC http auth, and pluggable http authentication (ssl, digest, proxy handling, the lot). Best of all, it weighed in at 30k, and had 0 dependencies (not even an xml parser was required!).

A few days ago, I notice that SAAJ 1.2 is out. A minor revision supposedly that adds some convenience methods here and there. So like a good spec follower, I decide that I should update my soap lib to the latest spec.

Imagine my horror and dismay at a supposed tiny change introduced: ‘all soap element classes now extend their W3C DOM equivelants’. My world crumbled around me. My beautiful tiny library now had to implemented tens of useless irrelevant methods, and carry another 10-15k of deadweight, plus the cost of impl for that deadweight.

I’m not sure who should be blamed for this. It feels a lot like the request dispatcher debate that the servlet expert group went through for the 2.3 release. With some vendors (names not mentioned to protect the guilty) squealing ‘but it’s so hard for us to implement it in this nice user friendly way, so the spec should accomodate us!’. I realise most SOAP vendors care little for size or bloat, preferring instead of churn out be all end all solutions. Yes, SOAP messages are XML, but if you’re providing an API for SOAP, where the whole point is to ABSTRACT away the xmlness of it all, and provide convenient SOAP specific methods, why on earth would you want to say ‘ohyeah, you can just treat this like a normal XML Document if you want, even if half the methods are illegal or don’t make sense to call on soap envelopes’? Just because the RI sees fit to rely on xerces and various other braindamaged impls, is no reason to deliberately cripple everyone the same way.

The Apache Syndrome

Wednesday, June 11th, 2003

I don’t like jakarta projects, on the whole. Projects that have migrated to jakarta sometimes have a better quality feel to them, but that seems to have stopped after log4j. Apache seems to have become the Microsoft of open source Java. All about marketing and penetration rather than any quality or usefulness. Just being an apache project is sufficient. The clout and fashionability of it will ensure that no matter how poorly executed, the project will have countless lemmings extolling its virtues to high heaven.

Lets go through some of the projects:

  • BCEL: Very popular, goes hand in hand with the AOP fuss (at least, all the silly impls out there). Poorly designed, poorly executed, and performs terribly. Don’t believe me? Check out ASM from objectweb. over 10 times smaller jar, and 8 times the performance.
  • commons-*: Ugh. A wonderful case study of jakarta’s componentisation obsession. Endlessly splitting up things into single projects and jars, it’s just a matter of time before commons-commons.jar makes an appearance. commons-logging.jar rapidly becoming the most useless and overused library around. Why? Well, how often have you needed to switch between log4j and jdk 1.4 logging? Is it something you do often? Do you find yourself switching back and forth? I suspect for 90% of commons-logging.jar users, then answer is ‘well I just use log4j’. So why add another useless abstraction layer? If you don’t want to depend on log4j, then fine, use your own library or jdk14 logging. Don’t pretend you’ll be endlessly switching logging libraries every day. Some of the commons-* projects are so silly that I’m almost too ashamed to mention them here.
  • ECS: Great idea, for anyone stupid enough to expect developers to churn out pleasing well designed pages. Back in the real world, html pages are made by professional html designers. It’s an art, it requires a completely different skillset that writing java code. ECS ensures your html pages cannot be modified by an expert, and will retain that symmetrical drab tedious look that all developer written pages have.
  • Jetspeed: A tool built on turbine, which spawned maven. I shudder to think of the jarfest that ensures. I’m writing a JSR-168 impl which manages to not require any of those jars. So if I can do it, so can a team of so called world class engineers at jakarta.
  • Lucene: OK, Lucene is pretty cool and works as advertised. It does its job well, and has a cool job. I thought I’d throw something positive in just for variety.
  • POI: I remember back when I first saw POI, it had nothing to do with jakarta and was a cute effort that had some promise. At the time it was nowhere near functional enough for me to use in a project. I ended up writing my own xls parsing engine (read-only) which is now deployed at a rather large financial institute and used globally. For kicks I compared my library again POI a while back, and my impl outperformed POI by a factor of 5. Bummer. In time I stumbled across JExcelApi, which is a far superior OSS library that provides both read and write functionality, with no dependencies (none when I looked at it anyway). Needless to say, it also outperformed POI. Yet POI, by dint of being a jakarta baby, gets far more usage and publicity. Quality is clearly a secondary concern.
  • Struts: I won’t go on too much about struts, as many others already have. Struts is rather silly, and it’s a terrible shame that its bastard child JSF is somehow turning into a spec, which brings me nicely to…

    ..the terrible effect that jakarta has had on specs. For one thing, it’s resulted in tomcat, a product inferior to every single servlet engine out there, being deployed as a production system in some places. It’s resulted in people who get seats on expert groups just by being willing to write code for tomcat. All this of course comes with the usual mantras of open source zealotry. ‘But I have the source!’ ‘I can always fix the bugs myself!’ ‘I can keep working on it if they go out of business!’. For any of you thinking those things, count to yourself the number of times you used the source beyond glancing through it and ooh’ing and aah’ing, the number of bugs you fixed on that source, and the amount of work you’ve done on it. I take my proverbial hat off to you if that number is even fractionally over 0.

    In closing, I wish people who see Jakarta for what it is. Just another code repository. It is not a seal of quality. It has much mediocre code, some good stuff, and a lot of truly awful stuff. Marketing and exposure are not the end all and be all of software development. If you won’t accept those things from Microsoft and IBM, then you should be ashamed for accepting them from Jakarta.

  • If only dynamocks worked

    Tuesday, June 10th, 2003

    So based on some buzz that’s been going round, I decided to give mockobjects a try in my testcases. I’m implementing JSR-168 for our portal product and so I thought it’s a good chance to get to play with mockobjects and the dynamic mocks that people have been drooling about in various fashionable circles.

    It’s all going swimmingly well, until it’s time to do something beyond the utterly trivial. For the uninitiated, the idea behind dynamic mocks is that you can specify an interface, return values for various methods, and expected values for various things. The idea being that you can mock out your classes and then use the resultant proxy classes instead of the real thing, which might have too many external deps, or require a db, or all sorts of other junk that gets in the way of smooth and fast testcases.

    The major flaw with dynamic mocks is that the return values are for all intents and purposes static. So for example, you can specify something like myMock.expectAndReturn("getBlah", "blah"); but cannot express something where the return value is not static. Why might you want to do that, you might wonder. Well, lets say you want to create a mock object for ServletContext, you’d want to be able to specify a Map that methods like getInitParameter and get/setAttribute work off of. Alas, this is impossible without much arm twisting and ugly hackery. You basically have to implement your own CallFactory which has all the extra magic in it. Maybe I’m missing something, but a less braindead solution to me would be to have the possibility of return values implementing some kind of interface, and in that special case, use a callback to determine what the actual return should be.

    The more fanatical mock objects users might start squealing now about the prexisting mock objects for standard java libraries, such as the servlet API. I tried to use those too, but they’re equally if not even more braindead. For example, they do not allow for arbitrary method calling. To the MockHttpServletRequest for example, it seems unacceptable to call a getAttribute twice in a row, so much so that it blows up with a mean and unfriendly error. You’re only allowed to call a getAttribute after a setAttribute for that same property. The provided mock objects are filled with such pedantry, where expectations have to be incredibly explicit and strict.

    Needless to say, this all fails horribly when you’re trying to develop a library where the user is expected to try unexpected things, and to abuse your impl as much as possible.

    So, java-mockobjects is yet another decent idea, which will make you feel very cool and fashionable for using it. The downside of course is that you’ll spend more time cursing it and trying to twist its arms to do what you want than actually writing the damn testcases.

    Motivation

    Tuesday, June 10th, 2003

    Alright, I decided to start a blog. Not because I feel the love, not because I want to be part of anything. The reason is in fact is my disgust at the endless circlejerk that most java bloggers seem to be indulging in. It’s so draining hearing people talking about stuff like:

  • My friend so and so now has a blog, check it out!
  • My project so and so is very cool, download it!
  • My company is great, everyone loves me!
  • I visited/will visit some friends yesterday/today/tomorrow
  • Listen to my endless tedious opinions about how great design pattern X is.
  • Go over to so and so’s blog to see other stuff I think is cool
  • I went to the cinema and saw movie X, it rocks/sucks/makes me want to post endless links about it.

    Now, if you’re here to find some kind of solution, salvation, or hope, then move along now. It’s a blog, it doesn’t need to be well written, logical, or even coherent. I’m going to bitch and moan about everyone and everything that annoys me (and it’s a huge long list). I just hope I don’t get bored within a few days of ranting and raving.

    I’m not an angry bitter man, it’s just rather pleasurable sometimes to let those aspects of one’s psyche go play a bit.

  • Why Maven Sucks

    Tuesday, June 10th, 2003

    Now that a lot of the initial glee and excitement over Maven has died down, it looks like people are finally waking up and realising what a truly horrific idea/product/impl maven is. So, here’s a brief overview for those who are still undecided. Note that this rant is purely from a *user* perspective. I don’t use maven in any of my projects if I have any choice in the matter, and generally try to avoid it. My exposure to it has been through JIRA. At work we’re jira licensees and have done some weird and wonderful things to the source code, so this requires some familiarity with the JIRA build process, which uses maven in the latest release.

    The first oddity I notice is that there’s a global repository where maven gleefully dumps all its jar files. Yes folks, the global CLASSPATH is back. Maven has successfully resold a concept that went out of fashion in 1998. The Apache name ensures that fashion victims everywhere swoon and start bleating about what a wonderful thing this is. This means that projects are now no longer the isolated units of joy they are, with their own dependencies, this means you now have global jars. Woe unto you if you have the same name jar with different contents in different projects.

    Secondly, Maven does not work out of the box on OSX. It requires you to define a JAVA_HOME variable. Ant does not. Ant has OSX magic in the ant shell script. When quizzing a Maven developer about this, he arrogantly pointed out to me that EVERYONE MUST define JAVA_HOME. The fact that I don’t have to do so under OSX is a BUG, and I should take it up with Apple for having a broken JVM. How very typical, forcing users to jump through hoops for no good reasons other than a retarded developer opinion.

    Of course, this is before we consider JIRA’s usage of Maven, which also brings about its own set of trials and tribulations. JIRA is split up into a number of subprojects (4-5). The fun part is that some of these subprojects depend on one another. Eg, we have component A depends on component B depends on component A. So to make an API change in component A, which component B depends on, you need to build component A against an OLD version of component B, then rebuild component B against the new binary of component A (I’m skipping the lets-copy-jars-and-figure-out-what-to-name-and-where-to-put-them obligatory dance when it comes to Maven).

    Oh and of course, there’s the obligatory jars being misnamed, misplaced. The veritable plethora of random cvs jars, and suchlike and so forth.

    The fundamental flaw with Maven, in my opinion, is that much like other Apache projects, it solves a side effect of an underlying problem, rather than addressing the problem itself. The project came about because Turbine or somesuch had too many dependencies. Now, instead of the sane and reasonable solution of ‘we need to reduce dependencies’, they decided that it’s better to go crazy with dependencies but write yet another tool to manage them. No doubt that road will in turn lead to yet another tool to manage maven.

    So, I beg of everyone involved in any open source projects, please boycott Maven. I don’t want it fixed, I don’t want it improved, I want it to just go away quietly. Those who used it can still be mocked now and then, but time will heal all wounds, and in time, they can be accepted back into civilised java society.