Microservices and Java EE

Microservices based architectures are everywhere these days. We learn so much about how today’s innovators, like Netflix and Amazon use these to be even more successful in generating more business. But what about all of us, who are using Java EE application servers and write classical systems? Are we all doing it wrong? And how could we make our technical designs fit for the future?

Monoliths
First of all, let’s look into those classical systems. Or called monolithic applications. Even if the word has a bad smell these days, this is the way we built software for a very long time. It basically describes the fact, that we build individual applications to fulfill a certain functionality.
And monolithic does refer to exactly what Java EE or better the initial Java 2 Enterprise Edition was designed for. Centralized applications which could be scaled and clustered but not necessary build to be resilient by design. They relied on infrastructure and operations in failure scenarios most of the time.

Traditionally, Java EE applications followed some core patterns and were separated into three main layers: presentation, business, and integration. The presentation layer was packaged in Web Application Archives (WARs) while business and integration logic went into separate Java Archives (JARs). Bundled together as one deployment unit, a so-called Enterprise Archive (EAR) was created. The technology and best practices around Java EE have always been sufficient to build a well-designed monolith application. But most enterprise-grade projects tend to lose a close focus on architecture.  This is why sometimes a well designed spaghetti ball was the best way to visualize the project dependencies and internal structures. And when this happened, we’ve quickly experienced some significant drawbacks. Because everything was too coupled and integrated even making small changes required a lot of work (or sometimes major refactorings) and before putting the reworked parts into production, the applications also had to be tested with great care and from beginning to end.
The whole application was a lot more than just programmed artifacts: it also consisted of uncountable deployment descriptors and server configuration files, in addition to properties for relevant third-party environments.

The high risks in changes and the complexity of bringing new configurations into productions lead to less and less releases. A new release saw the light of day once or twice a year. Even the team structures were heavily influenced by these monolithic software architectures. The multi-month test cycle might have been the most visible proof. But besides that, projects with lifespans longer than five years tended to have huge bugs and feature databases. And if this wasn’t hard enough, the testing was barely qualified–no acceptance tests, and hardly any written business requirements or identifiable domains in design and usability.

Handling these kinds of enterprise projects was a multiple team effort and required a lot of people to oversee the entire project. From a software design perspective, the resulting applications had a very technical layering. Business components or domains were mostly driven by existing database designs or dated business object definitions. Our industry had to learn those lessons and we managed not only to keep these enterprise monoliths under control, but also invented new paradigms and methodologies to manage them even better.

spaghettiSo, even if the word „monolith“ is considered synonym for a badly designed piece of software today, those architectures had a number of benefits. Monolithic applications are simple to develop since IDEs and other development tools are oriented around developing a single application. Its a single archive that can be shared with different teams and encapsulates all the functionality in there. Plus, the industry standard around Java EE gave enterprises solid access to the resources needed to not only build but also operate those applications. Software vendors have build a solid knowledge base around Java EE and sourcing isn’t a big issue in general. And having worked with them since more than 15 years by now, the industry is finally able to manufacture these applications in a more or less productized and standardized way. We know which build tools to use, which processes scale in large teams and how to scale those applications. And even integration testing got a lot easier since tool like Arquillian emerged. We still are paying a price for the convenience of a mature solution like Java EE. Code-bases can grow very large. When applications stay in business for longer, they get more and more complex and harder to understand for the development teams. And even if we know how to configure application servers, the one or two special settings in each project still cause major headaches in operations.

Microservices
microservicesBut our industry doesn’t stand still. And the next evolution of system architecture and design just saw the light of day a couple of years ago. With the growing complexity of centralized integration components and the additional overhead in the connected applications the search for something more lightweight and more resilient began. And the whole theory finally shifted away from big and heavyweight infrastructures and designs. Alongside with this IT departments started to revisit application servers alongside with wordy protocols and interface technologies.

The technical design went back to more handy artifacts and services with the proven impracticality of most of the service implementation in SOA- and ESB-based projects. Instead of intelligent routing and transformations, microservices use simple routes and encapsulate logic in the endpoint itself. And even if the name implies a defined size, there isn’t one.  Microservices are about having a single business purpose. And even more vexing for enterprise settings, the most effective runtime for microservices isn’t necessarily a full-blown application server. It might just be a servlet engine or that the JVM is already sufficient as an execution environment. With the growing runtime variations and the broader variety of programming language choices, this development turned into yet another operations nightmare. And even developers today are a little lost when it comes to defining microservices and how to apply this design to existing applications.

Microservices are designed to be small, stateless, in(ter)dependent & fully contained applications. Ideally able to deploy them everywhere, because the deployment contains all the needed parts.

Microservices are designed to be small.  But defining “small” is subjective.  Some of the estimation techniques like lines of code, function points, use cases may be used.  But generally “small” isn’t about size.
In the book Building Microservices the author Sam Newman suggests a few techniques to define the size of microservice, they are:

  • small enough to be owned by a small agile development team,
  • re-writable within one or two agile sprints ( typically two to four weeks) or
  • the complexity does not require to further divide the service up

A stateless application handles every request with the information contained only within it. Microservices must be stateless and it must service the request without remembering the previous communications from the external system.

Microservices must service the request independently, it may collaborate with other microservices within the eco-system.  For example, a microservice that generates a unique report after interacting with other microservices is an interdependent system. In this scenario, other microservices which only provide the necessary data to reporting microservices may be independent services. A full stack application is individually deploy-able. It has its own server, network & hosting environment.  The business logic, data model and the service interface (API / UI) must be part of the entire system.  A Microservice must be a full stack application.

Why now? And why me?
“I’ve been going through enough already and the next Java EE version is already under development. We’re not even using latest Java EE 7. There are so many productivity features coming: I don’t care if I build a monolith if it just does the job and we can handle it.” And I do understand these thoughts. I like Java EE as much as you probably do and I was really intrigued to find out why microservices evolved lately. The answer to those two questions might not be a simple one: But lets try:

Looking at all the problems in our industry and the still very high amount of projects failing, it is perfectly fine to understand the need to grow and eliminate problems. A big part of new hypes and revamped methodologies is the human will to grow.

And instead of “never touch a running system” our industry usually want’s to do something better than the last time.
So, to answer the second part of the question first: “You probably want to look into this, because not doing anything isn’t a solution.”

As a developer, architect or QA engineer we basically all signed up for live long learning. And I can only speak for myself at this point, but this is a very big part of why I like this job so much. The first part of the question isn’t so easy to answer.

Innovation and constant improvement are the drivers behind enterprises and enterprise-grade projects. Without innovation, there will be outdated and expensive infrastructure components (e.g., host systems) that are kept alive way longer than the software they are running was designed for. Without constant validation of the status quo, there will be implicit or explicit vendor lock-in. Aging middleware runs into extended support and only a few suppliers will still be able to provide know-how to develop for it. Platform stacks that stay behind the latest standards attempt to introduce quick and dirty solutions that ultimately produce technical debt. The most prominent and quickest moving projects in the microservices space are Open Source projects. Netflix OSS, Spring, Camel, Fabric8 and others are prominent examples. And it became a lot easier to operate polyglot full-stack applications with today’s PaaS offerings which are also backed by Open Source projects like Docker and Kubernetes. In our fast paced world the lead times for legally induced software changes or simple bug fixes are shrinking. Very few enterprises still have the luxury to work with month long production cycles and the need for software to generate real value for business emerges even more. And this is not only true for completely software driven companies like Uber, NetFlix, Amazon and others.

We need to build systems for flexibility and resiliency, not just efficiency and robustness.  And we need to start building them today with what we have.

And I really want to make sure you’re reading this statement the right way: I am not saying, that everything from today on is a microservice.

  • But we should be aware of the areas where they can help and be able to
  • change existing applications towards the new approach when it makes sense.
  • and we want to be able to be a good consultant for those asking about the topic

And Java EE isn’t going anywhere soon. It will be complemented and the polyglot world will be moving in in various places, but we’re not going to get rid of it soon.  And this is the good news.

Learn more about how to evolve your Java EE applications into microservices by downloading my free eBook from developers.redhat.com. Make sure to re-watch my O’Reilly Webcast about “Java EE Microservices Architecture”  and also follow my blog.eisele.net with some more technical information about WildFly Swarm, Docker and Kubernetes with OpenShift.

Doing microservices with micro-infra-spring

We’ve been working at 4financeit for last couple of months on some open source solutions for microservices. I will be publishing some articles related to microservices and our tools and this is the first of (hopefully) many that I will write in the upcoming weeks (months?) on Too much coding blog.

This article will be an introduction to the micro-infra-spring library showing how you can quickly set up a microservice using our tools.

Introduction 

Before you start it is crucial to remember that it’s not enough to just use our tools to have a microservice. You can check out my slides about microservices and issues that we have dealt with while adopting them at 4financeit.

4financeit microservices 12.2014 at Lodz JUG from Marcin Grzejszczak

Here you can find my video where I talk about microservice at 4finance (it’s from 19.09.2014 so it’s pretty outdated)


Also it’s worth checking out the articles of Martin Fowler about microservices, Todd Hoff’s – Microservices not a free lunch! or The Strengths and Weaknesses of Microservices by Abel Avram’s.

Is monolith bad?

No it isn’t! The most important thing to remember when starting with microservices is that it will complicate your life in terms of operations, metrics, deployment and testing. Of course it does bring plenty of benefits but if you are unsure of what to pick – monolith or microservices then my advice to use is to go the monolith way.

All the benefits of microservices like code autonomy, doing one thing well, getting ridd of pacakge dependencies can be also achieved in the monolithic code thus try to write your applications with such approaches and your life will get simpler for sure. How to achieve that? That’s complicated but here are a couple of hints that I can give you:

  • try to do DDD. No, you don’t have DDD when your entities have methods. Try to use concepts of aggregate roots
  • try not to make dependencies on packages from different roots. If you have two different bounded context like com.blogspot.toomuchcoding.client and com.blogspot.toomuchcoding.loan – go via tight cohesion and low coupling – emit events, call REST endpoint, send JMS messages or talk via strictly defined API. Do not reuse internals of those packages – take a look at the next point that deals with encapsulation
  • take your highscool notes and read about encapsulation again. Most of us make the mistake of thinking that if we make a field private and add an accessor to it then we have encapsulation. That’s not true! I really like the example of Slawek Sobotka (article in polish) who shows an example of common approach to encapsulation:

    human.getStomach().getBowls().getContent().add(new Sausage())

    instead of

    human.eat(new Sausauge())

  • add to your IDE class generation template that you want your new classes to be package scoped by default – what should be publicly available are interfaces and really limited number of classes
  • start doing what’s crucial in terms of tracking microservice requests and measuring business and technical data in your own application! Gather metrics, set up correlation ids for your messages, add service discovery if you have multiple monoliths.

I’m a hipster – I want microservices!

Let’s assume that you know what you are doing, you evaluated all pros and cons and you want to go down the microservice way. You have a devops culture there in your company and people are eager to start working on multiple codebases. How to start? Pick our tools and you won’t regret it 😉

Clone a repo and get to work

We have set up a working template on Github with UI – boot-microservice-gui and without it – boot-microservice. If you clone our repo and start working with it you get a service that:
  • uses micro-infra-spring library
  • is written in Groovy
  • uses Spring Boot
  • is built with Gradle (set up for 4finance – but that’s really easy to change)
  • is JDK8 compliant
  • contains an example of a business scenario
what you just have to do is:
  • check out the slides above to see our approach to microservices
  • remove the packages com/ofg/twitter from src/main and src/test
  • alter microservice.json to support your requirements
  • write your code!
Why should you use our repo?
  • you don’t have to set up anything – we’ve already done it for you
  • the time required to start developing a feature is close to zero

Aren’t we duplicating Spring Cloud?

In fact we’re not. We’re using it in our libraries ourselves (right now for property storage in Git repository). We have some different approaches to service discovery for instance but in general we are extending Spring Cloud’s features by:

Conclusions

If you want to go down the microservice way you have to be well aware of the issues related to that approach. If you know what you’re doing you can use our libraries and our microservice templates to have a fast start into feature development. 

What’s next

On my blog at toomuchcoding.blogspot.com I’ll write about different features of the micro-infra-spring library with more emphasis on configuration on specific features that are not that well known but equally cool as the rest 😉 Also I’ll write some articles on how we approached splitting the monolith but you’ll have to wait for that some time 😉

This post is part of the Java Advent Calendar and is licensed under the Creative Commons 3.0 Attribution license. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on!