Modern Java EE Design Patterns - Apphosting.io

Transcription

Modern Java EEDesign PatternsBuilding Scalable Architecture forSustainable Enterprise DevelopmentMarkus Eisele

Modern Java EE DesignPatternsBuilding Scalable Architecturefor Sustainable Enterprise DevelopmentMarkus Eisele

Modern Java EE Design Patternsby Markus EiseleCopyright 2016 O’Reilly Media. All rights reserved.Printed in the United States of America.Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA95472.O’Reilly books may be purchased for educational, business, or sales promotional use.Online editions are also available for most titles (http://safaribooksonline.com). Formore information, contact our corporate/institutional sales department:800-998-9938 or corporate@oreilly.com.Editor: Brian FosterProduction Editor: Shiny KalapurakkelCopyeditor: Charles RoumeliotisProofreader: Jasmine KwitynOctober 2015:Interior Designer: David FutatoCover Designer: Karen MontgomeryIllustrator: Rebecca DemarestFirst EditionRevision History for the First Edition2015-10-05: First Release2016-01-15: Second ReleaseWhile the publisher and the author have used good faith efforts to ensure that theinformation and instructions contained in this work are accurate, the publisher andthe author disclaim all responsibility for errors or omissions, including without limi‐tation responsibility for damages resulting from the use of or reliance on this work.Use of the information and instructions contained in this work is at your own risk. Ifany code samples or other technology this work contains or describes is subject toopen source licenses or the intellectual property rights of others, it is your responsi‐bility to ensure that your use thereof complies with such licenses and/or rights.978-1-491-93982-6[LSI]

Table of ContentsAcknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v1. Enterprise Development Today. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Enterprise Goals and ObjectivesResistant to Change and Economically EfficientDevelopers Left AloneTechnology-Centric Versus Business-CentricAims and Scope223332. History of Java EE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Mistakes We MadeEvolution Continues with ESBsChallenges and Lessons Learned6793. Designing Software for a Scalable Enterprise. . . . . . . . . . . . . . . . . . . 13Greenfield Versus BrownfieldDomain-Driven DesignService CharacteristicsMicroservices Best PracticesIndependently Deployable and Fully ContainedCrosscutting Concerns1516171926264. Java EE and Microservices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31Matching the Real WorldThe Missing PiecesMigration Approaches323435iii

5. Microservices Design Pattern. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39Common PrinciplesAggregator PatternProxy PatternPipeline PatternShared ResourcesAsynchronous Messaging3940414243446. Conclusion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47A. Additional Technologies and Team Considerations. . . . . . . . . . . . . . . 49B. Further Resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55iv Table of Contents

AcknowledgmentsWriting books takes a lot more time than reading them—and itrequires a lot more people to be successful at it. I am thankful tohave had the technical support and creativity of Mark Little, ArunGupta, and Daniel Bryant throughout the writing process andbeyond.I cannot forget my girls here. Thank you! I love you! v

CHAPTER 1Enterprise Development TodayEnterprise is a noun. One of its meanings refers to a project orundertaking, especially a bold or complex one. But it also refersmore generally to businesses or corporations. Used in the context ofsoftware technology, the term encapsulates a mixture of these mean‐ings, which is underlined by the inability to adopt new technologiesat a reasonable speed due to a large organization’s inability to movequickly. Nevertheless, all those attributes and descriptions are verypersonal based on specific work environments. And not everythingabout this negative introduction is bad. The reasons behind this areobvious: those complex undertakings or large organizations need amuch higher level of standardization than startups. Changing asmall thing for one out of a hundred projects might lead to unantici‐pated problems.One major technology that has become a standard platform acrossmost enterprises to build complex—and stable—applications is JavaEnterprise Edition (Java EE). And while this technology stack hascome a long way since its inception in 1998, it is still not meant to beused for innovation and the adoption of more cutting-edge technol‐ogies and development paradigms.Nevertheless, innovation and constant improvement are the driversbehind enterprises and enterprise-grade projects. Without innova‐tion, there will be outdated and expensive infrastructure compo‐nents (e.g., host systems) that are kept alive way longer than thesoftware they are running was designed for. Without constant vali‐dation of the status quo, there will be implicit or explicit vendor1

lock-in. Aging middleware runs into extended support and only afew suppliers will still be able to provide know-how to develop for it.Platform stacks that stay behind the latest standards attempt tointroduce quick and dirty solutions that ultimately produce techni‐cal debt.And typically every 5 to 10 years, the whole software industry, espe‐cially in the enterprise integration or enterprise application space,spits out a new methodology or architectural style that promises tomake everything 10 times more productive, agile, flexible, andresponsive. As a result, we’ve seen everything from the creation ofenterprise application integration, web services, and serviceoriented architecture (SOA) to component-based architectures andenterprise service buses (ESBs).Enterprise Goals and ObjectivesAs technology has evolved, the decision makers in enterprise ITdepartments have implemented new capabilities and processesacross their organizations. Thus, IT has changed operations andturnaround for the better. But besides this technical standardizationand forward march of progress in internal operations and cost cut‐ting, these departments are still accused of not understanding theneeds of the business. Operations and buying decisions are stillfocused on generating quick results from investments and long-termcost savings. These results ignore the need for new business require‐ments or market developments, such as the still growing mobilemarket or the new communication style of a whole generation.Resistant to Change and EconomicallyEfficientSpeaking of this mismatch, operations and business have always fol‐lowed completely distinct goals while working on the greater good.Operations and sourcing have won out mostly. It’s an easier businesscase to calculate how much a corporation-wide standardization for aJava EE application server can produce in savings than to examinethe individual lines of source code and maintenance that must bedealt with for each individual project. And it’s not only the differ‐ence in mindset behind this. It’s also about long-term support andlicense agreements. Instead of changing the foundation and every‐2 Chapter 1: Enterprise Development Today

thing attached to it a couple of times a year, decisions need to guar‐antee a decent support level over many years. Following this, the gapbetween what latest technology is state-of-the-art and what enterpri‐ses allow developers to work with grows larger each year.Developers Left AloneEven if the preceding analysis barely scratches the surface, it revealswhy developers are feeling left alone in those enterprise settings.Having to fight the same stack day in and day out might have advan‐tages for generating knowledge about common pitfalls and short‐comings, but it also puts a strong block on everything that promisesto solve problems more elegantly, in shorter timeframes, and with alot less code. And we haven’t even talked about the other problemthat results from this.Technology-Centric Versus Business-CentricMany traditional enterprises have become strongly business-centricand mostly treat IT and operations as cost centers. The goal of pro‐viding homogenous IT services was mostly reached by overly focus‐ing on IT architectures, information formats, and technology selec‐tion processes to produce a standard platform for application opera‐tions. This produced a dangerous comfort zone that siphons atten‐tion away from the real value of business software: the businessdomains and relevant processes whose standardization and optimi‐zation promise a much higher payback than just operational opti‐mizations.The good news is that many organizations have started to takenotice and are undertaking changes toward easier and more efficientarchitecture management. But change is something that doesn’t nec‐essarily have to come from above; it is also the responsibility ofevery developer and architect. As a result, today’s buzzwords have tobe incorporated in a manageable way by all parties responsible forcreating software.Aims and ScopeSo, there’s a lot to reflect on here. This report focuses on how enter‐prises work and how the situation can be improved by understand‐ing how—and when—to adopt the latest technologies in such anDevelopers Left Alone 3

environment. The main emphasis is on understanding Java EEdesign patterns, as well as how to work with new development para‐digms, such as microservices, DevOps, and cloud-based operations.This report also introduces different angles to the discussion sur‐rounding the use of microservices with well-known technologies,and shows how to migrate existing monoliths into more finegrained and service-oriented systems by respecting the enterpriseenvironment. As you’ll come to find out, Java EE is only a verysmall—yet crucial—component of today’s enterprise platformstacks.4 Chapter 1: Enterprise Development Today

CHAPTER 2History of Java EE“Develop once, run everywhere!” This developer promise was thekey driving force behind much of the success enjoyed by the Javaprogramming language. And as interest in Java continued to risethrough broad adoption, the need for robust enterprise-grade appli‐cations soared. The advent of the Internet and the first browser ver‐sions led to the implementation of the first web server in Java as wellas the introduction of the Servlet and JSP specifications. These twospecifications became the foundation for the Java 2 Enterprise Edi‐tion (J2EE) platform, and from 1999 to 2003, the number of con‐tained Java Specification Requests (JSRs) grew from 10 to 18. Theplatform was renamed Java EE in 2006 (and now carries its versionnumber on the tail end). As of the writing of this report, the mostrecent version is Java EE 7 (JSR 342), with Java EE 8 (JSR 366) due torelease at the end of 2016.Enterprises adopted Java EE early—and often—because of the manyadvantages it promised, such as centralized infrastructures, a scala‐ble, transactional, and standardized programming model, highthroughput, and reliable operations. However, every single promisecame with a drawback, and it took a while until the platform as aspecification embraced operational and developer performance.Given the slow uptake of new versions by both vendors and custom‐ers, we still see a lot of Java EE 5-based applications out in the wild(this particular release dates back to mid-2006).5

Mistakes We MadeTraditionally, Java EE applications followed the core pattern definedin the book Core J2EE Patterns and were separated into three mainlayers: presentation, business, and integration. The presentationlayer was packaged in Web Application Archives (WARs) whilebusiness and integration logic went into separate Java Archives(JARs). Bundled together as one deployment unit, a so-called Enter‐prise Archive (EAR) was created.The technology and best practices around Java EE have always beensufficient to build a well-designed monolith application. But mostenterprise-grade projects tend to lose a close focus on architecture.The aspects of early Java EE applications outlined in Figure 2-1 don’tmake assumptions about their technical capabilities, and are derivedfrom experience in the field.Figure 2-1. Typical enterprise Java applicationThose applications could be scaled with the help of more instancesof the application server and a load balancer. If the responsiblearchitect thought about reuse here, he most likely considered imple‐menting a common JAR or library that became part of all the appli‐cations in the enterprise. Crosscutting concerns, such as single signon (SSO), were taken care of by enterprise access management6 Chapter 2: History of Java EE

(EAM) solutions, and there are even more centralized enterpriselevel infrastructures (e.g., logging, monitoring, and databases).Because everything was too coupled and integrated to make smallchanges, applications also had to be tested with great care and frombeginning to end. A new release saw the light of day once or twice ayear. The whole application was a lot more than just programmedartifacts: it also consisted of uncountable deployment descriptorsand server configuration files, in addition to properties for relevantthird-party environments.Even the teams were heavily influenced by these monolithic soft‐ware architectures. The multimonth test cycle might have been themost visible proof. But besides that, projects with lifespans longerthan five years tended to have huge bugs and feature databases. Andif this wasn’t hard enough, the testing was barely qualified—noacceptance tests, and hardly any written business requirements oridentifiable domains in design and usability.Handling these kinds of enterprise projects was a multiple teameffort and required a lot of people to oversee the entire project.From a software design perspective, the resulting applications had avery technical layering. Business components or domains weremostly driven by existing database designs or dated business objectdefinitions. Our industry had to learn those lessons and we man‐aged not only to keep these enterprise monoliths under control, butalso invented new paradigms and methodologies to manage themeven better.Evolution Continues with ESBsAnother technology was created in the advent of business-centereddesigns and the broader shift into more service-oriented organiza‐tions. The enterprise service bus (ESB) promised to deliver reusabil‐ity and exchangeability by still standing up as a centralized andmanaged infrastructure component. Evangelized by many vendors,this technology was poised to be the number one solution to all ofthe monolithic applications in existence.All of the applications needed to be sliced and rebuilt to supportexchangeable services. Service-oriented architectures (SOA) werethe new paradigm behind this. Unfortunately, the interface technol‐ogy of choice tended to be web services (WS). Web services trans‐Evolution Continues with ESBs 7

port data between systems by encoding it into XML and transport‐ing it via the Simple Object Access Protocol (SOAP). This intro‐duced a significant amount of additional code and descriptors intomost projects (see Figure 2-2).Figure 2-2. ESB-based architecturesWhat’s more, every ESB came with its own tooling and barely two ofthem could be used without it. As a result, codebases grew even fur‐ther and developers now had to learn to work with overloaded IDEsto wire all the parts of an application together. Rewiring was now thenew coding for the first projects under development.Instead of switching protocols or serialization methods for the rele‐vant endpoints, every route in the ESB ended up being a transfor‐mation. These new possibilities introduced a significant amount of8 Chapter 2: History of Java EE

additional complexity by just offering new methods of transforma‐tion and routing inside the ESB. What was monolithic and hard totest until now just became distributed and even harder to test.Although the distribution aspects were not critical, the complexdependencies created serious issues. Small changes in the ESB’srouting and transformation logic had a large impact and for a longtime there’s been no way to even stage those centralized ESB config‐urations through the different environments—and that’s before weeven think about versioning them.While the technology evolved and best practices started to mature,the biggest impact fell on operations. The distributed applicationhad to be monitored, and most importantly, scaled to fit the avail‐able resources and required demand. This simple sentence covers acomplete set of individual components, starting with the operatingsystem and its resources, which host a single application server orcluster, which itself is hosting any number of web services, all theway up to the scaling of the ESB.Only completely integrated platforms and expensive, specializedmonitoring solutions could help control these deployments. Theearly days of ESBs were also the days of initial experiments with cor‐porate data models. With business processes becoming the newfirst-level application design approach and spanning many differentattributes, the relevant domain objects needed to be aligned as well.The customer entity turned out to have many more attributes whenit was used to complete a process, instead of just one applicationserving a bunch of related use cases. We learned that data segmenta‐tion was a critical success factor.Challenges and Lessons LearnedFrom what you’ve read so far, it’s pretty clear that enterprise projectscontain challenges on varying levels. And going through the last 5 to10 years of evolution in this field, it is obvious that the technicalchallenges haven’t been the only ones. It took some time, but thefirst experts mastered the complexity and refactored the first patternand best practices.Our industry also had to learn to handle project management differ‐ently, and new project management methodologies became broadlyaccepted. Iterative and agile approaches required a more finegrained cut of requirements and teams, and this led to even moreChallenges and Lessons Learned 9

frequent changes, which had to be pushed to test and production.Automation and reliability in the software delivery process weresoon accepted practices and made it possible to quickly deliver newfeatures even in the more inflexible setting of an enterprise-gradeproject.DevOps: Highly Effective TeamsAnother very important part of successful software delivery was atighter coupling between operations and development. With morefrequent changes and a very high automation rate, the number ofdeployments to individual environments spiked. This was some‐thing straight deployment processes could hardly handle. This iswhy DevOps was born. At its core, the DevOps movement is aboutteam culture. It aims at improving communication and collabora‐tion between developers, operations, and other IT professionals.Based on automation and tooling, it helps organizations to rapidlyput high-quality software into production. Even more than that, itmanifested itself in a new team communication methodologyembracing frequent changes. Development teams not only wantedto just produce code, but also were responsible for pushing com‐plete changes down the DevOps chain into production.Microservices: Lightweight and FastCentralized components no longer fit into this picture, and evenheavyweight application servers were revisited alongside wordy pro‐tocols and interface technologies. The technical design went back tomore handy artifacts and services with the proven impracticality ofmost of the service implementation in SOA- and ESB-basedprojects. Instead of intelligent routing and transformations, micro‐services use simple routes and encapsulate logic in the endpointitself. And even if the name implies a defined size, there isn’t one.Microservices are about having a single business purpose. And evenmore vexing for enterprise settings, the most effective runtime formicroservices isn’t necessarily a full-blown application server. Itmight just be a servlet engine or that the JVM is already sufficient asan execution environment. With the growing runtime variationsand the broader variety of programming language choices, thisdevelopment turned into yet another operations nightmare. WherePlatform as a Service (PaaS) offerings used to be the number one10 Chapter 2: History of Java EE

solution, a new technology found its place in the stack for the nextgeneration of enterprise applications.Containers: Fully Contained ApplicationsIf operations can’t provide full support for all of the available lan‐guages and runtimes out there, there has to be something else fillingthe gap. Instead of hiring an army of specialists for a multitude ofruntime environments, containers became an obvious choice. Con‐tainers are an approach to virtualization in which the virtualizationlayer runs as an application within the operating system (OS). TheOS’s kernel runs on the hardware node with several isolated guestvirtual machines (VMs) installed on top of it. The isolated guests arecalled containers.They finally gave application developers the opportunity and toolingto not only build, test, and stage applications, but also the completemiddleware infrastructure, including the relevant configurationsand dependencies. The good news here was that projects no longerdepended on centralized platform decisions, and operations werestill able to ensure a smooth production.Public, Private, Hybrid: Scalable InfrastructuresThe number of environments needed for those projects spiked. Andnone of the changes just discussed effectively saved money in opera‐tions. Even worse, the additional time spent on making DevOps andcontainers functional needed to be compensated. This might be themost compelling explanation for the still-growing demand for cloudinfrastructures.Although virtualization has proven to be cost-efficient by runningany number of the same instances, it was never easy to manage andwas tightly coupled to the hardware underneath. As a matter of fact,it still had to scale alongside the demand of the projects, and therewas a cost assigned to every single instance. It literally had to bebought and owned by the project in most cases.Cloud infrastructures changed this quickly—pay for what you usewith rapid provisioning. Just recently, cloud platforms received anupgrade to their capabilities with the emerging container technolo‐gies. Instead of spinning up instances of application servers or data‐bases, today’s most relevant products rely on containers to define theChallenges and Lessons Learned 11

software stack to run and provide enough flexibility to projectswhile maintaining manageability alongside cost-effective operations.We can see the result of the earlier-mentioned methodologies andtechnologies in Figure 2-3. This image is a pyramid of modernenterprise application development and reflects the cornerstones offuture development. The following chapters will dive deeper into thedetails of each part of the pyramid.Figure 2-3. The pyramid of modern enterprise applicationdevelopment12 Chapter 2: History of Java EE

CHAPTER 3Designing Software for aScalable EnterpriseLooking back at the lessons learned alongside the latest develop‐ments in software, the most pressing question becomes: how dodevelopers and architects design software for enterprises that needto scale more quickly? With clouds and containers serving as thenew foundation, and more and more applications adopting micro‐services architecture, everything we knew about software designseems to be turned on its head.With that said, the basic concepts of software architecture anddesign that were developed to cater to a multitude of stakeholders,follow separation of concern principles, generate quality, and guar‐antee the conceptual integrity of our applications remain the pri‐mary drivers for creating great software. And yet we do need to payclose attention to some of the principles we already know andchoose the correct approach.Microservices remain an ever-present buzzword and viable designpattern, yet upon closer inspection the name represents a new termfor a style of architecture that has been around a while: modulardesign. Microservices are the right choice if you have a system thatis too complex to be handled as a monolith. And this is exactly whatmakes this architectural style a valid choice for enterprise applica‐tions. As Martin Fowler states in his article about “MicroservicePre‐mium”:13

The fulcrum of whether or not to use microservices is the complex‐ity of the system you’re contemplating.This quote is perfectly explained in the accompanying graphic in thesame article (reproduced here in Figure 3-1). The main point is tonot even consider using a microservices architecture unless youhave a system that’s too large and complex to be built as a classicalmonolith. As a result, the majority of modern software systemsshould still be built as a single application that is modular and takesadvantage of state-of-the-art software architecture patterns.Figure 3-1. Microservices: productivity versus base complexity (source:Martin Fowler; um.html)As we have been building complex enterprise systems in Java EE foryears, it may seem unlikely that we will find one suitable for amicroservices architecture. But this is not the complete truth: tech‐nical or business complexity should not be the only reason forchoosing this kind of architecture.One of the most important concerns in the current developer envi‐ronment is team size. With growing developer teams, it seems morereasonable and effective to have completely decoupled services. Butthere aren’t any hard metrics or even estimates about complexitythat make a decision easy. The best way to decide which route topursue will be the overall setting. This starts with the decision aboutwhich software system needs to be worked on.14 Chapter 3: Designing Software for a Scalable Enterprise

Greenfield Versus BrownfieldMost of today’s enterprise software was built years ago and stillundergoes regular maintenance to adopt the latest regulations ornew business requirements. Unless there is a completely new busi‐ness case or significant internal restructuring, the need to constructa piece of software from scratch is rarely considered. But let’sassume we want to assess the need or even advantage of implement‐ing a new microservices-based architecture. What would be themost successful way to proceed? Start with a new development fromscratch (i.e., greenfield), or tear apart an existing application intoservices (i.e., brownfield)? Both approaches offer some risks andchallenges.I remain convinced that it is much easier to partition an existing,“brownfield” system than to do so up front with a new, greenfieldsystem.—Sam Newman (Source:http://bit.ly/1FMXNjs)As usual, the common ground is small but critical: you need toknow the business domain you’re working on. And I would like totake this point even further: enterprise projects, especially thoseconsidered long-term, tend to be sparse on documentation, and it iseven more important to have access to developers who are workingin this domain and have firsthand knowledge.Additionally, I believe any decision will have various shades of com‐plexity. There are a range of options in brownfield developments(i.e., migrations), and this allows for a very selective and risk-freeapproach that will fit most business requirements (more on this laterin “Migration Approaches” on page 35). No matter which avenueyou pursue, you’ll need to evaluate your own personal toolbox forsuccess. Therefore, in order to help you make the best decision pos‐sible, let’s get to know the best methodologies and design patternsbehind modern enterprise application development.Greenfield Versus Brownfield 15

Domain-Driven DesignThe philosophy of domain-driven design (DDD) is about placingthe attention at the heart of the application, focusing on the com‐plexity of the core business domain. Alongside the core businessfeatures, you’ll also find supporting subdomains that are oftengeneric in nature, such as money or time. DDD aims to create mod‐els of a problem domain. All the implementation details—like per‐sistence, user interfaces, and messaging—come later. The most cru‐cial thing to understand is the domain, because this is what a major‐ity of software design decisions are going to be based on. DDDdefines a set of concepts that are selected to be implemented in soft‐ware, and then represented in code and any other software artifactused to construct the final system.Working with a model always happens within a context. It can varybetween different requirements or just be derived, for example, fromthe set of end users of the final system. The chosen context relates tothe concepts of the model in a defined way. In DDD, this is calledthe bounded context (BC). Every domain model lives in preciselyone BC, and a BC contains precisely one domain model. A BC helpsto model and define interactions between the BC and the model inmany different ways. The ultimate mapping for the model is theinside view of the one related BC.Assuming we already have a layered application approach (e.g., pre‐sentation, application, domain, infrastructure), DDD acts on thedomain layer. While the application layer mostly acts as a mediatorbetween presentation, domain, and infrastructure (and holds addi‐tional crosscutting concerns, such as security and transactions), thedomain layer only contains the business objects. This includes thevalue objects themselves and all related artifacts (e.g., property files,translations) and the module structure, which typically is exp

digms, such as microservices, DevOps, and cloud-based operations. This report also introduces different angles to the discussion sur‐ rounding the use of microservices with well-known technologies, and shows how to migrate existing monoliths into more fine-grained and service-oriented systems by respecting the enterprise environment.