First off, I must say that my opinion on this book might be a little biased. Indeed, the author Romain Manni -Bucau had worked for several years in my team at Atos Worldline. I’ve known him first as an intern and have been impressed by his capacity to deep dive and quickly into technical matters. I am proud to note his evolution notably through the ability to write a book such as this one. That being said, let’s go about this book.
When I started reading it, I didn’t know exactly what to expect. The field of performance is so vast. Especially since Java EE does not always have a good reputation in this matter…
Romain approaches this issue from a developer perspective. His book is not prescriptive, it does not describe a complete and detailed methodology to ensure high performance on your application, it rather gives some sense of awareness on many factors that can influence performance.
Below is a description of my reading with some personal comments.
Chapter 1 “Money the Quote Manager Application” introduces a demo application which is a simple but good illustration on how to combine Java 8 with Java EE 8. It makes use of different specifications: CDI, JAX-RS, WebSocket, JSON-B, JPA and JTA.
Interestingly, it is mostly based on transactional CDI beans, which seems to be a significant trend of modern Java EE applications. CDI is more and more seen as a generalization of EJB. Even if EJB still keeps some specificity, an alignment is expected in the following versions. Maybe a next step for Jakarta EE …
Chapter 2 “Looking under the cover-What is this EE thing” is of high interest and a must read. It provides insights about some important technical aspects related to performance without diving too much into detail. I recommend reading it with the specifications within reach so that you can deepen your Java EE knowledge in parallel. I would entitle this chapter “Everything a developer should know before coding”.
In my opinion, the most emblematic example in that matter is the misunderstanding of the JPA-SQL mismatch. When JPA was released in 2005, there was a strong SQL culture in the developer community. Most developers had a SQL background and were naturally curious to check how JPA is turned into SQL requests. This is a good practice to avoid very bad surprises in production. JPA is very powerful but used naively, it can load the whole database in memory! Unfortunately, it seems that this SQL culture has disappeared over the years. Many junior developers don’t know enough SQL and must be coached by seniors.
Chapter 3 “Monitor your application” illustrates the different possibilities to monitor the JVM, the application server (Glassfish 5 in this case which is the Java EE 8 Reference Implementation) and the application. High level APM tools are mentioned but not detailed. The purpose of the chapter is rather to describe basic means offered by the JVM, the application server and the different possibilities to instrument your code (using CDI interceptor or javagent).
To wrap it up, it describes how you can check the behavior of your application and its execution environment. It is important to keep in mind that the overall performance comes from both. Personal warning: if you decide to make use of Java Mission Control and Java Flight recorder do not forget that they are commercial features with Oracle JDK 8. Fortunately, they are included for free since Open JDK 9!
Chapter 4 “Application Optimization-Memory management and server configuration” starts with a simple but highly interesting description of the Garbage Collection mechanism. I’ve really appreciated it and I recommend every developer to read it! The second part deals with Java EE resources in general and is interesting too. As mentioned in my description of chapter 3, the overall performance results both from the application and its execution environment. The best application just delivers the worst performance with a poorly configured JRE and application server.
According to my experience, one common issue is the inappropriate configuration of Datasource Connection Pool. Both the sizing and the validation mechanism (how to check or not that connections to the database server are still valid) need to be carefully tailored to your needs.
Chapter 5 “Scale Up – Threading and Implications” includes a very interesting description of how each Java EE specifications (EJB, Servlet, JAX-RS, Bean Validation …) interacts with thread management. Great job! It also describes what is at your disposal in terms of asynchronous programming with JAX-RS, CDI, EJB and EE concurrency. I’ve also appreciated the part on Reactive Programming.
In my opinion, shifting the programming model from imperative and synchronous to asynchronous and functional will take a while for so-called enterprise applications. I can see two reasons for that:
- developer training and mindset change,
- the need for ACID transactions as offered by SQL databases when it comes to sensitive data.
Chapter 6 “Be lazy; Cache your Data” explains the different cache mechanisms available for a typical RESTful application: Servlet, JAX-RS, Service layer and JPA. The description of JCache and its CDI integration is really interesting.
From my experience, when properly configured (sizing and eviction policy), the second level cache of JPA (called “shared cache” for EclipseLink) can provide significant benefits, especially for reference data which are mostly read-only. However, do not dream: it cannot compensate poor performances, it’s just ice on the cake! In the end keep in mind that the “Cache is King”, but eviction is often a real challenge!
Chapter 7 “Be Fault-Tolerant” details the different strategies of load-balancing and fail-over which are of high importance with modern so-called microservices architectures.
I prefer the generic SOA term to microservices. For me what we call now microservices is just “SOA well done” with monitoring and resiliency in mind. But do not be naïve: distributing a system is a source of complexity in production. A lot of maturity and automation are needed before getting its expected benefits: continuous deployment with multiple versions of the same service, scalabilty at the service level … Before blindly following the hype, ask yourself if you really have the needs of Netflix.
Chapter 8 “Loggers and Performances-A trade off” provides a review of the numerous logging and façade frameworks and how they work.
To my amazement, a need as basic as logging is still an issue in 2018. Despite the plethora of solutions, it seems that proper logging is not a given and can lead to poor performance.
Chapter 9 “Benchmarking Your Application” before going to production, you should benchmark your application. Most Java EE applications are complex in terms of architecture and business functionalities and because of that, there are many potential risks of poor performance. This chapter details how to prepare, automate and run a benchmark. Once again, it is not prescriptive in terms of tooling and different options are proposed.
More often than not, the benchmarking effort is underestimated. If the project is late, it is tempting to skip it. This is never a good option! You will pay the price (at least) twice in firefighting mode.
Chapter 10 “Continuous Performance Evaluation” at this stage of the book, as a developer, you should be convinced that performance should be part of your daily life. This chapter details how to implement that in your continuous integration pipeline with some Open Source products.
I’ve personally discovered some interesting way to do it. Looking forward to test it!
To conclude this post, I would say that “Yes, you can develop powerful Java EE applications!”. But it is necessary to master a minimum of technique. No doubt that this book will help you!