Saturday, September 4, 2010

My issues with Spring

One of the things I've had to come to turns with as a professional Java developer, is navigating the massive chaos of frameworks out there. It doesn't really matter which corner of the development stack we're talking, in Java we're sure there won't ever be just one official standard; if we're lucky, we can identify a state-of-the-art de-facto standard and if we're *truly* lucky, our choice will remain a good one for longer than a few years.

One of those de-facto standards appears to be Spring. There is little doubt, that IoC (Inversion of Control), or more specifically DI (Dependency Injection), can be a great tool to decouple concrete dependency layers. However, in my opinion Spring introduces just as many problems as it solves, and here's my take on why.

Everything and a Kitchen Sink
While Spring does address IoC/DI, it also does a gazillion other things as well - as evident by looking at the Spring maven repo. On one of the project I was on, my Maven POM ended up holding 15+ dependencies to Spring related technologies, leading me to categorize Spring as containing everything and a kitchen sink. Spring is so many things in one, that it's hard to fathom let alone explain the boundaries; there's Spring JDBC, Spring MVC, Spring Security, Spring Remoting, Spring AOP, Spring DI, Spring RESTfull and probably much more that. Each part may very well be useful in their own right, but one can not help but to be weary of this creeping featuritis.

Abstraction layer madness
Most of the frameworks we use, take the shape of some sort of abstraction layer shielding us from hairy details further down. However, from navigating a Spring projects various configuration files and Stack traces (btw. confirmed by Nasa of being visible from space), I get reminded of a short conversation between two luminaries within our industry.

Computer Scientist Butler Lampson is known to have said:
"All problems in computer science can be solved by another level of indirection"

Whereto David Wheeler supposedly responded wisely:
"...except for the problem of too many layers of indirection."

In other words, perhaps we should be careful not to get blinded by magic frameworks which, when everything gets added up, turns out to be as much a disadvantage as an advantage. In this day and age, arguably it's the frameworks rather than the programming languages, we spend the most time understanding - but where we should spend our time, is in solving our clients problems.

Configuration madness
The inventor of Java, James Gosling, is known to have said something along the line of
"Every configuration file ends up becoming a programming language"
Now, if you've dived into Spring, you know this is very much true. Inevitably you'll find yourself looking up documentation trying to figure out what XML to write, where to write it and in which order. There's a trend towards depending on intelligent IDE's in order to conquer this type of complexity, but honestly that feels more like treating the symptom rather than fixing the actual problem. This goes for annotations too btw. which is often abused as a type-unsafe embedded DSL sneaked in by language designers who gave up on trying to innovate by adding first-class language constructs.

No bashing of framework overuse can be complete, without a reference to the Hammer Story. While I understand that we do need frameworks and they can indeed help us solve many problems faster and better, Spring is one of those I just can't recommend. Perhaps it's just me and my interpretation of KISS, but since a picture says a thousands words let me end with one.

So if you're one of those who heard about Ioc and DI, but haven't quite made the jump yet, I urge you to try an alternative to Spring, one that does indeed reveal up front how deep the rabbit hole goes. Google's Guice is a good candidate, and it's a testament to its simplicity that it has been ported to other corners of Java i.e. Android.

Update: It seems even Maven is now using Guice.

Update: I had no idea that jotting down my experiences and associated feelings about Spring would cause such controversy. It's clear that Spring is working fine for many and/or is worth the extra complexity. For the record, I don't hate Spring but just find that perhaps we should question whether it's really needed before pulling in dependencies from left and right.

So take this for what it is; a developer questioning whether we can't solve our problems in more elegant and lean ways than what the Spring stack has to offer. I think that often we can. Although at the concrete level I primarily address Spring IoC/DI above, the mere vastness of Spring makes it impossible to go into every aspect even if I had the knowledge to do so. "Pick and choose what you need" is a valid argument of course, but for now I remain unconvinced. Try to imagine the state of your applications dependencies a few years from now. Or try to imagine adding a new green developer to your team and how hard it will be for him to become productive.

The one mantra that truly never failed me is to Keep It Simple Stupid.