40,81 €
Discover how cloud-native microservice architecture helps you to build dynamically scalable applications by using the most widely used and adopted runtime environments
Key Features
Book Description
Businesses today are evolving rapidly, and developers now face the challenge of building applications that are resilient, flexible, and native to the cloud. To achieve this, you'll need to be aware of the environment, tools, and resources that you're coding against.
The book will begin by introducing you to cloud-native architecture and simplifying the major concepts. You'll learn to build microservices in Jakarta EE using MicroProfile with Thorntail and Narayana LRA. You'll then delve into cloud-native application x-rays, understanding the MicroProfile specification and the implementation/testing of microservices. As you progress further, you'll focus on continuous integration and continuous delivery, in addition to learning how to dockerize your services. You'll also cover concepts and techniques relating to security, monitoring, and troubleshooting problems that might occur with applications after you've written them.
By the end of this book, you will be equipped with the skills you need to build highly resilient applications using cloud-native microservice architecture.
What you will learn
Who this book is for
This book is for developers with basic knowledge of Java EE and HTTP-based application principles who want to learn how to build, test and scale Java EE microservices. No prior experience of writing microservices in Java EE is required.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 334
Veröffentlichungsjahr: 2019
Copyright © 2019 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Aaron LazarAcquisition Editor: Alok DhuriContent Development Editor: Zeeyan PinheiroTechnical Editor: Sabaah NavlekarCopy Editor: Safis EditingProject Coordinator: Vaidehi SawantProofreader: Safis EditingIndexer: Rekha NairGraphics: Alishon MendonsaProduction Coordinator: Aparna Bhagat
First published: January 2019
Production reference: 1310119
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78883-786-6
www.packtpub.com
Luigi Fugaro's first encounter with computers was in the early 80s when he was a kid. He started with a Commodore Vic-20, passing through a Sinclair, a Commodore 64, and an Atari ST 1040, where he spent days and nights giving breath mints to Otis. In 1998, he started his career as a webmaster doing HTML, JavaScript, Applets, and some graphics with Paint Shop Pro. He then switched to Delphi, Visual Basic, and then started working on Java projects. He has been developing all kinds of web applications, dealing with backend and frontend frameworks. In 2012, he started working for Red Hat and is now an architect in the EMEA Middleware team.
He has authored WildFly Cookbook and Mastering JBoss Enterprise Application Platform 7 by Packt Publishing.
Mauro Vocale was born on March 25, 1980 in Venaria Reale, Italy. He started to work in Java and Linux OS in 2001. He is a passionate open source developer, and he is excited to be working for a company like Red Hat as a middleware consultant since November 2015. He is a Certified Oracle Master Java SE 6 Developer, Oracle EJB, and Web Component Developer for JEE 6 and JBoss EAP 7 administration.
As a consultant, he has the opportunity to implement enterprise applications in many different scenarios and, like many IT people, he takes big enterprise companies through the journey of digital transformation and microservices adoption. He was the official reviewer of Mastering JBoss Enterprise Application Platform 7, published by Packt Publishing.
Sebastian Daschner is a Java freelancer working as a consultant and trainer, and is enthusiastic about programming and Java (EE). He participates in the JCP, helping to form future Java EE standards, serving in the JSR 370 and 374 Expert Groups, and collaborating on various open source projects. For his contributions to the Java community and ecosystem, he was recognized with the titles Java Champion and Oracle Developer Champion.Sebastian is a regular speaker at international IT conferences, such as JavaLand, JavaOne, and Jfokus. He won the JavaOne Rockstar award at JavaOne 2016. Together with Java community manager, Steve Chin, he has traveled to dozens of conferences and Java User Groups on his motorbike. Steve and Sebastian have launched JOnsen, a Java conference held at a hot spring in the countryside of Japan.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Title Page
Copyright and Credits
Hands-On Cloud-Native Microservices with Jakarta EE
Contributors
About the authors
About the reviewer
Packt is searching for authors like you
About Packt
Why subscribe?
Packt.com
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Get in touch
Reviews
Jakarta EE - the New Open Source Life of Java EE
Open source
The Java programming language
Sun Microsystems
Oracle Corporation
Eclipse Foundation
OpenJDK 9 and 10 – key features for cloud environments
JDK 9
JDK 10
Java EE – MicroProfile.io – Jakarta EE
MicroProfile
Jakarta EE
Summary
Microservices and Reactive Architecture
MicroProfile and the principles of MSA
What are microservices?
Benefits of microservices
Drawbacks of microservices
SOA versus MSA
Differences between MSAs and SOAs
From monolith to microservices
What is a monolith?
Migration path
Reactive systems and reactive programming
Reactive systems
Reactive programming
RxJava
Spring WebFlux and reactive stacks
Vert.x
Reactive Java EE monolith
Asynchronous processing
Messaging communications
Summary
Cloud-Native Applications
Twelve-factor applications
Code base
Dependencies
Config
Backing services
Build, release, run
Processes
Port binding
Concurrency
Disposability
Development/production parity
Logs
Admin processes
Security
Microservices
Runtime environments
Spring Boot
Thorntail
Vert.x
Verticles
Event bus
Summary
Building Microservices Using Thorntail
Thorntail
Fractions
Flexible configuration
Building a fantasy football application
The football player microservice
Database installation and configuration
Creating the source code
Entity class – JPA
RESTful web service – JAX-RS and CDI
The football manager microservice
Database installation and configuration
Creating the source code
Entity class – JPA
RESTful web service – JAX-RS and CDI
The football team microservice
Database installation and configuration
Creating the source code
The user interface microservice
Building a user interface
Summary
Eclipse MicroProfile and Transactions - Narayana LRA
Transactions
ACID properties
Transaction managers
JTA
JTS
Extended architecture
Consensus protocol
2PC protocol
3PC protocol
The Paxos consensus
Transactions in microservices architecture
The saga pattern
Saga implementations
The Axon framework
Eventuate
Eventuate ES
Eventuate Tram
MicroProfile LRA
The football market microservice
LRA coordinator
Football-player-microservice-lra
Football-player-offer-microservice-lra
Football-player-market-microservice-lra
Initialize
The LRA business method
The complete phase
The compensate phase
Football_Player_Market_client
Limitations
Summary
Linux Containers
Linux Containers
Cgroups
Namespaces
SELinux
Containers
Docker
football-player-microservice
football-player-ui
Kubernetes
Summary
Platform as a Service
An introduction to OpenShift
OpenShift for developers
OpenShift for operations
OKD
Installing OKD
The OpenShift client
Managing a local OpenShift cluster
Templates
Networking
Services
Routes
Monitoring
Summary
Microservices Patterns
Decomposition
How do you decompose an application?
By functionality
By integration
By resource consumption
Serverless 
API gateway
Bulkhead
Circuit breaker
Istio
Sidecar
Summary
Deployment
Continuous integration and continuous delivery
What's the difference between CI, CD, and CD?
Blue-green deployment
Canary deployment
A/B testing deployment
Rolling deployment
Summary
Monitoring
Prometheus
Installing Prometheus
Node-exporter
Installing Node-exporter
Grafana
Installing Grafana
Summary
Building Microservices Using Spring Boot 2
Spring Boot
Maven settings
Gradle settings
Upgrading from an earlier version of Spring Boot
Building Spring Boot microservices
Project details
Database installation and configuration
Creating the source code
Entity class – JPA
Repository – JPA
The RESTful web service
Swagger documentation and OpenAPI
Building Microservices Using Vert.X
Vert.x
Maven settings
Gradle settings
Building a football player microservice
Project details
Database installation and configuration
Creating the source code
The data access layer
The RESTful web service
Creating the test code
The football player microservice – Vert.x + RxJava
Other Books You May Enjoy
Leave a review - let other readers know what you think
Businesses today are evolving rapidly, and developers now face the challenge of building applications that are resilient, flexible, and native to the cloud. To achieve this, you'll need to be aware of the environment, tools, and resources that you're coding against. This beginner's guide will help you take your first steps toward building cloud-native architectures in Jakarta EE.This book will begin by introducing you to cloud-native architecture and simplifying the major concepts. You'll learn how to build microservices in Jakarta EE using MicroProfile with Thorntail and Narayana Long Running Actions (LRAs). You'll then delve into cloud-native application X-rays, and we'll explore the MicroProfile specification and the implementation and testing of microservices. As you progress further, you'll focus on continuous integration and continuous delivery, in addition to learning how to Dockerize your services. The concluding chapters will help you grasp how to deploy microservices to different target environments using Docker and how to get ready for the cloud. You'll also cover concepts and techniques related to security, monitoring, and troubleshooting problems that might occur with applications after you've written them.By the end of this book, you will be equipped with the skills you need to build highly resilient applications using a cloud-native microservice architecture.
This book is for developers with basic knowledge of Java EE and HTTP-based application principles who want to learn how to build, test, and scale Java EE microservices. No prior experience of writing microservices in Java EE is required.
Chapter 1, Jakarta EE – the New Open Source Life of Java EE,describes the evolution of the Java SE and Java EE platforms in order to help you to quickly become useful in the new cloud ecosystem. We will discuss Jakarta EE (the new Java EE) and the possible future of Java EE.
Chapter 2, Microservices and Reactive Architecture, describes what a microservice is and explains its basic principles. We will describe the differences between a monolithic application and a microservice application. In this chapter, we will also become familiar with the principles and API of the MicroProfile initiative.
Chapter 3, Cloud-Native Applications,describes the concepts and the paradigm of writing an application that's ready for the cloud. We will describe the meaning of a cloud-native application, microservices, and the Twelve-Factor App methodology. We will focus on the design and the implications for both software and architectures.
Chapter 4, Building Microservices Using Thorntail, discusses how to create a distributed microservice architecture using the Jakarta EE and MicroProfile specifications, along with with Thorntail. It covers a basic example of a microservice architecture built on top of Thorntail, an implementation of the MicroProfile and Java EE specifications.
Chapter 5, Eclipse MicroProfile and Transaction – Narayana LRA,explains how to implement and handle transactions in a microservice architecture, in particular regarding the aspects related to atomicity, consistency, isolation, durability (ACID), Extended Architecture (XA) transaction, application compensations, and the saga pattern. We will implement an example of handling transactions using Narayana.
Chapter 6, Linux Containers, discusses the concept of Linux containers, using the Docker image format. We will learn how to implement a Docker file, and how to build and run a Docker image.
Chapter 7, Platform as a Service,describes the main use of the OpenShift Platform as a Service (PaaS). We will also describe how PaaS can get the best out of technologies such as Docker and Kubernetes. We will also describe how to move your microservice architecture onto the cloud.
Chapter 8, Microservices Patterns, won't describe the complete lists of patterns to use with the microservices approach, but we will concentrate on the most commonly used ones to get you started and interested in the topic of patterns.
Chapter 9, Deployment, explains how to decompose an application and let our microservice architecture take shape from it. We will implement patterns with a testing application.
Chapter 10, Monitoring, explains how to monitor your microservice architecture, benefiting from our PaaS. We will also describe and use Grafana to provide an additional monitoring system.
Chapter 11, Building Microservices Using Spring Boot 2, explains how to create, through Spring Boot, the same microservices that were developed in the previous chapters.
Chapter 12, Building Microservices Using Vert.X, explains how to realize, through Vert.x, the same microservices developed in the previous chapters.
Readers are required to have some knowledge of Java EE and HTTP-based application principles.
Specific installation instructions are given in the respective chapter's README file in their respective folders on GitHub.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Cloud-Native-Microservices-with-Jakarta-EE. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
This book uses open source components. You can find the source code of their open source projects along with license information at: https://github.com/jlprat/reactive-jee/blob/master/LICENSE
We acknowledge and are grateful to these developers for their contributions to open source.
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/9781788837866_ColorImages.pdf.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "Every time a new item is published by the observable, the onNext() method is called on each subscriber until the observable finishes its data flow."
A block of code is set as follows:
<!--https://mvnrepository.com/artifact/io.reactivex.rxjava2/rxjava --><dependency> <groupId>io.reactivex.rxjava2</groupId> <artifactId>rxjava</artifactId> <version>2.1.14</version></dependency>
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
public interface
FootballPlayerRepository
extends
CrudRepository
<
FootballPlayer
,
Integer
> {}
Any command-line input or output is written as follows:
$ java -listmods
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Click the Generate Project button to download a scaffold of a Maven project."
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
We are living in a new era of information technology. All people like me, who started work at the beginning of the 2000s, have gone through a constant but gradual evolution of languages, frameworks, and architectures. The last year has marked a great change in the way we approach a software release.
The great competition that drives the global market has changed the cultural approach of companies, which now have a milestone target—the reduction of time to market. The need to release a new business service as soon as possible is the main target of a company, regardless of their business area.
From an information technology point of view, this need has been translated into a complete review of development platforms and their updating and evolution processes.
From an enterprise point of view, this change, defined as digital disruption, is leading to the need to review company structures with regard to the organization of roles and skills, as well as to the policies of continuously updating to keep up with market needs. The community side of developers has led to a conceptualization of ideas as has not been seen for some time.
The best way to comprehend all the ideas that are being born around these concepts is through the open source model.
In this chapter, we will cover the following topics:
Open source
The Java programming language
OpenJDK 9 and 10
Java EE – MicroProfile.io – Jakarta EE
First of all, we start with a definition of open source—it is a way of thinking about the development of software that encourages the sharing of ideas and code. All sections of a product—documentation, source code, and so on—should be made publicly available. Using this model, you can build a product that will be able to benefit from the continuous improvement boosts given by the community in terms of standards, security, and technology evolution.
Sometimes, people confuse open source with the concept of no cost, which means we can use the technology for free. Using a technology only on the basis of its cost (cheap versus expensive) can expose your project to very high risks, including the failure of the objectives set. This way of perceiving open source is extremely reductive and dangerous.
Open source is much more. It is a model, like a philosophy, that encourages open collaboration and the sharing of ideas. An idea becomes stronger and more useful if more people collaborate to identify the weaknesses in order to improve them and find the right solutions. The intent is to promote these ideas in order to create an ecosystem based on solid rules for building the architecture of the future and to make all ideas freely available.
In this way, a community is created that cannot only develop the ideas that have emerged, but also continues the work of improvement, evolution, and dissemination. We can therefore state that, as in all other sectors, even in information technology, unity is strength.
Once the standards on which the technologies are based have been identified, it is possible to move on to their realization. In this stage as well, open source represents the best approach.
All stacks of software can grow in a better way if implemented under the open source model. Imagine having a community spread around the world that could test, evaluate, update, and fix your code in many different scenarios; a team composed of people, of different cultures and different skills, linked by a common goal—to create and consolidate a development framework. What company has such a special team?
If we think about the most common tools and framework used in information technology, we could immediately have an idea of how much open source communities are involved in our work life:
Software foundations:
Eclipse Foundation
:
http://www.eclipse.org/
Linux Foundation
:
https://www.linuxfoundation.org/
Python Software Foundation
:
https://www.python.org/psf/
OpenJDK
:
http://openjdk.java.net/
Operating systems
:
Fedora
:
https://getfedora.org/
Linux kernel
:
https://www.kernel.org/
CentOS
:
https://www.centos.org/
Containers
:
Docker
:
https://www.docker.com/
Kubernetes
:
https://kubernetes.io/
Middleware
:
Apache Software Foundation
:
http://apache.org/
WildFly
:
http://www.wildfly.org/
Jakarta EE
:
https://jakarta.ee/
Operations
:
Ansible
:
https://www.ansible.com/community
KVM
:
http://www.linux-kvm.org/page/Main_Page
OpenShift
:
https://www.openshift.com/
OpenStack
:
https://www.openstack.org/
Storage
:
Ceph
:
https://ceph.com/
Gluster
:
https://www.gluster.org/
This is only a fraction of the great number of open source communities involved in just a few critical areas. Do you still continue to think that open source means only free of cost?
One of the key points of the open source model is participation. Collaboration between people in the community is fundamental and solves one big question that companies often have—should they build a solution from scratch, or buy a solution that implements their requirements?
It's difficult to have all the skills needed to build an entire development framework. Buying a product from a vendor may solve the problem and reduce the effort of implementation, but leaves you unable to know the limit of your solution and the margins for improvement.
Using an open source-based solution gives you the opportunity to know exactly what you're using, letting you know whether your solution will be able to adapt to the future evolutions of information technology.
You should choose your open source community and project based on your needs.
Now you are ready to build your environment using open source products, frameworks, languages, and so on, and do the following:
Share your knowledge through blogs, social networks, and all free channels that give you the opportunity to disseminate knowledge and encourage the exchange of ideas.
Create your source code and donate it to the community, using one of the open source licenses and standards (
https://opensource.org/licenses
).
Fork, star, watch, and create issues on open source repositories, such as GitHub, in order to promote good principles and ideas.
Take part in the source life cycle of the open source project, and submit code that is able to solve issues that you may encounter during your experience.
Help with documentation, in order to allow an increasingly clear and simple use of open source code.
Help to test features; this could help the community to increase the strength of code, and gives an easy-to-understand example of usage of code.
In other words, you can become part of the community and make your contribution according to your skills, and the time you can dedicate.
From the application development perspective, open sourcing has provided a great contribution over the years. One of the most popular programming languages that has grown (thanks to the help of open source communities—this is one that will be the leading actor in our microservice journey) is Java.
Java is a full-featured and general-purpose programming language that was initiated in 1991 by a team led by James Gosling and Patrick Naughton at Sun Microsystems. Let's take a look at the evolution of Java in the hands of its developers.
Sun Microsystems released the first Java public implementation, version 1.0, in 1996. The concept of write once run anywhere, with the promise of great portability of software and ease of learning and use from the developers (in particular for automatic memory management and object-oriented paradigms) have all facilitated the rapid spread of Java in the information technology ecosystem.
The evolution and spread of the language was fast and continuous. After the two releases JDK 1.1 (February, 1997) and Java Standard Edition (JSE) 1.2 (December, 1998), Sun Microsystems released Java Platform, Enterprise Edition (Java EE (which was formerly known as Java 2 Platform, Enterprise Edition (J2EE)).
This was intended as a set of specifications, based on Java Platform, Standard Edition (Java SE), dedicated to enterprise applications that were rapidly moving from a desktop's local environment to a web browser environment.
At the end of 2006, Sun decided to donate the major part of the core code of the Java Virtual Machine (JVM), Standard and Enterprise Edition, as open source software under the terms of the General Public License (GPL). At the beginning of 2007, Sun completed the process, making all of its JVM's code available under free software and open source distribution terms. The final result of this process is the creation of OpenJDK, which became the open source implementation of the Java SE.
The work Sun did during these 10 years, from the first public release of 1996 to the birth of OpenJDK and the open source release of the JVM core and JSE platform in 2007, ideally made its role with regard to Java seem like that of an evangelist.
After this great period, Oracle Corporation acquired Sun Microsystems in 2009-2010.
At the beginning of this new era, Oracle declared that it will continue supporting and investing in Java for customers. You can take a look at the declaration on the following site: https://web.archive.org/web/20100131091008/http://www.oracle.com/us/technologies/java/index.html
Despite this declaration; the resignation from Oracle of James Gosling, the father of Java, in 2010; and the lawsuit against Google in 2012 related to the use of Java in the Android SDK; changed the perception of the community about the future of the Java language.
Oracle tried to give new impulse to Java and, after almost five years, released a new Java SE version (JDK 7 - July, 2011) and a new Java Enterprise Release (Java EE 7 - June, 2013). Furthermore, OpenJDK became a reference implementation of Java SE since version 7.
The rapid evolution of business requirements and the slowdown of the Java source life cycle convinced Oracle to change the strategy about the Java platform with a clear bet on the open source model.
OpenJDK binaries are the reference implementation of the JSE platform. OpenJDK is an incubator of the latest new features and has defined time-based releases that will be delivered every year in March and September. The version numbers follow the schema of year-month (YY.M). Unlike the previous release approach, this one will not be delayed to await a major feature to be completed and stabilized—an example was the delay of JDK 8 due to Jigsaw project issues, which was then retargeted into JDK 9.
With the new model, the new features will not be merged all together into a release source control repository until they are complete. If they are not ready to be included in a new release, they will be retargeted for the next release or later. The intention of this model is to avoid problems with a feature that, if not ready, could delay an entire release that could contain other features useful for developers.
Those enterprises and organizations that don't necessarily want or need to upgrade at a rapid pace will be free to choose a vendor to have support for a specific Java version, depending on market reaction. The same choice was also made for Java EE.
During the years, the platform became very big. The need to maintain backward compatibility and the delay of new Java SE releases, on which it depends, have made the platform very difficult to manage, delaying its evolution and making it unattractive for environments, such as cloud and microservices, in continuous evolution.
At the end of 2017, Oracle announced the donation of Java EE to the Eclipse Foundation. Initially, the project was named Eclipse Enterprise for Java (EE4J). After a survey taken by the community, the name of Java EE was changed, in order to avoid legal problems due to the fact that Oracle owns the trademark for the name Java, to Jakarta Enterprise Edition (Jakarta EE)—the entry point for the new platform is Java EE 8.
Under the umbrella of the Eclipse Foundation community, and with the commitment of the major vendors, the Enterprise Edition platform could start a new life in order to accelerate the adoption for the implementation of business applications for a cloud-native world.
The migration of all source code to Jakarta EE is proceeding quickly but, in the meantime, the evolution of the cloud environment and microservices require immediate answers in terms of standards and implementation models.
For this reason, Eclipse MicroProfile was created, as it's meant to optimize Enterprise Java for a microservice architecture. MicroProfile is aimed at spurring innovation that may result in future as a standard, but at the moment requires a faster rate of change than the intentionally measured pace of a standard process.
The expectation is that the existing Eclipse MicroProfile community and other open source communities should continue leading the way. Jakarta EE will incorporate Java innovations from these projects and communities into new versions in order to have complete and strong standards.
The following screenshot shows the history of Java EE releases, in terms of versions and the time duration between each of them, in months:
As you can see, the intervals between releases keep getting longer, and the last release version, which is Java EE 8, came out after 52 months!
In the next section, we will analyze the details of the latest OpenJDK versions, 9 and 10, and the Java EE 8 platform. These represent the base on which Eclipse MicroProfile is found, which is the Java Enterprise proposal for the realization of microservice architectures in cloud environments.
Java SE 9 and 10 introduce some important new features and improvements.
A detailed analysis of the new features is out of the scope of this book. We will look at the main innovations that have brought added value to the use of Java within cloud platforms and microservices.
Let's start with Java SE 9, the revolutionary element entailing the modularization of the JDK reached through the Jigsaw project (http://openjdk.java.net/projects/jigsaw/).
The main goals of this new feature are as follows:
Make Java SE more flexible and scalable
Improve security and maintainability
Make it easier to construct, maintain, deploy, and upgrade large applications
Enable improved performance
Two of the main criticisms made by the community toward the Java SE platform were the slowness in the release of the newer versions, as described previously, and the size of the JDK both in terms of space occupation and class size (approximately 4,240 classes in JDK 8).
In cloud environments and devices related to Internet of Things (IoT) architectures, these aspects represented an important limit.
But, it was not easy to find a solution that would allow overcoming these limits without abandoning one of the cornerstones of Java SE—the backward compatibility between versions.
It was, therefore, difficult to eliminate obsolete classes or remove classes designed for internal use but used intensively, especially by the framework, via Java reflection. The most famous example is the one put up by Sun Microsystems, which is related to the com.sun.misc.Unsafe class. It specified that: sun.* packages are not part of the supported, public Java interface. If you want to see the actual release, you can visit this link: https://www.oracle.com/technetwork/java/faq-sun-packages-142232.html
Through the Jigsaw project, it was not only possible to modularize the JDK in its core code but also to provide a tool for the realization of applications able to significantly decouple the interfaces of exposure of its services with respect to the actual implementation.
For JDK core code, it is possible to encapsulate JDK APIs, as described in JEP 260 (http://openjdk.java.net/jeps/260), using the following approach:
Encapsulate, by default, all internal APIs that are considered non-critical.
Encapsulate all internal APIs, that are considered critical, for which exist, in JDK 8, supported replacements.
Do not encapsulate critical internal APIs, but implement the following steps:
Deprecate them in JDK 9
Define a plan to remove these APIs in JDK 10
Implement a workaround solution via a command-line parameter
Remove, from the JDK distribution, a limited number of supported
Java Community Process
(
JCP
) standard APIs
Remove the extension mechanisms and the endorsed standards override
Java EE modules, due to the Jigsaw project, are not resolved by default.
In this way, you can easily obtain a small bootable Java runtime that contains only the features, in terms of classes and interfaces that you really need, avoiding the presence of useless code and that can have only negative side effects in terms of footprint and space allocation.
You could easily analyze this using the following command:
$ java -listmods
As mentioned before, both the JDK and the application can benefit from modular development. Decoupling the components present in the applications is essential in microservice architectures, which need a very agile software life cycle to reduce time to market.
Using a modularity approach, you could easily achieve the following:
Loose coupling between components
Clear contracts and dependencies between components
Hidden implementation using strong encapsulation
The main element in your implementation is the module.
Developers can organize their code into a modular structure, within which are declared dependencies inside their respective module definition files.
The properties of a module are defined into a file named module-info.java that contains the following attributes:
The module name
The module's packages that you want to make available publicly
The dependencies, direct or transitive, that the module depends on
The list of the services that the module consumes
All possible implementation of the service that the module provides
The following are the main keywords used to set the main features of a module through the module-info.java file:
module
: The module definition file starts with this keyword followed by its name and definition.
provides ... with ...
: The
provides
keyword is used to indicate that the module provides implementations for a defined service interface. The service interface is expressed using the
with
keyword.
requires
: This keyword is used to indicate the dependencies of the modules. A module name has to be specified after this keyword and the list of dependencies are set through multiple required directives.
transitive
:
This keyword
is set after the
requires
keyword; with this feature, you are declaring that any module that depends on the module defining
requires transitive <modulename>
gets an implicit dependence on the
<modulename>
.
uses
:
This keyword
is used to indicate the service interface that this module is using; a type name, complete with fully qualified class or interface name, has to be specified after this keyword.
opens
:
This keyword
is used to indicate the packages that are accessible only at runtime; you can also use them for introspection, using Reflection APIs. This is quite important for libraries and frameworks that use reflection APIs in order to be as abstract as possible; the
opens
directive can also be set at module level—in this case, all packages of the module are accessible at runtime.
exports
:
This keyword
is used to indicate the packages of the module that are publicly available; a package name has to be specified after this keyword.
But the two approaches, Java Jigsaw module and Open Service Gateway Initiative (OSGi), have some differences.
OSGi's adoption is largely due to its support for dynamic component control. In this case, plugins or components are loaded dynamically and then activated, deactivated, and even updated or removed as needed. Presently, this dynamic module life cycle is not available with Java modules.
Additionally, compared with Java modules, OSGi supports improved versioning. Other OSGi advantages are related to isolation; for example, bundle changes require only the direct dependencies to be recompiled, whereas a Java module's entire layer, along with all child layers, need to be recompiled if just one module changes.
The downside is that OSGi bundles still suffer from class path issues, such as runtime exceptions for missing dependencies, or arbitrary class loading for packages with the same name.
Additionally, OSGi requires a class loader per module, which can affect some libraries that expect only a single class loader. Java modules don't allow split packages which is considered a big improvement in Java overall, and don't have similar class loader requirements or restrictions. One big advantage Java modules have over OSGi is compiler support.
I think we can get the most out of the modularization of the application components in a microservice architecture, combining the best of both technologies. The overall strategy is to use Java modules to modularize libraries (either imported or exported) and the JVM itself, and use OSGi on top to handle application modularity and dynamic life cycle control.
JDK 10 introduced some new features. As mentioned earlier, we will concentrate on the most important features related to cloud environments and microservice architecture.