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