Java EE design patterns for scalable architecture

By: Markus Eisele

Updated: 11/17/2015

With the ascent of DevOps, microservices, containers, and cloud-based development platforms, the gap between state-of-the-art solutions and the technology that enterprises typically support has greatly increased. Some enterprises are now looking to bridge that gap by building microservice-based architectures on top of Java EE. This report thoroughly explores this possibility and provides savvy advice for enterprises that want to move ahead. The issue is complex: Java EE wasn’t built with the distributed application approach in mind, but rather as one monolithic server runtime, or cluster hosting many different applications.

This book explains how to:

  • Understand the challenges of starting a greenfield development vs. tearing an existing brownfield application apart into services.

  • Examine your business domain to see if microservices would be a good fit.

  • Explore best practices for automation, high availability, data separation, and performance.

  • Align your development teams around business capabilities and responsibilities.

  • Inspect design patterns to model service interactions such as aggregator, proxy, pipeline, or shared resources.


Access Java EE design patterns now

Java EE and microservices

There are a lot of technologies that barely offer any advantages to microservices-based architectures, such as the Java Connector Architecture or the Batch Processing API. If you are starting to build microservices architectures on top of Java EE, make sure to look at the asynchronous features and try to use the best available parts. One important item to keep in mind: Java EE was never built to work with distributed applications or microservices. So every decision and line of code should be carefully inspected and validated to maximize asynchronicity.

JAX-RS 2.0

To execute asynchronous requests in JAX-RS, inject a reference to a interface in the JAX-RS resource method as a parameter. The resume method on the AsyncResponse object needs to be called from within a separate thread after the business logic execution is complete, as illustrated here:


private Executor executor;

public void asyncGet(@Suspended final AsyncResponse

                                  asyncResponse) {
                executor.execute(() -> {

                String result = service.timeConsumingOperation();



Access Java EE design patterns now