A couple of fays again, on the Twitter sphere, I saw blog post by Sam Atkinson called Why I hate Spring. This blog entry was written well over a year ago in 2014, but then DZone actually picked up on it and published it. Atkinson is developer actually at the time of writing is travelling around the world. So he must have been very surprised at the social media in his personal views.
Mr Atkinson article touches on several interesting issues in current Java enterprise application design: XML configuration and compile time safety, magic incantations, imports of other Spring application context files and software complexity. I will briefly examine each of these in this blog post.
I was not surprised by XML configuration, but then J2EE 1.3 had a horrible experience of manipulating EJB XML mapping files and so did Hibernate persistance earlier on. Eventually, Java SE 5 annotations and the Java EE 5 specification helped to change things around. The ideas of CONVENTION-OVER-CONFIGURATION from Ruby on Rails helped to move Java onto the next phase. Spring Framework was earlier to the OSS market with workable dependency injection container implementation in 2002 and 2003. At the time J2EE 1.3/1.4 was horrible mess of container managed session EJB and deranged concept of entity EJB. There was no standard DI framework, and Spring’s competitors were Pico Container, the much older Apache Avalon (Now Closed) framework and even Struts 1.x framework. Years later from 2006, Java EE came along and provided Context and Dependency Injection (CDI) 1.0 with strong type safety at compile time. CDI was too late for thousands of businesses that adopted Spring Framework and at the time most of them where battling with migration from Java 1.4 (J2EE 1.4) to Java 5 and/or 6. The biggest issue ten years ago was keeping mission critical applications running in either a WebLogic Server 7/8 or IBM WebSphere 5/6 application server. So the state of the art was already broken for several years. Spring Framework had it own DI container and yet Java EE 6 also featured a DI container and never the twain will ever meet up.
When it was first conceived Dependency injection was already mind-twist even way back in 2003, it took a lot of thought to understand the common issues of object-oriented systems. Chief amongst them was the testability of applications and selection of alternative implementations for Java object. By giving up control of the instantiation of Plain Old Java Objects (POJOs) to a foreign framework was very unusual at the time. After the water had broken the levy, every engineer, then, pushed classes and implementations over to the framework, well maybe that was a mistake that we pay for now in the present. The magic incantation of which beans are injected and at what application layer was great when the software works, however it was a nightmare to figure out, like Sam Atkinson opined, when you were chasing a bug and refactor some other team’s set of dependencies with Spring Framework. Add to the usual PEOPLE-WARE issues of BIT-ROT and inside investment banking culture of softwre development, SILO DIVISION engineering, then Spring Framework and other application framework were always going to lose at some point.
Sam Atkinson alluded to typical LAYERING issue of large application code bases, especially when the source code is split over hundreds. or occasionally, thousands of engineers, testers and architects inside organisations. Spring Framework already had peculiar feature since version 1.0 to modularises application context files by placing different beans definitions inside different Maven projects. The concept was great to keep bean definitions close to the module that defined and used them. Maybe this philosophy was great for application with small enough set of Maven projects, once the organisation defined a hundred projects with bean definitions, this trick became the nightmare to control. [Let’s not forgot that is the state of the art now.] Combined with magic incantation, layering and delegation of multitude Spring beans in scores of related application context, probably did cause Sam Atkinson a massive cognitive overload. However, this is not strictly a Spring Framework, but rather the application of EVERYTHING IS A NAIL issue.
Finally, software complexity is the bane of many businesses and the effects of building a sufficiently large application and having to then to decipher it, distill it down and eventually replace it might lead to people having a CORONARY. Perhaps the biggest complexity project inside Java is the modularisation of the JDK itself by Oracle and Sun Microsystems and that one does not use a dependency injection container at all. Atkinson talked about the probable fallacies with Spring Boot as a framework around a framework and being possibly dangerous. He is correct in this idea, because Java EE does not (yet) have a standard API or JSR about fully embedded application server infrastructure. [Antonio Gonclaves and others, including myself, have pleading for such API “One Container to Rule Them All” to be brought into existence more than once.] There are uncertain paths if you going down this path with the likes of WildFly Swarm, because your tool chain and development mechanics might not support you all the way. For example, your IDE may not be able to achieve Hot JVM class reloading or be able contribute much to front-end page content changes. These so-called container-less solutions rely on the concept of applications that already are modularised into separate components. If your application is a humongous BEHEMOTH then turning it in to embedded application server application is not going to help in anyway. You have instead serious work to do before reaching the first rung of the ladder of micro-services like attempting to unknit the spaghetti projects and Maven dependencies within your own organisation. The failure is to understand how a large scale Spring Framework application is just the symptom of the illness and not the diagnosis.
Why are we going to lose? Or may be question is why are we just losing it now? The hardest problem inside software engineering is figuring out what to do with LEGACY SOFTWARE and DREAMSCAPING. Most engineers know something about the concept of legacy software and technical debt. It is tremendously hard to write applications that are bug free, flexible and agile; and robust with supremely maintainability. Most technical senior management have either forgotten or do not believe in the effects on legacy. Then, there are the dreams that recruitment companies, sometimes company businesses sell to us, the engineers, designers and architects. Most of the nine to ten million Java developers are the constant baits of the so-called GREENFIELD. Unless you work in a startup company right a very beginning, there really no such thing as this humble green lawn. Even when an existing business spawns out a SKUNK work team and promises that you will not have to work with Legacy, in a couple of weeks, or a couple months, guess what? You will hit the wall of integration between the new fangled system and the older legacy system. At the heart of Sam Atkinson passionate cries of frustration with Spring Framework, the fault is in the architectural design of the applications. The vast majority systems out there in the real world of corporate are BROWNFIELD, please don’t let a recruitment consultant kid you on. He, himself, said that he had not time to train, coach and/or mentor other developers inside his organisation, because of that older directive TIME-TO-MARKET. The moral of the story is, is that there is no moral, except that we are on a MOVING-TECHNOLOGY-FEAT, beating down on Spring Framework, so what? We can beating down Java EE or PHP, Ruby and Scala. If we cannot control our instincts, time pressures and designs, good old human nature is going to seep into our application, and we can attempt to achieve 100% code coverage, write the best functional tests with Cucumber, JBehave, we will still have broken applications in years to come. Software is software, we lose most of the time, and sometimes we win. It’s just extremely difficult when, where and how to achieve this grand ambition.