Deferring the Java EE or Spring choice

Posted by Insane Programming on April 9, 2017

The last article on this blog stirred up quite some dust in the Java EE and Spring communities. It’s encouraging to see that both parties realize the benefit of the approach the other one has and that the road to symbiosis might be the one that gets us out of this situation at last.

That being said, it’s more clear to me than ever that one of the biggest problems we face nowadays isn’t even framework related. Most of us really know how to code and it doesn’t matter whether we’re using Java EE or Spring. I compare the choice as the one that a builder needs to make when deciding between Makita and Milwaukee. Both are great tools and in the end, it depends on personal preference. No, our problem isn’t code. It’s designing good systems that’s the big problem.

Mainly thanks to one person (@khofmans), I got interested in Clean Architecture. While I was already familiar with the movies by Uncle Bob and had read Clean Code and The Clean Coder, somehow I missed that. And if you look further, there are a lot of people (like Simon Brown) sharing information that echoes the same sentiment that Uncle Bob does. Clean Architecture is about deferring the choices that you need to make and about starting to become aware of the design of the system instead of focussing on the technical aspect. Ideally such systems, the core of your application should be devoid of any choice regarding Spring or Java EE. It’s only in the outer layers technical opinions start to matter and where the choice needs to be made. And even there you can do your best to defer the choice as long as you can.

For example, in a standard Clean Architecture design, the domain and the application layer do not contain any dependency that dictates a later deployment on either platform. I’m using CDI annotations because both Spring and Java EE have support for DI using those and other standard annotations that both platforms can work with. It’s all about deferring choice. In the infrastructure layers, choices need to be made. For the REST infrastructure you need to choose whether you’ll be using Spring MVC or JAX-RS. But if you would really want to you could opt for the JAX-RS option because both platforms can handle it and thus once again deferring the choice. The same thing on the other end of the chain regarding persistence. JPA could be a choice that enables you to defer the choice of the deployment platform until it’s not practical to do so anymore.

In my opinion, whenever you make a choice that binds you to either Spring or Java EE as a deployment platform, you’re accepting a certain level of technical debt. It’s a debt that is perfectly justifiable, but a debt nonetheless. I know when I’m building a Spring Boot app and later on the choice is made to deploy on a Java EE container and I need to use JNDI resources instead of Spring managed ones, someone will collect on that debt.

But the technical debt you’re accumulating when you’re improperly designing your software is much larger than any choice regarding Java EE or Spring will ever be. A nice example of this is the current overzealous adoption of the microservice concept. Microservices are popular right now and with all the cool examples like Zalando, Netflix, Amazon, … it’s hard not to be carried away with the movement. And yes, Spring Boot has been an enabler of microservices from day one and Java EE is playing catch-up here. But again, a poorly designed modular system using Spring Boot with microservices is much worse than a monolith with Java EE. Technology is not the deciding factor here, you can just as easily screw up using either Spring Boot or Java EE (using KumuluzEE, Wildfly Swarm). Simon Brown gave a fantastic talk on Devoxx last year about building modular monoliths and what he told in that presentation was much more important than any technological choice we could ever make: if you’re not able to build a modular monolith, why the hell are you using microservices? I extend this to: if you’re not able to design a modular system properly, why the hell were you pushing to use Spring Boot or Wildfly Swarm in the first place, if not only for being able to start building microservices?

Being able to write good software regardless of using Java EE or Spring is what makes a great developer. By deferring the choice you’re forcing yourself to design better software and not use the shortcuts that tend to introduce technical debt into the design. I’m not saying everyone will be equally productive when using both approaches, but the difference really won’t be that big really. A good design is what dictates speed of development, not the technology. Not anymore.