45,59 €
Find out how to craft effective, business-oriented Java EE 8 applications that target customer's demands in the age of Cloud platforms and container technology.
This book is for experienced Java EE developers who are aspiring to become the architects of enterprise-grade applications, or software architects who would like to leverage Java EE to create effective blueprints of applications.
Java EE 8 brings with it a load of features, mainly targeting newer architectures such as microservices, modernized security APIs, and cloud deployments. This book will teach you to design and develop modern, business-oriented applications using Java EE 8. It shows how to structure systems and applications, and how design patterns and Domain Driven Design aspects are realized in the age of Java EE 8. You will learn about the concepts and principles behind Java EE applications, and how to effect communication, persistence, technical and cross-cutting concerns, and asynchronous behavior.
This book covers Continuous Delivery, DevOps, infrastructure-as-code, containers, container orchestration technologies, such as Docker and Kubernetes, and why and especially how Java EE fits into this world. It also covers the requirements behind containerized, zero-dependency applications and how modern Java EE application servers support these approaches. You will also learn about automated, fast, and reliable software tests, in different test levels, scopes, and test technologies. This book covers the prerequisites and challenges of distributed systems that lead to microservice, shared-nothing architectures. The challenges and solutions of consistency versus scalability will further lead us to event sourcing, event-driven architectures, and the CQRS principle. This book also includes the nuts and bolts of application performance as well as how to realize resilience, logging, monitoring and tracing in a modern enterprise world. Last but not least the demands of securing enterprise systems are covered.
By the end, you will understand the ins and outs of Java EE so that you can make critical design decisions that not only live up to, but also surpass your clients' expectations.
This book focuses on solving business problems and meeting customer demands in the enterprise world. It covers how to create enterprise applications with reasonable technology choices, free of cargo-cult and over-engineering. The aspects shown in this book not only demonstrate how to realize a certain solution, but also explain its motivations and reasoning.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 575
Veröffentlichungsjahr: 2017
BIRMINGHAM - MUMBAI
Copyright © 2017 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 author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be 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.
First published: October 2017
Production reference: 1051017
ISBN 978-1-78839-385-0
www.packtpub.com
Author
Sebastian Daschner
Copy Editor
Safis Editing
Reviewer
Melissa McKay
Project Coordinator
Vaidehi Sawant
Commissioning Editor
Aaron Lazar
Proofreader
Safis Editing
Acquisition Editor
Alok Dhuri
Indexer
Aishwarya Gangawane
Content Development Editor
Rohit Kumar Singh
Graphics
Abhinash Sahu
Technical Editor
Pavan Ramchandani
Production Coordinator
Nilesh Mohite
Languages in our industry come and go, and the pace at which hip new languages come out only seems to increase. Every year, new languages come out and each has the colossal job of building an entire ecosystem around itself before the next new darling language comes and steals all the fickle early adopters. As each trend waxes and wanes, so do the ecosystems built around them.
Those of us who invest heavily in these trending ecosystems are often bitten by a common set of problems that lead to failures at the business level, losing project momentum due to the inability to find and hire developers. The new solutions presented are often the same old idea, but with a youthful misunderstanding of the problem space that leads to real performance and reliability problems. As the ecosystem matures, the act of recognizing and realigning to the true complexity of systems often results in severe incompatibilities. Tooling choices are often narrow or buggy, or they simply never materialize.
The unbeatable source of strength of the Java ecosystem over the last 20 years has been its standards, Java EE being chief among them. There have been 53 Java Specification Requests (JSRs) completed under the Java EE umbrella, ranging from XML parsing to JSON parsing, Servlets to JAX-RS, binary protocols to RESTful protocols, front-end technologies such as JSF or MVC, APIs for marshaling data to XML (JAX-B) or JSON (JSON-B) . The breadth of specifications is so wide that even if you do not think of yourself as a Java EE user, if you are a Java developer, you are definitely leveraging it in some way. With an estimate of 9 million Java developers worldwide, this is a stable and experienced talent pool.
Major deployments of Java EE range from Walmart, the world's largest retailer and third largest employer, to NASA’s SOFIA program, scanning space at 40,000 feet. While the developer community is large and the corporations that use it are larger, the modern Java EE runtimes are incredibly small. Walmart and NASA, for example, use Apache TomEE, an implementation that is 35 MB on disk, boots in a second and consumes less that 30 MB of memory. This low profile is indicative of all modern implementations including WildFly, Payara, and LibertyProfile. The Java EE tools, cloud and IDE landscape is filled with competitive choices, almost too many to track. The 200+ person company ZeroTurnaround, for example, is built on a product that added instant deploy options to Java EE servers.
With such an expansive ecosystem that has almost 20 years of history, truly getting to the essence of what makes Java EE great today and how to put it into practice for today’s Microservices world can be a challenge. It’s all too easy to find very informed, but ultimately dated information from 2, 5, and 10 years back. The authoritative tone of one article one date can directly conflict with equally authoritative, but ultimately contrarian perspective of another author on a different year. In fact, a challenge almost unique to Java EE is its history. Few technologies last long enough and evolve so much.
This book, like the author himself, represents a new generation of Java EE. The chapters in this book guide the reader through the journey of leveraging Java EE in the context of today’s Microservice and Containerized world. Less of a reference manual for API syntax, the perspectives and techniques in this book reflect real-world experience from someone who has recently gone through the journey themselves, meticulously annotated the obstacles, and has them ready to share. From packaging to testing to cloud usage, this book is an ideal companion to both new and more experienced developers who are looking for an earned insight bigger than an API to help them realign their thinking to architect modern applications in Java EE.
David Blevins Founder and CEO, Tomitribe
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 motorbike. Steve and Sebastian have launched JOnsen, a Java unconference held at a hot spring in the countryside of Japan.
There are many people whom I had the privilege to meet during my career, and who had a great impact not only on my work but also this book and without whom this would not have been possible. This list of people grows and grows every year. All of them are indirectly helped shaping this book, which I immensely appreciate.
There are a few friends who had a direct impact on this book and whom I particularly want to thank.
Kirk Pepperdine, for his tireless aspiration to myth-bust the world of software performance and for the permission to use jPDM. His invaluable experience not only vastly improved the quality of this book but also greatly educated me personally.
Melissa McKay, for her tireless reviews, being eager (and crazy) enough to review this whole book, what greatly improved the quality, for sharing her experience in Enterprise Java, and not least for inspiration and motivation.
David Blevins, for sharing the passion in the topic of Java EE and writing the foreword to this book.
Andy Gumbrecht, for help not only in the topic of enterprise testing but also the English language.
Markus Eisele, for igniting the spark of this work.
Philipp Brunenberg, for creating constructive inspiration and not least, tons of motivation through weeks of writing.
Melissa McKay has been a software developer, for the last 15 years in the private sector working with various types of applications, both in a contracting capacity for external clients and on enterprise products. Her current focus is on creating Java server applications used in the communications and video industry. Her interests include clustered systems, and she has a particular passion for solving issues with concurrency and multithreaded applications.
Melissa regularly attends the JCrete unconference in Crete, Greece, and had the pleasure of attending the initial launch of the JOnsen unconference in Japan. She enjoys volunteering for technology events for kids including JavaOne4Kids and JCrete4Kids. She is a member of the Content Committee for JavaOne 2017 and an active member of the Denver Java User Group.
For support files and downloads related to your book, please visit www.PacktPub.com.
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.PacktPub.comand 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.PacktPub.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.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/1788393856.
If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
Introduction
New demands in enterprise systems
Modern way of realizing enterprise systems
Relevance of Java EE in modern systems
Java EE 8 update and roadmap
Java Community Process
What to expect in the book
Designing and Structuring Java Enterprise Applications
The purpose of enterprise applications
What developers should focus on
Meeting customer's demands
Outer enterprise project structure
Business and team structures
Software projects contents
Application source code
Software structures
Version control systems
Binaries
Build systems
Single versus multi-module projects
Illusion of reusability
Technical dependencies
Organizational challenges
Reusability considerations
Project artifacts
One project per artifact
Build systems for Java EE
Apache Maven
Gradle
Structuring for modern frontend technologies
Enter JavaScript frameworks
Organizing modern frontends
Enterprise project code structure
Situation in enterprise projects
Horizontal versus vertical layering
Business-driven structure
Designing reasonable modules
Realizing package structures
Package contents
Horizontal package layering
Flat module package
Entity Control Boundary
Packages
Package access
Don't over-enforce architecture
Summary
Implementing Modern Java Enterprise Applications
Use case boundaries
Core domain components of modern Java EE
EJB and CDI - differentiation and integration
CDI producers
Emitting domain events
Scopes
Patterns in Java EE
Design patterns revisited
Singleton
Abstract factory
Factory method
Object pool
Decorator
Facade
Proxy
Observer
Strategy
Further patterns
Domain-Driven Design
Services
Entities
Value objects
Aggregates
Repositories
Factories
Domain event
External and cross-cutting concerns in enterprise applications
Communication with external systems
How to choose communication technology
Synchronous HTTP communication
Representational State Transfer
Java API for RESTful web services
Mapping HTTP content types
Validating requests
Mapping errors
Accessing external systems
Stability when consuming HTTP
Accessing Hypermedia REST services
Asynchronous communication and messaging
Asynchronous HTTP communication
Message-oriented communication
Server-sent events
WebSocket
Connecting enterprise technology
Database systems
Integrating RDBMS systems
Mapping domain models
Integrating database systems
Transactions
Relational databases versus NoSQL
Cross-cutting concerns
Configuring applications
Caching
Flow of execution
Synchronous execution
Asynchronous execution
Asynchronous EJB methods
Managed Executor Service
Asynchronous CDI events
Scopes in asynchronicity
Timed execution
Asynchronous and reactive JAX-RS
Concepts and design principles of modern Java EE
Preserving maintainable code with high quality
Summary
Lightweight Java EE
Lightweight enterprise technology
Why Java EE standards?
Convention over configuration
Dependency management of Java EE projects
Lightweight way of packaging applications
Java EE application servers
One application per application server
Summary
Container and Cloud Environments with Java EE
Motivations and goals
Infrastructure as code
Stability and production readiness
Containers
Java EE in the container
Container orchestration frameworks
Realizing container orchestration
Java EE in orchestrated containers
Connecting external services
Configuring orchestrated applications
12-factor applications and Java EE
Have one codebase tracked in revision control, many deploys
Explicitly declare and isolate dependencies
Store config in the environment
Treat backing services as attached resources
Strictly separate build and run stages
Execute the app as one or more stateless processes
Export services via port binding
Scale out via the process model
Maximize robustness with fast startup and graceful shutdown
Keep development, staging, and production as similar as possible
Treat logs as event streams
Run admin/management tasks as one-off processes
Cloud, Cloud native, and their benefits
Cloud native
Summary
Application Development Workflows
Motivation and goals of productive development workflows
Realizing development workflows
Version control everything
Building binaries
Java artifacts
Artifact versions
Building containers
Quality assurance
Deployment
Configuration
Credentials
Data migration
Adding database structures
Changing database structures
Removing database structures
Implementing migration
Testing
Build metadata
Going to production
Branching models
Technology
Pipeline-as-code
Workflows with Java EE
Continuous Delivery culture and team habits
Responsibility
Check in early and often
Immediately fixing issues
Visibility
Improve continuously
Summary
Testing
The necessity of tests
Requirements of well-crafted tests
Predictability
Isolation
Reliability
Fast execution
Automation
Maintainability
What to test
Definition of test scopes
Unit tests
Component tests
Integration tests
System tests
Performance tests
Stress tests
Implementing tests
Unit tests
Implementation
Technology
Component tests
Motivation
Implementation
Delegating test components
Technology
Integration tests
Embedded containers
Embedded databases
Running integration tests
Code level integration tests versus system tests
Shortcomings of integration tests
Shortcomings of system tests
Conclusion
System tests
Managing test scenarios
Simulating external concerns
Designing system tests
Deploying and controlling external mocks
Performance tests
Motivation
Key performance indicators
Developing performance tests
Insights
Running tests locally
Maintaining test data and scenarios
Importance of maintainable tests
Signs of lack of test quality
Test code quality
Test technology support
Summary
Microservices and System Architecture
Motivations behind distributed systems
Challenges of distribution
Communication overhead
Performance overhead
Organizational overhead
How to design systems landscapes
Context maps and bounded contexts
Separation of concerns
Teams
Project life cycles
How to design system interfaces
API considerations
Interface management
Change-resilient APIs
Breaking the business logic
Hypermedia REST and versioning
Documenting boundaries
Consistency versus scalability
Event sourcing, event-driven architectures, and CQRS
Shortcomings of CRUD-based systems
Scalability
Competing transactions
Reproducibility
Event sourcing
Benefits
Eventually consistent real world
Event-driven architectures
Eventual consistency in event-driven architectures
Enter CQRS
Principles
Design
Benefits
Shortcomings
Communication
Microservice architectures
Sharing data and technology in enterprises
Shared-nothing architectures
Interdependent systems
12-factor and cloud native applications
When to use and when not to use microservices
Implementing microservices with Java EE
Zero-dependency applications
Application servers
Implementing application boundaries
Implementing CQRS
System interfaces
Example scenario using Apache Kafka
Integrating Java EE
CDI events
Event handlers
State representation
Consuming Kafka messages
Producing Kafka messages
Application boundaries
Integrating further CQRS concepts
Java EE in the age of distribution
Discovering services
Communicating resiliently
Validating responses
Breaking timeouts and circuits
Bulkheads
Shaking hands and pushing back
More on being resilient
Summary
Monitoring, Performance, and Logging
Business metrics
Collecting business metrics
Emitting metrics
Enter Prometheus
Realization with Java EE
Integrating the environment
Meeting performance requirements in distributed systems
Service level agreements
Achieving SLAs in distributed systems
Tackling performance issues
Theory of constraints
Identifying performance regression with jPDM
Subsystems
Actors
Application
JVM
Operating system and hardware
jPDM instances - production situations
Analyzing the jPDM instances
Dominating consumer - OS
Dominating consumer - none
Dominating consumer - JVM
Dominating consumer - application
Conclusion
Technical metrics
Types of technical metrics
High frequency monitoring versus sampling
Collecting technical metrics
Boundary metrics
Logging and tracing
Shortcomings of traditional logging
Performance
Log levels
Log format
Amounts of data
Obfuscation
The concerns of applications
Wrong choice of technology
Logging in a containerized world
Journaling
Tracing
Tracing in a modern world
Typical performance issues
Logging and memory consumption
Premature optimization
Relational databases
Communication
Threading and pooling
Performance testing
Summary
Security
Lessons learned from the past
Security in a modern world
Security principles
Encrypt communication
Delegate security concerns
Treat user credentials properly
Avoid storing credentials in version control
Include tests
Possibilities and solutions
Encrypted communication
Protocol-based authentication
Decentralized security
Proxies
Integration in modern environments
Implementing security in Java EE applications
Transparent security
Servlets
Java principals and roles
JASPIC
Security API
Authentication mechanisms
Identity stores
Custom security
Accessing security information
Summary
Conclusion
Motivations in enterprise development
Cloud and Continuous Delivery
Relevance of Java EE
API updates introduced in Java EE 8
CDI 2.0
JAX-RS 2.1
JSON-B 1.0
JSON-P 1.1
Bean Validation 2.0
JPA 2.2
Security 1.0
Servlet 4.0
JSF 2.3
JCP and participation
MicroProfile
Eclipse Enterprise for Java
Appendix: Links and further resources
Java EE 8 brings with it a load of features, mainly targeting newer architectures such as microservices, modernized security APIs, and cloud deployments. This book will teach you to design and develop modern, business-oriented applications using Java EE 8. It shows how to structure systems and applications, and how design patterns and Domain-Driven Design aspects are realized in the age of Java EE 8. You will learn about the concepts and principles behind Java EE applications and how they affect communication, persistence, technical and cross-cutting concerns, and asynchronous behavior.
This book focuses on solving business problems and meeting customer demands in the enterprise world. It covers how to create enterprise applications with reasonable technology choices, free of cargo-cult and over-engineering. The aspects shown in this book not only demonstrate how to realize a certain solution, but also explain its motivation and reasoning.
With the help of this book, you will understand the principles of modern Java EE and how to realize effective architectures. You will gain knowledge of how to design enterprise software in the age of automation, Continuous Delivery, and cloud platforms. You will also learn about the reasoning and motivation behind state-of-the-art enterprise Java technology, which focuses on business.
Chapter 1, Introduction, introduces Java EE enterprise applications and why Java EE is (still) relevant in modern systems.
Chapter 2, Designing and Structuring Java Enterprise Applications, shows how to design the structure of an enterprise application using examples, keeping design enterprise applications with business use cases in mind.
Chapter 3, Implementing Modern Java Enterprise Applications, covers how to implement modern Java EE applications and why that technology choice is still relevant today.
Chapter 4, Lightweight Java EE, teaches you how to realize lightweight Java EE applications with a small footprint and minimal third-party dependencies.
Chapter 5, Container and Cloud Environments with Java EE, explains how to leverage the benefits of containers and modern environments, how to integrate enterprise applications, and how this movement encourages productive development workflows.
Chapter 6,Application Development Workflows, coversthe key points for fast development pipelines and high software quality, from Continuous Delivery to automated testing and DevOps.
Chapter 7, Testing, as the name suggests, covers the topic of testing, which helps enable you to ensure high quality in software development automated testing with reasonable coverage.
Chapter 8, Microservices and System Architecture, shows the key points of how to design systems after the project and company circumstances, how to construct applications and their interfaces, and when microservice architectures make sense.
Chapter 9, Security, covers how to realize and integrate security concerns in today's environments.
Chapter 10, Monitoring, Performance, and Logging, covers why traditional logging is harmful, how to investigate performance issues, and how to monitor the business and technical aspects of an application.
Appendix, Conclusion, recapitulates and summarizes the contents of the book, including giving advice and motivation.
To execute and perform the code examples given in the book, you will require the following tools configured in your system:
NetBeans, IntelliJ or Eclipse IDE
GlassFish Server
Apache Maven
Docker
Jenkins
Gradle
This book is for experienced Java EE developers who aspire to become the architects of enterprise-grade applications, or for software architects who would like to leverage Java EE to create effective blueprints of applications.
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "The EJB is annotated using@Startup."
A block of code is set as follows:
@PreDestroy public void closeClient() { client.close(); }
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
private Client client; private List<WebTarget> targets; @Resource
ManagedExecutorService mes;
In order to increase simplicity and readability, some code examples are shortened to their essence. Java import statements are only included for new types and code parts that are insignificant to the example are omitted using three dots (...).
Any command-line input or output is written as follows:
mvn -v
New terms and important words are shown in bold.
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.
To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. You can download the code files by following these steps:
Log in or register to our website using your e-mail address and password.
Hover the mouse pointer on the
SUPPORT
tab at the top.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on
Code Download
.
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/Architecting-Modern-Java-EE-Applications. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at [email protected] with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
Compared to the past, we see a lot of new demands in enterprise software. It is no longer sufficient to just develop some piece of software and deploy it to an application server. Or maybe it never was.
The world moves faster than ever. And moving fast is one of the most important criteria of today's IT companies. We see companies that can adapt to the real world and the customer's needs with high velocity. The expected time to market of features has shrunk from years and months to weeks and less. In order to cope with this, companies not only need to introduce new technology or throw more money at their business problem, but also rethink and refactor the way they operate at the core of their IT.
What does move fast mean in this context? What aspect does this include? And which methods and technology support this?
Moving fast is all about quickly adapting to the needs of the market and customers. If a new feature is desired or looks promising, how long does it take to get from the initial idea to the feature being in the user's hands? If new infrastructure is required, how long does it take from that decision to the running hardware? And do not forget, if a certain piece of software is developed with all that velocity, is there automated quality control in place that ensures everything will work as expected and not break the existing functionality?
In software development, most of these questions lead to Continuous Delivery and automation. Software that is being developed needs to be built, tested, and shipped in an automated, fast, reliable, and reproducible way. A reliable, automated process not only leads to quicker turnarounds but ultimately higher quality. Automated quality control, such as software tests, are part of the process. In modern software development, Continuous Delivery, automation, and proper testing are some of the most important principles.
Traditionally, infrastructure was a big bottleneck in most companies. Smaller companies often struggled to provide new infrastructure with a limited budget. Bigger companies mostly fail to implement fast and productive processes. For big corporations, in most of the cases the issue is not the budget but the implementation of the processes. It is not untypical to wait days and weeks for new infrastructure, due to approvals and overly complex processes that technically could have been finished in a matter of minutes.
Therefore, application infrastructure and how it is designed is an important aspect. Chapter 5, Container and Cloud Environments with Java EE, will show you the topic of modern cloud environments. Actually, we will see that it's not so much about whether cloud service providers are being used. Fast and productive processes certainly can be implemented with on-premises hardware. Rather, it is more a question of whether processes are implemented properly, using well-suited technologies.
Modern infrastructure needs to be set up in a matter of minutes, in an automated, fast, reproducible, and reliable way. It should adapt to changing demands without great effort. To meet this criterion, infrastructure should be defined as code, either with procedural scripts or in declarative descriptors. We will see how infrastructure as code impacts software development workflows and which technologies support it.
These demands will impact the way teams operate. It is no longer sufficient for development teams to just develop and let the operational teams deal with running the software and facing potential issues on production. This practice always leads to tensions and finger pointing once critical errors occurred in production. Instead, the common goal should be to deliver software that fulfills a purpose. By defining the required infrastructure and configuration as code, development and operations teams will naturally move together. This DevOps movement, a compound of development and operations, aims toward accountability of the software team as a whole. Everybody involved is responsible for customers being able to use proper software. This is more an organizational challenge than a technical one.
On a technical aspect, Continuous Delivery, as well as the 12-factor and cloud nativebuzzwords attempted to meet these demands. The 12-factor and cloud native approaches describe how modern enterprise applications should be developed. They define requirements, not only for the development processes but also for the way applications are run. We will look into these approaches, modern cloud environments, and where Java EE supports us, later in this book.
Now we will look at how enterprise software projects are being developed.
Following the approach of meeting the needs of real-world customers, we will face the question of the purpose of the application that we want to develop. The motivations and purposes of the enterprise systems need to be clear before immediately going into technology details. Otherwise, software is just being developed for the sake of developing software. Sadly, this is the case way too often. By focusing on business logic and the principles of Domain-Driven Design, as wonderfully described in the book by Eric Evans, we will ensure that the software we are building will meet the business demands.
Only after the application's purpose and responsibility is clear to the stakeholders, can we focus on the technological aspects. Teams should favor technologies that can not only implement the business use cases appropriately but also reduce the amount of work and overhead. Developers should be able to focus on the business, not the framework and technology. Good frameworks support solving business problems in a lean way and don't want the developer's attention themselves.
The chosen technology should also support productive development workflows as much as possible. This not only includes automation and fast development turnarounds but also the ability to embrace modern infrastructure, such as Linux containers. In Chapter 4, Lightweight Java EE, and Chapter 5, Container and Cloud Environments with Java EE, we will have a closer look into the nuts and bolts of modern environments and how Java EE supports them.
Let's talk about Java EE since this is the topic of this book and it is relevant in enterprise systems.
Java EE and J2EE are being used heavily, especially in bigger companies. One of the advantages was always that the platform consists of standards that guarantee to be backwards compatible with older versions. Even old J2EE applications are guaranteed to still function in the future. This was always a big benefit for companies that are planning for the long term. Applications that are developed against the Java EE API can run on all Java EE application servers. Vendor-independent applications enable companies to build future-proof software that doesn't lock it into a specific solution. This turned out to be a sound decision that ultimately led to a mindset of the enterprise industry that standards, or de facto standards which everybody agrees upon, improve the overall situation.
Compared to the J2EE world, a lot has changed in Java EE. The programming model is totally different, much leaner, and more productive. This was drastically changed when the name switched from J2EE to Java EE 5, and especially since EE 6. We will have a look at the modern way of developing Java enterprise in Chapter 3, Implementing Modern Java Enterprise Applications. We will see what architectural approaches and programming models are being used and how the platform leverages development productivity much more than in the past. Hopefully, the idea of why Java EE now provides a modern solution to develop enterprise applications will become clear.
Right now, bringing this message out to the industry is actually more of a marketing and political challenge than a technical one. We still see tons of developers and architects who still consider Java EE to be the cumbersome, heavyweight enterprise solution of the J2EE age, which required a lot of time, effort, and XML. Enterprise JavaBeans (EJB), as well as application servers, have a particularly bad reputation due to their past. This is why a lot of engineers are biased toward that technology. Compared to other enterprise solutions, Java EE never saw much marketing targeted at developers.
In Chapter 4, Lightweight Java EE, we will see why modern Java EE is actually one of the most lightweight enterprise solutions. We will define the term lightweight aspects and see why the Java EE platform is more relevant than ever, especially in modern cloud and container environments. The impression the IT industry has of a particular technology is important for its success. I hope this chapter will shed some light into this topic.
Companies have usually chosen Java EE mostly because of its reliability and backwards compatibility. I personally favor Java EE because of its productivity and ease of use. In Chapter 4, Lightweight Java EE, and Chapter 5, Container and Cloud Environments with Java EE, we will cover more about this. In this book, I would like to show the readers why Java EE is a solution well-suited to today's enterprise demands. I will also show the technologies and standards, not in every detail, but rather how they are integrated with each other. I believe that focusing on the integrational part leads to a better understanding in how to effectively craft enterprise applications.
Let's have a very high-level overview of what has happened in Java EE version 8. The goal of this version is to improve the developer's experience even more, to streamline the API usage further, and to make Java EE ready for new demands in cloud environments. We saw two completely new JSRs, JSON-B (Java API for JSON Binding) and Security, together with improvements in existing standards. In particular, introducing JSON-B simplifies the integration of JSON HTTP APIs in a vendor-independent way.
The direction of Java EE is to improve the development of enterprise applications in regard to modern environments and circumstances. It turns out that modern environments are not only compatible with Java EE but encourage approaches that have been part of the platform for years. Examples are the separation of the API from the implementation, or application server monitoring.
On the long-term roadmap, there is better support for modern monitoring, health-checks, and resilience. Currently, these aspects have to be integrated in a few lines of codes, as we will see in later chapters. The long-term goal is to make that integration more straightforward. Java EE aims to let developers focus on what they should focus on - solving business problems.
What makes Java EE platform unique is the process of how it is specified. The standards of Java EE are developed as part of the Java Community Process (JCP). The JCP is a prime example of an industry that actively encourages participation in defining standards, not only from the few engineers involved but anybody interested in that technology. The platform comprises standards in the form of Java Specification Requests (JSR). These JSRs are not only relevant for Java and Java EE but also for technologies that build upon them, such as the Spring framework. Ultimately, the real world experience of these other technologies then again help shaping new JSRs.
During application development, and especially when encountering potential issues, the written specifications that emerge from the JSRs are extremely beneficial. The vendors who support the enterprise platform are required to provide the implementation in the way it's specified in these standards. That said, the specification documents inform both the vendors and developers as to how the technology will work. If some functionality is not met, the vendors are required to fix these issues in their implementations. This also means that developers, in theory, only have to learn and know these technologies, no vendor-specific details.
Every developer can participate in the Java Community Process to help in shaping the future of Java and Java EE. The Expert Groups who define the specific standards welcome constructive feedback from anybody interested in the topic, even if they're not active members of the JCP. Other than this, you're able to have a peek into the next versions of the standards even before they're released. These two facts are very interesting for architects and companies. There is not only insight into where the direction will go but also the possibility to contribute and make an impact.
These motivations were also two of the reasons why I personally specialized in Java EE. I have a background of enterprise development with the Spring framework. Besides the fact that both technologies are very similar in terms of the programming model, I especially valued the power of the CDI standard as well as the possibility to seamlessly use all of the technologies within the platform. I started to look into the specific JSRs that are part of the enterprise platform and started to contribute and provide feedback on features that were standardized back then. At the time of writing this book, I'm part of two Expert Groups, JAX-RS 2.1 and JSON-P 1.1. Helping to define these standards improved my knowledge in enterprise systems a lot. You are naturally obliged to dive deep into the topics, motivations, and solutions of the specific technology that you help standardize. And of course, it is somewhat satisfying to know that you helped in working on standards in the IT industry. I can only encourage developers to participate in the JCP, looking into what's currently developed, and to contribute and provide feedback to the Expert Groups.
I've decided to write this book about the things I learned in the past working on Java enterprise systems of all kinds. My motivation is to show you what a modern Java EE approach looks like. This, of course, first of all aims toward developing enterprise applications themselves, and modern programming models. I try to build up an impression as to how Java EE is used in the age of EE 8 and where the platform shines. There are new design patterns and paradigms being used that have emerged from modern framework approaches. If you were familiar with the J2EE world, you will hopefully see the advantage of modern Java EE. I try to show which of the old paradigms, constraints, and considerations that made J2EE sometimes being disliked among developers are not true anymore and can be discarded. Besides this, the book is an attempt to spread some enthusiasm and explain why I am convinced that Java Enterprise serves the purpose of realizing enterprise applications well.
That said, you, the reader, don't need prior knowledge of the J2EE world and patterns and best practices thereof. In particular, the programming model so different that I'm convinced it makes sense to showcase today's approach from a green field.
It you have built and designed J2EE applications, this is great. You will see what the challenges with past J2EE design patterns were, particularly when in the modern world, our domain can focus on business demands first and not the technology used to implement it. This is especially true when we follow the approaches of Domain-Driven Design. You will notice how many cumbersome and painful aspects of J2EE systems in the past can be eradicated in modern Java EE. The simplicity and power of the Java EE platform may inspire you to rethink certain approaches that we have done so far. Maybe you can try to take a mental step back to have a fresh, unbiased view on the technology.
This book is meant for software engineers, developers and architects who design and build enterprise applications. In the book, I will mostly use the term developers or engineers. That said, I am convinced that architects should also, from time to time, the more the better, touch source code and get their hands dirty with technology. This is not only to support other developers in the team but also important for themselves to get more real-world experience. In the same way all developers should have at least a basic understanding of the system's architecture and the reasoning for the architectural choices. Again, the better this mutual understanding is, the better will the communication and development function in the projects.
Modern enterprise application development touches much more than just the sole development. As we are seeing, new demands of enterprise applications, engineers care about development workflows, cloud environments, containers, and container orchestration frameworks. We will cover whether and how Java Enterprise fits into this world and what approaches and best practices there are that support this. This will tackle the topics of Continuous Delivery and automated testing, why they have such importance, and how they integrate with Java EE. We will also cover container technologies, such as Docker, and orchestration frameworks such as Kubernetes. In today's enterprise world it's important to show how a technology such as Java EE supports these areas.
Microservice architecture is a big topic, another of today's hypes. We will look at what microservices are about, and if and how they can be realized with Java EE. The topics of security, logging, performance, and monitoring will also be covered later in this book. I will point out what architects should know and be aware of in today's enterprise software world. The used choices of technology, especially when it comes to modern solutions that support applications; for example, in the areas of 12-factor or cloud native applications, serve as examples as to what would be chosen as of today. However, it is much more important to understand what the concepts and motivations behind these technologies are. Used technology changes day by day, principles and concepts or computer science live much longer.
For all of the subjects that I cover in this book, my approach is to show the motivations and reasoning behind solutions first, and then how they are applied and implemented in Java EE second. I believe that simply teaching a certain technology may certainly help developers in their daily jobs but they will not fully embrace the solution until the motivations behind it are completely understood. This is why I will also start with the motivations behind enterprise applications in general.
There is a lot of functionality included in Java EE, even more if you look into the past. This book does not aim to represent a full Java EE reference work. Rather, it is intended to provide real world experience as well as recommendations, call them best practices, tackling typical scenarios with pragmatic solutions. Now, please lean back and enjoy the journey through a modern enterprise software world.
Every piece of software is designed in a certain way. The design includes the architecture of the system, structure of the projects, and structure and quality of the code. It can either communicate the intentions well or obfuscate them. Engineers need to design an enterprise application or system, before it is implemented. In order to do that, the purpose and motivations of the software need to be clear.
This chapter will cover:
What aspects to focus on when developing software
Project build structures and Java EE build systems
How to structure enterprise projects modules
How to realize module package structures
Behind every action, be it in daily life, big organizations, or software projects, there should be a reason. We humans need reasons why we are doing things. In enterprise software development, there is no difference.
When we build software applications, the first question asked should be why?. Why is this piece of software needed? Why is it reasonable or required to spend time and effort to develop a solution? And why should the company care about developing that solution itself?
In other words, what is the application's purpose? What problem is this piece of software trying to solve? Do we want the application to implement an important business process? Will it generate revenue? Is it going to gather revenue directly, for example by selling products, or indirectly by marketing, supporting customers, or business processes? Are there other possibilities to support customers, employees, or business processes?
These and other questions target the application's business goals. Generally speaking, every piece of software needs a justification in the overall picture before we invest time and effort into it.
The most obvious legitimization is to implement necessary business use cases. These use cases bring certain value for the overall business and will sooner or later realize features and generate revenue. At the end of the day, the software should achieve the goal of implementing the business use cases as best as possible.
Therefore, software developers as well as project managers should first focus on meeting the business concerns and implementing the use cases.
This clearly sounds obvious, but too often the focus of enterprise projects starts drifting away into other concerns. Developer effort is spent on implementation details or features that have little benefit for solving the actual problem. How many logging implementations, home-grown enterprise frameworks, or over-engineered levels of abstractions have we seen in the past?
Non-functional requirements, quality of software, and so-called cross-cutting concerns are in fact an important aspect of software development. But the first and main focus of all engineering effort should be directed to meeting the business requirements and developing software that actually has a purpose.
We have the following questions:
What is the application's business purpose?
What are the most important features that users care about?
Which aspects will generate revenue?
The answers to these questions should be known to the stakeholders. If not, then the correct way would be to take a step back, look at the overall picture of the software landscape, and reconsider the software's right to exist. Not in all cases the motivation will be purely business-driven. There are, in fact, a lot of cases where we will implement solutions that do not directly generate revenue but do so indirectly, by supporting others. These cases are certainly necessary and we will cover them and the general topic of how to construct reasonable system landscapes in Chapter 8, Microservices and System Architecture.
Besides these supporting software systems, we focus on business aspects. Having this main goal in mind, the first thing to address is how to model the business use cases and transform them into software. Only after that, the use cases are implemented using certain technologies.
These priorities will also reflect the customer demands. The application's stakeholders care about software that fulfills its purpose.
Software engineers tend to see this differently. They care about implementation details and the elegance of solutions. Engineers are often passionate about certain technologies and spend much time and effort choosing the right solutions as well as implementing them well. This includes a lot of technical cross-cutting concerns, such as logging, and so-called over-engineering, which is not mandatory for the business domain. Embracing software craftsmanship certainly has its importance and is essential for writing better software, but many times it is orthogonal to the client's motivations. Before spending time and effort with implementation details, engineers should be aware of the client's demands first.
Project timeline requirements are another aspect to consider. Software teams weigh business use cases against the quality of technical solutions. They tend to postpone required software tests or quality measures in order to meet deadlines. The technology used to implement the business application should support effective and pragmatic development.
When seeing the enterprise world through the eyes of a paying customer or a manager with limited time and budget, software engineers will likely understand their priorities. Caring about revenue-generating use cases first is mandatory. Technical necessities beyond these are seen by customers and managers as a necessary evil.
The rest of this book will show you how to meet and balance these two motivations with Java EE.
Having the goal of business use cases in mind, let's move our focus a bit more down to earth to real-world enterprise projects. In later chapters, we will see what methods are there to help us reflecting the business domains in the architecture in a suitable way.
Software projects are usually developed by a team of engineers, software developers, or architects. For simplicity, we will call them developers. Software developers, architects, testers, and all kind of engineers should arguably program from time to time.
However, in most situations we have several people working simultaneously on a software project. This already requires us to take a few things into account, mainly communication and organizational overhead. When we look at the structure within organizations with several teams working on multiple projects, or temporarily even the same project, we deal with even more challenges.
The Conway's law claims that:
That being said, the way in which the teams are organized and communicate with each other will inevitably leak into software design. The organization chart of developers and their effective communication structures has to be considered when constructing software projects. We will have a detailed look into how to construct several distributed systems and more specific microservices inChapter 8,Microservices and System Architecture.
Even in a single project owned by a team of few developers, there will likely be multiple features and bug fixes being developed simultaneously. This fact impacts how we plan the iterations, organize, and integrate source code, and build and deploy runnable software. In particular Chapter 6, Application Development Workflows and Chapter 7, Testing will cover this topic.
Enterprise software projects include several artifacts necessary to build and ship applications. Let's have a closer look at them.
First of all, all enterprise applications, like probably any application, are written in source code. The source code is arguably the most important part of our software project. It represents the application and all its functionality at its core and can be seen as the single source of truth of software behavior.
The project's sources are separated into code that runs on production and test code to verify the application's behavior. The technologies as well as the quality demands will vary for test and production code. In Chapter 7, Testing, we will deeply cover the technologies and structures of software tests. Apart from that chapter, the focus of this book lies on production code, which is shipped and which handles the business logic.
The software project organizes the source code in certain structures. In Java projects, we have the possibility to cluster components and responsibilities into Java packages and project modules, respectively:
Structuring these components is obviously less a technical rather than an architectural necessity. Code that is packaged arbitrarily would technically run equally well. However, this structure helps engineers understanding the software and its responsibilities. By clustering software components that fulfill coherent features, we increase cohesion and achieve a better organization of the source code.
This and the next chapter will discuss the benefits of Domain-Driven Design, described in the book by Eric Evans, and the why and how to organize code in business-driven packages. For now, let's record that we group coherent components that form logical features into logical packages or project modules.
Java SE 9 comes with the possibility of shipping modules as Java 9 modules. These modules are, in essence, similar to the JAR files with the ability to declare dependencies and usages restrictions of other modules. Since this book is targeted for Java EE 8 and since the fact that the usage of Java 9 modules hasn't spread yet in real-world projects, we will cover only Java packages and project modules.
Breaking the structure of software projects further down, the next smaller unit of software components is a Java class. Classes and the responsibilities thereof encapsulate single functionalities in the domain. They are ideally loosely coupled and show a high cohesion.
A lot has been written about clean code practices and representing functionality in source code. The book Clean Code by Robert C. Martin, for example, explains methods such as proper naming or refactoring, that help achieve well-crafted source code in packages, classes and methods.
The source code is kept under version control, since most software projects require coordination of simultaneous code changes, made by multiple developers. Version control systems (VCS) have established themselves as mandatory to reliably coordinate, track, and comprehend changes in software systems.
There are a lot of choices of version control systems, such as Git, Subversion, Mercurial or CVS. In the last years, distributed revision control systems, particularly Git, have been widely accepted as the state-of-the-art tools. They use a so-called hash tree, or Merkle tree to store and resolve individual commits, which enables efficient diffs and merges.
Distributed VCS enables developers to work with project repositories in distributed ways, without constantly requiring a network connection. Every workstation has its own repository, which includes the full history and is eventually synchronized with the central project repository.
As of writing this book, the vast majority of software projects use Git as version control system.
The VCS project repository should only contain the sources that are produced and maintained by developers. Certainly, enterprise applications will have to be deployed as some kind of binary artifacts. Only these shippable binaries can be executed as runnable software. The binaries are ultimately the outcome of the development and build process.
In the Java world this means that the Java source code is compiled to portable bytecode and is usually packaged as Web Application Archive (WAR) or Java Archive (JAR), respectively. WAR or JAR files comprise all classes and files required to ship an application, framework dependency, or library. The Java Virtual Machine (JVM) finally executes the bytecode and together with that, our business functionality.
In enterprise projects the deployment artifacts, the WAR or JAR files, are either deployed to an application container or already ship the container themselves. The application container is needed, since beside their distilled business logic, enterprise applications will have to integrate additional concerns, such as application life cycle or communication in various forms. For example, a web application that implements certain logic but is not addressable over HTTP communication has little value. In Java Enterprise, the application container is responsible for providing this integration. The packaged application contains the distilled business logic and is deployed to a server, which takes care of the rest.
In recent years, more Linux container technologies such as Docker have emerged. This carries the ideas of shippable binaries even further. The binary then not only contains the packaged Java application, but all components required to run the application. This, for examples, includes an application server, the Java Virtual Machine, and required operating system binaries. We will discuss the topic of shipping and deploying enterprise applications, especially regarding container technology, in Chapter 4, Lightweight Java EE.
The binaries are produced as part of the software build process. It enables to reliably recreate all binaries from the repository's sources. Therefore, the binaries should not be kept under version control. The same is true for generated source code. In the past, for example, JAX-WS classes which are required for SOAP communication were usually generated from descriptor files. Generated source code is created during the build process and should also not be kept under version control. The idea is to keep only the distilled source code in the repository and no artifacts that can be derived from it.
The build process is first of all responsible for compiling the sources of a Java software project into bytecode. This happens every time changes have been made to the project. All modern build systems ship with useful conventions to minimize the required configuration.
