Translate Languages

Youarehere You are here: Home Arrow 2008 Arrow 07 Arrow 29 Arrow infradeath.html 

29-Jul : Death of an infrastructure

Ok, this is a potentially long story. I usually don’t write them because it takes me too much time to consolidate my thoughts on paper (keyboard), and anyway most of the people won’t consider this. But, what the heck, if Joel Spolsky can write about pretty much everything, I can do it as well.

The whole point is that I cannot withstand anymore the whole Java stack and all the related infrastructure pieces. Oh, we are talking about web applications obviously. I find it really disappointing and counter-productive. I have an even worse opinion about it than Agent Smith has about humans in The Matrix. The rest of this article is just a plain rant, you can stop reading now.

To get started, suppose you have a traditional Java based web application. Being a traditional developer, I adhere to the best practices and lay out my architecture accordignly. It’s so well designed that could fit in a school book:

  • a relational database on the backend
  • Hibernate on top of it
  • Some abstractions of mine to facilitate data access in some cases
  • an IOC framework on top of it, be it Guice or Spring
  • More abstractions of mine to hide direct data access behind services . I mean, not webservices, just plain pojos that act as a facade to hide the real data. For what? I don’t know, but hey, in the future we may have to expose real webservices and it would be ready with a minimal change (they say).
  • a Web framework on top of it (or beside, depending on how you like to draw diagrams). Say, WebWork like.
  • some JSON library and/or other AJAX related server-side proxy because if you don’t do ajax today you’re not event entitled to call yourself human. Such library obviously produces and consumes pojos out of JSON ready to be used in my code.
  • a bunch of interceptors to handle cross-cutting issues. The usual logging, authentication, blahblah mess.
  • a bunch of JSP 2.0 tags to deal with issues that Actions are too noble to be bothered with.
  • and then, on the client, more libraries. At least one to abstract all the language implementations incoherences (Prototype ? JQuery ? Who cares ) and clearly some fancy UI widgetry ( this could be the YUI , the Dojo Toolkit or whatever else. In my case, it’s a completely different case altogether ).

So far pretty standard, isn’t it? I bet that in at least half of your projects you have used a similar setup, and in the other half you just changed some details. And I haven’t even considered some features that are nowadays traditional, such as webservices, RESTful APIs. Nonetheless I bet this setup is familiar to most of you. Even if you read every day on DZone.com how to create the next best app™ with 2 lines of Erlang, after your morning coffee you’ll still end up beating your keyboard with thousands of Java lines of code.

Sorry, I can’t hear you, what are you saying? EJB, BPEL, Service orchestration ? I don’t even want to consider that names. The scenario I’m about to describe infernal enough without the need to add further players ( I’ll have to pay a fee to IBM for this sentence ). But more on this later.

Now that you have your stack ready, you need an application.

Today we are dealing with cows. A cow has many steaks and a farmer has many cows. And you working on the ultimate application to allow farmers to survive in the mind-boggling world of cow management. They usually sell their cows to the butcher, so they don’t care about steaks, but today they have a new feature. They want to get rid of the butcher and sell the steaks by themselves. So now a farmer has also many steaks.

And this is where hell breaks loose. You have to enhance your application to serve the new need. In the farmer details page, you want to provide a steak management function where the farmer can add or remove steaks to its stockpile. In case you don’t know, steaks are uniquely identified by their unique name (or RFID tag if you prefer), so you cannot just treat them like numbers. A bit of respect! And a steak can be shared by multiple farmers (you never understood this requirement, but management said it was utterly important).

And here it starts. You upgrade the database creating the new relationship and necessary linking table. But since you’re a savvy user, you just don’t fire the SQL directly: you write a Java class that represents the migration, so that it can be inserted into the streamlined change management process and rolled back if needed when applied in production. And you write the associated unit test. And the integration test against your test db.

Then you upgrade your hibernate mappings. Then you upgrade the pojo mapped by hibernate with the new relationship. And you write the unit test. Oh, well, and the FarmerValidation.java rules as well, since he cannot have more than 1e9 steaks for monopoly reasons. And you write the unit test.

Then it’s time for your abstractions over the database. Since you have been so smart to declare that you won’t ever use SQL again (why? why? why!) you have to write a 200 line long method full of hibernate criterias to be able to extract the data (needed for the uber-useful steak selling trends report) that would have required 2 lines of reasonable SQL joins. And the unit test. And in the meantime you decide that this can be useful in the future, so you create a utility class to refactor this behavior. And the unit test. The fact that you’re not reusing 99% of the utility classes you created before doesn’t ring a bell. Anyway they all lay scattered around somewhere in the codebase. And don’t forget the unit test for the utility. And a couple of Mocks since later on you’ll want to write unit tests abstracting the dependencies.

Now you wire up your IOC so that FarmerService.java now has a SteakMarketplace.java instance injected. And you unit test the Guice configuration file, obviously, to make sure that noone even remotely thinks about changing your service bindings. Time to enrich the couple of affected webwork actions and you’re almost done. And the unit test.

Since the feature will be ajax enabled, don’t forget about your JSON library, which will need a SteakToJsonSerializer.java otherwise it’ll serialize the whole steak graph and you’ll end up with your whole db inside an html page. And the unit test.

After a bit of struggling with the JSP pages to accomodate the new layout where the AJAX stuff will be injected, you feel you’re so close to finishing. But hmmm, now you have to test the JSP layout. HtmlUnit is perfectly fine, so you spend half a day updating the existing HtmlUnit test, because clearly you don’t remember a single one of the 20 xpath selectors you used in the test so far.

Finally on the client side, you have to create a new widget, according to your library rules, to fetch and display the promised steaks. And a bit of JSON-to-a-different-js-object conversion, since the library you are using doesn’t precisely accomodate your needs. And the unit test, that will be JsUnit for the occasion. And some more trickery, since the way data are sent back to the server doesn’t exactly conform to what Webwork expects, so you end up coding (and testing!) an hack to inject your data on the onSubmit() event, which in turn causes infinite troubles because it disrupts the prepare-validate cycle the way your web framework thinks everybody should follow.

At last, you only need to write the integration tests. At the time, when you decided to use Selenium, it appeared the perfect choice, but now you struggle for half a day with the Selenium IDE, unbelievably complex xpath selectors, and 10 more integration tests that pass through every possible crazyness your farmers may decide to try (except for the one they will actually try and you didn’t think of).

Final result for a feature that is equivalent to adding a multiselect box in a plain old traditional html form in a plain old traditional html page? Lines of code in the orders of a few thousands, that span at least 4 layers, 15 or so new classes ( three never-reused utilities ) and three or four dozens of new unit tests. And three weeks of work. During such period, obviously, farmers changed their mind and decided to sell milk instead.

I am sure that you have encountered the same situation in your past experiences. I am sure that you have tried yet another framework that promised to abstract everything away and you ended up only raising the level of abstraction and writing tons of code against it to circumvent its model leakages. And I am sure someone tried to convince you that everything could be solved by giving a BPEL-SOA gui designer in the hands of some consultants and forget about the code. And I am sure that this situation applies to a thousand different cases if you change the names here and there.

For how much you might like to write code day and night, this is not exactly paradise. Not sure about where the culprit really is, but I see a lot of fingers pointed to the Java language and its statically-typed dumbness. And the thousands of frameworks that try like crazy to make it appear as a loosely typed ultra-flexible scripting language.

We should measure engineering effort in terms of squared pixels. The less squared pixels your feature requires to be displayed, the less you should spend on framework-ish work to get it done. Unless you’re an Apple engineer, but this is a different story.

Give me ruby, rails, python, javascript, groovy or whatever else, but save me from more framework-ish java. And give me back plain SQL! Now! Or at least until the next best framework™ comes along.

Riccardo Govoni, last modified on Nov 7, 2008 - 16:46