Taking charge of frameworks
Who is in control?

Modern software projects are largely built on the shoulders of third party frameworks and tools. But the tools can sometimes become more hinderance than help. How does this happen? What can we do to make sure that we drive the frameworks and they dont drive us?
End of the affair
I was coding on a recent project when it dawned on me that I had fallen out of love with the build tool Maven. Once upon a time I have to admit I did love Maven. As a build tool it had made my life easier. I could now do many common things quickly and easily, and I was appreciative. At least initially. Then the day came when I wanted to do something a little different with my build. Maven, rather than being there to help me, suddenly became an obstacle to that new but in no way onerous task. For the first time I had to register both the costs and the benefits of using this tool and question if it was still worth using it.
How does it happen?
Lets take a look at how we come to be using a framework. We have some problem, we see that framework X makes it easier. We take a punt (meaning of course exhaustive research and due diligence), and decide to adopt it. We then have a honeymoon period as we go through and apply our shiny new framework acquisition to the many low hanging fruit around our project that fall well within the framework's domain or area of expertise. So far its benefits all the way. Every step seems to validate further the decision to bring the tool on board. (Note this is probably the best time to ask your boss for that pay rise you were hoping for).
But slowly we see something new creep in. Things get a little harder. The tasks that we now want to accomplish don't seem to fall so easily within framework X's reach. Its not to say that they were in any way difficult tasks. Before we had introduced X, it would have been easily enough accomplished. But with X involved we find that in order to get the job done, we either have to bend X to allow it to do the new task, or take a big step to get around X in order to do it ourselves. What has happened here? Our project has become so enamoured with the perceived benefits of X that we were quite happy to streamline it front and centre into our project when we were picking off the easy stuff. It was only once we got to some of the harder stuff that we discovered that there might be some cost involved. If only we had known about the costs of using X up front back when we making the decision to use it a year ago!
This is not to say that we should never have used X in the first place. For my recent project the tool was Maven, and although we began to discover a lot more cost down the road than I for one ever anticipated, I still feel it was the right choice to make at the time. Even now on the balance of the benefits and the costs, it was I still believe we come out well on top. But this does little to soothe my disappointment, and disillusionment with the tool.
What can we do?
So what could I have done differently, way back then, when the decision was being made? Is there anything I could have done to have been able to more accurately gauge the costs and benefits of applying this tool to my project? Well, almost certainly yes.
A little more homework
The more you can learn about a frameworks costs and benefits, the better. But this is not always so easy. To fully appreciate both sides of the story, you need to look a lot further than just the framework's own web site and documentation. Invariably, its own literature will go to town on its strengths, showing you how you can begin picking all those low hanging fruit for yourself and how easy it will be. To get the other side of the story we really need to rely on outsider's experience in lieu of any of our own. What competing tools are there out there that we could use? Who has used them? Why did they choose them over X? Does X have a user forum or mailing list? What sort of questions are being asked? Are there any that don't seem to be getting satisfactory answers? Perhaps it is difficult to find much of anything written about X that you can take on board. Does this suggest that you would be a very early adopter (with an increased risk profile)? Or perhaps X is a technical outlier for a very good reason?
A more demanding test drive
Even with as much of other people's experience that we can take on board, we have to remember that every project is different. The costs and benefits of using X on one project will differ from those experienced on the next. Understanding our own project's requirements now, and having some sense of where these may lead in the future is vital for establishing what X applied may look like. We should put this to the test in a practical sense and try to test drive X within our project (or a branch of) on a range of different use cases - not just the low hanging fruit. This is much like the Tracer Bullet idea that the Pragmatic Programmers speak about, or the Walking Skeleton that Pryce/Freeman describe, except that we may be talking about an existing project already at some point of maturity. Regardless, the feedback we get from trying X on some of our own project's more demanding use cases will give us a good idea how easy things will be, and where we are likely to find pain.
Going forward
So our research comes up ok, and our test drives are looking good. We decide that we want to use X in anger. What can we do to protect ourselves from the decision we have just made backfiring? There are a couple of things.
Remember what its there for
It seems like a trivial idea, but we must remember why we considered using X in the first place. What problem were we trying to solve? It was that component Y couldn't service 1000 concurrent requests without falling over, right? We should right this down somewhere where it wont get lost. Somewhere permanent, where we have a record of the decision we are making. That way if we ever need to revisit it, we can see why and how the decision got made.
The first reason that we need to remember this is that if the problem goes away, (ie Y becomes redundant, or no longer needs to scale to 1000 concurrent requests) then we no longer have the original basis for using basis for using X. We may have also decided in the meantime to use X to solve some problem that component Z has, but that is a separate concern. In other words, if the requirement disappears, so should the solution.
Scope its use
X may have what we need to solve Y's scalability problems, but it may also come with all lots of other whizzy bells and features that look great on the glossy marketing sheet, but have nothing to do with Y's requirement. Now that we have onboarded X, it can be awfully tempting to start using some of these bonus features elsewhere in our project. The trouble with this is that X has managed to bypass our technical due diligence. These features may be good for us, or more likely they may be seriously compromising. (We've all seen the web frameworks that despite being MVC oriented, 'just happen' to have SQL support right out of the view layer!). I'm not pretending its easy, particularly on larger projects with many developers, but without scoping the usage of X to just the problems that we have decided to use it for, we may find that we are committed to the wrong tool for the job, even later if we no longer need it for its original purpose.
Having a backout plan
If there is one thing for certain in software it is that nothing can be taken for certain. Today's critical requirement could be negated by tomorrows, business change. As Dave Thomas and Andy Hunt (of Pragmatic Programmers fame) put it: "There are No Final Decisions". Retaining the reversability of the technical decisions that we make is not always easy, but every aspect of our software needs to be ready to adapt to change. This includes any frameworks that we choose to use. We should always be ready and able to back away from any frameworks or infrastructural code that we use to support our domain specific development work. At the end of the day it is our domain specific code that is most important, not the frameworks or infrastructure that we use to support it.
Theres probably no getting away from the reality that modern programming is to a large degree about stitching together frameworks (http://reprog.wordpress.com/2010/03/03/whatever-happened-to-programming/) We may not like it but we owe it to ourselves to make sure that we are discriminiating in the frameworks that we use. We need to make sure, that we control the frameworks and tell them what to do, rather than they telling us what we cannot.
[photograph Jan Tik - Creative Commons License]
“The maven, osgi, & spring combo, is about to happen”
.... taking a quick quote from Jilles Van Gurp, that I couldnt help but agree with.
The combination of dependency injection (Spring), runtime modularisation (OSGi) and compile/package time modularisation (Maven2) seems powerful, interrelated, and somewhat inevitable. The degree of crossover between these tools however suggests that some of the architectural design flaws in Java itself with respect to packaging and reuse are now bubbling to the surface in several places at once.
With the lack of language support for modularisation, it will be interesting to see which (if any) of these three technologies becomes the central tool in a developers toolkit. Considering the degree to which the Spring guys have embraced OSGi, my money would be on Spring.
Forthcoming books in the RESTful WebServices space
There seem to be a number of promising books upcoming in the RESTful WebServices space....
- RESTful Webservices Cookbook - Subbu Allamaraju, Mike Amundsen - progress and content breakdown
- “GET /connected - Web-based integration” (working title), Jim Weber Savas Parastatidis, Ian Robinson - see also article on infoq
- “RESTFul Java” - Bill Burke - looks likely to focus heavily on JBoss's JAX-RS implementation RESTEasy
- "RESTful Applications with Microsoft Azure" - Alan Dean
Any others out there?
RESTful Web Services in Java
Ive been soaking up pretty much everything I can find on REST recently. Some time ago I was about to start a new human web project, and thought designing it RESTfully might possibly be a good idea. Since then, I have read Sam Ruby/Leonard Richardson's excellent tome RESTful Web Services, and have become convinced that it is.
Being a long time Spring advocate, I have watched closely the gradual emergence of Spring 3.0, which is looking to fill in a lot of its gaps in REST support. Most interestingly, its server side implementation has come as the next great adventure with Spring MVC, and not its already mature Web Services effort framework.
Spring of course is certainly not alone, or anywhere near first in this area with several significant projects arguably at a much greater level of maturity.
JAX-RS (JSR-311)
The main non-Spring thrust for RESTful WS in Java, has become centered around the recently finalised JSR-311, known as JAX-RS. This is not to say that the RESTful Java story begins with a Sun standard (perish the thought). At least one of the RESTful java efforts (RESTlet) predated JSR-311 quite significantly, but is now an adoptee of the JSR. There are at least the following open source implementations that I know of:
- Jersey
- Restlet
- RestEasy
- Apache CXF
- Apache Wink
Of these, the only one I have spent any real time kicking the tyres on is Jersey. Although this is billed as the reference implementation from Sun, it seems to have some ambitions to penetrate the real world a lot further than other reference rollouts that Sun have provided in the past. So far, my entire experience of JAX-RS is limited to Jersey, so I wont trouble you with my as yet non-expert opinion of these, expecially as Solomon Duskis has been working on a comparrison of these implementations.
I will note though just a few things did strike me very quickly when running through a few representative scenarios with Jersey:
- The annotated API looks intuitive. With classes representing (Restful) Resources, and some easily recognisable annotations such as @GET, and @POST, etc. The initial learning curve looks pretty manageable.
- Getting started with Jersey is trivial. This is really just a credit to the good work done by the Sun guys, to provide lots of easy entry points to their project, including some useful maven2 archetypes that get you up and running with an executable (albeit Grizzly WebServer hosted) Hello World service, quicker than you can say "HATEOAS".
- Resource Instances per Request?. Instances of the Resource classes appear to be instantiated on every request. That I am suprised by this, could just be the newb in me showing. More likely it is coming from a Spring MVC Controller standpoint whereby the handler of the request is a managed global singleton. This wasnt immediately obvious from running a Hello World example as these only support GET, but as soon as I wanted to implement a mutative method like POST(a) I realised I was in trouble.
I would think that the Resource-Object-Created-On-Request pattern would not lend itself so well to dependecy injection frameworks like Spring which prefer to create upfront, and directly manage beans. Im sure there are plenty of ways around this, but it didnt seem to be the most natural approach. Perhaps this is the reason why the Spring guys did not themselves go down the JAX-RS route?
Other non-JAX-RS efforts
With the relative freshness of JSR-311, there are other efforts as well floating around that havent adhered to the spec. Other than Spring 3.0 itself, one worth noting is Josh Devins Mattress Framework. Josh also notes the Resource-Object-Created-On-Request pattern as a reason for not adhering to the spec. With very little community involvement however, rather than Mattress becoming a major player, its largest contribution may be to provide a running, mostly functional technical comparrison to JAX-RS.
Certainly for those who have been burnt in the past by Sun's 'spec first' approach, lightweight functional alternatives are always great to see.
Client Support
One area with possibly the greatest divergence is that of support for the client. Spring is offering its RestTemplate in the style of other boilerplate-hiding templates that they have proved successful with. Others in the JAX-RS camp have been reusing aspects of the spec on the client side, even though this is beyond scope of the spec itself.
What Im looking for
I am very interested to see how Solomon's comparrison progresses, not only to know which (if any) technology is worth investing my time (ahem career) in utilising, but also to see what method he takes in comparrison. Hopefully the same approach can be expanded to consider the effectiveness of non-JAX-RS efforts.
Im also interested to know if there is a reference application out there (preferably not involving any more pets or pet stores!) that might be useful in such a comparrison of frameworks.
Finally I am interested to see how successful any of these approaches are in providing for server side convergence of runtime code supporting both the human web and the machine web. How can architect the server side for a future that embraces both humans and machines as clients of the same resources? Building out on their MVC framework puts Spring well down this path, but is their new REST support strong enough?
Update. A couple of other JAX-RS implementations that are floating around:
- Apache Wink - looks to largely be a new collaboration between teams at HP and IBM
- Triaxrs - which appears to be gunning for the OSGi space
Good to see some more activity.
Clojure goes 1.0
News just in, Rich Hickey has announced the release of Clojure v 1.0.
Great news for the Clojure community and congratulations to Rich. Clojure has been quite useable for some time now, so it will be interesting to see if the notional shift to a 1.0 release will help it to attract any more of the increasing dynamic language mindshare circulating around the JVM. Some may not like its Lispness, but beyond that hurdle, Clojure looks to me to be a leading contender at this point in the race.
Would the real software architect please stand up
Mike Walker recently blogged about the breakdown of the 'architect' metaphor commonly used to align the notion of a high level software designer with that of the Construction industry.
Mike listed several areas where the model of a building/construction architect really does not fit with that of a software architect. In many cases this is a function of industrial maturity. As pointed out, Construction has many thousands of years greater experience in understanding and defining the role and responsibilities of the architect, whereas Software is so young that it has had to borrow the title in the first place.
Simon Brown followed up questioning why project sponsors seldom hold software architects accountable for project success as in the Construction industry. The flipside being that software architects then lack the authority to fully realise their vision.
For me the most important breakdown in the metaphor comes with identification. This too is the greatest impediment to software architects assuming additional authority that may or may not be useful.
When the holder of a role cannot easily be identified, then all the responsibilities, accountabilities and expectations cannot easily be attributed to them. Consider, why do police wear uniforms?
In Construction it is very easy to distinguish the architect from developers. The architect dresses differently, works at different times and locations, associates with different people event to the extent of being almost in a different social class. Their engagement with a project must necessarily begin far in advance of any development stage and their output reach advanced stages of completion prior to the commencement of development.
By contrast, the software engineer sits at a desk, with a computer, almost always side by side with the developers of the product. More and more often the architecture is not fully embodied ahead of time, and may develop to a much greater extent in parallel with general development.
Differences in the career path also add to the ambiguity. In Construction, the career path to architect is generally academic and does not incorporate very much of the same training given to a developer. Building architects are seldom developers in a past life, and do not develop as part of their role. In Software the roles are much more inextricably linked. Architects who do not code risk becoming astronauts, whereas the best of whom tend to be those most willing to delve deeply into code.
Like all metaphors the architect is useful to a point but tends to get over extended. We need to recognise that whilst the distribution of responsibilities falls differently across software teams as it does to those in construction, at the end of the day the same level of responsibility and accountability needs to be born by the team. Construction may have 10000 years head start, but without this, Software as an industry cannot hope to graduate to the same level of rigour.