+ All Categories
Home > Documents >  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software...

 · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software...

Date post: 01-Jan-2021
Category:
Upload: others
View: 0 times
Download: 0 times
Share this document with a friend
797
Transcript
Page 1:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 2:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 3:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TitlePageJava9ProgrammingByExample

Yourguidetosoftwaredevelopment

PeterVerhas

BIRMINGHAM-MUMBAI

Page 4:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 5:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Java9ProgrammingByExample

Copyright©2017PacktPublishingAllrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.

Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.

PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

Firstpublished:April2017

Productionreference:1240417

PublishedbyPacktPublishingLtd.LiveryPlace35LiveryStreetBirminghamB32PB,UK.

ISBN978-1-78646-828-4

www.packtpub.com

Page 6:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 7:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Credits

Author

PeterVerhas

CopyEditors

MuktikantGarimellaZainabBootwala

Reviewer

JeffFriesen

ProjectCoordinator

UlhasKambali

CommissioningEditor

KunalParikh

Proofreader

SafisEditing

AcquisitionEditor

DenimPinto

Indexer

MariammalChettiyar

Page 8:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ContentDevelopmentEditor

NikhilBorkar

Graphics

AbhinashSahu

TechnicalEditor

HussainKanchwala

ProductionCoordinator

MelwynDsa

Page 9:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 10:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AbouttheAuthorPeterVerhasisaseniorsoftwareengineerandsoftwarearchitecthavingelectricalengineeringandeconomicsbackgroundfromTUBudapest(MsC)andPTEHungary(MBA),andalsostudiedatTUDelftandTUVienna.Hecreatedhisfirstprogramsin1979,andsincethenhehasauthoredseveralopensourceprograms.HehasworkedinseveralpositionsinthetelecommunicationsandfinanceindustriesandwastheCIOoftheHungarianstart-upindex.huduringitsearlydays.

PeterworksforEPAMSystemsinSwitzerland,participatinginsoftwaredevelopmentprojectsatvariouscustomersites,andhesupportstalentacquisitionbyinterviewingcandidates,trainingprogramsfordevelopers,andinternalmentoringprograms.

YoucanfollowPeteronTwitterat@verhas,LinkedIn,andGitHub,orreadhistechnicalblog,JavaDeep,athttp://javax0.wordpress.com.

Acknowledgementisthesectionofabookthateverybodyignoresbyturningthepages.Thistime,thissectionisabitdifferent.Iwillmentionafewpeopleandtheirrolesinthemakingofthisbookbut,atthesametime,Iwillexplainwhyandhowitisimportanttorelyonpeople,beingasoftwaredeveloper.Doingprofessionalworkisnotpossiblewithouthavingalife.Itisquiteobviousifyoutakethatliterally,butitisjustastruefiguratively.Ifyoudonotfindthebalancebetweenyourpersonalandprofessionallife,youwillburnoutandwillnotoperateprofessionally.Thisistheplacetomentionmyfamily,myparentswhomIamluckytostillhavearound,mywife,andmyalreadyadultkidswhoneverstoppedbelievinginmebeingabletodothiswork,whoknowmorethanwellwhatahypocriteIam,advocatingpersonal-professionallifebalance,andwhocontinuallypushedmeclosertothisequilibriumpointinlifesothatIcouldkeepperformingprofessionally.Forprofessionalwork,coworkersarealmostasimportantasfamilysupport.Itisimportantthatyousupportyourcolleaguesasmuchasyouaskthemfortheirsupport.Youlearnalotfrombooksandfromexperience,butyoulearnthemostfromotherpeople.Payattentiontoseniordevelopers.Youcan,however,learnjustasmuchfromjuniors.Nomatterhowaceyouare,fromtimetotime,arookiemayshedlightonatopic.Duringtheyears,Ilearnedalotfromjuniorswhobroughtafreshviewtothetable,askingshockingquestionsthatwereabsolutelyvalid.Icannotnameeachandeveryjuniorwhoaidedmyworkwithfreshout-of-the-boxthinking.Ican,andshould,however,namesomepeerprofessionalswhoactivelyparticipatedinthecreationofthisbookwiththeiradvice,discussions,andsuggestions.IshouldcertainlymentionKárolyOláhwhowasveryenthusiasticaboutmyproject,andherepresented,supported,andencouragedtheideainsideEPAMsystems.Heactivelydiscussedwiththeuppermanagementthatthesupportforwritingabookwellfitstheinnovationlineanddevelopmentofthecompany,andthepeoplewhoworktogether.Withouttheofficialsupportfromthecompanyprovidingextratimeforthetask,Iwouldnothavebeenabletocreatethisbook.Goodcompanyattractsgoodpeoplewhoarecleverandalsogoodtoworkwith.Ihadmanydiscussionsaboutthebook,topics,andhowtoexplaincertainaspectswithmyfellowEPAMers:KrisztiánSallai,PeterFodor,SándorSzilágyi,MantasAleknavicius,GáborLénard,andmanyothers.IwillseparatelymentionIstvánAttilaKovácsfromourBudapestofficewithwhomIdiscussedChapter5indetail,andwhogavemeveryvaluablefeedbackaboutthetopic.Ifhedoesnotknowsomething

Page 11:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

aboutJavaparallelcomputing,thenthatsomethingdoesnotexist.Asasummaryandtakeawayforthepatientreaderwhoreadthissectiontilltheend,technology,knowledge,skills,andexperienceareextremelyimportantforbeingaprofessionalJava9developer,butitisthepeoplewhoreallymatter.

Page 12:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 13:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AbouttheReviewerJeffFriesenisafreelanceauthorandsoftwaredeveloperwhohastaughtJavaintheclassroomandbywritingnumerousarticlesandbookssincethelate1990s.HeholdsaBachelorofSciencedegreeinComputerScienceandMathematics.Priortofreelancing,Jeffworkedfortelecommunications,investment,andsoftwaredevelopmentcompanies.

JefffreelancesasaJavaauthorandsoftwaredeveloper.

JeffhaswrittenJavaI/O,NIOandNIO.2andJavaThreadsandtheConcurrencyUtilitiesforApress.Fulldetailsareavailableonhiswebsite(http://javajeff.ca/cgi-bin/makepage.cgi?/books).

IthankNitinDasanfortheopportunitytotechreviewthisbook.IalsothankUlhasKambaliforassistingmewiththetechreviewprocess.

Page 14:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 15:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

www.PacktPub.comForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.

DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusatservice@packtpub.comformoredetails.

Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

https://www.packtpub.com/mapt

Getthemostin-demandsoftwareskillswithMapt.MaptgivesyoufullaccesstoallPacktbooksandvideocourses,aswellasindustry-leadingtoolstohelpyouplanyourpersonaldevelopmentandadvanceyourcareer.

Page 16:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Whysubscribe?

FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser

Page 17:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 18:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CustomerFeedback

ThanksforpurchasingthisPacktbook.AtPackt,qualityisattheheartofoureditorialprocess.Tohelpusimprove,pleaseleaveusanhonestreviewonthisbook'sAmazonpageathttps://www.amazon.com/dp/178646828X/.

Ifyou'dliketojoinourteamofregularreviewers,youcane-mailusatcustomerreviews@packtpub.com.WeawardourregularreviewerswithfreeeBooksandvideosinexchangefortheirvaluablefeedback.Helpusberelentlessinimprovingourproducts!

Page 19:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 20:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TableofContents

PrefaceWhatthisbookcovers

Whatyouneedforthisbook

Whothisbookisfor

Conventions

Readerfeedback

CustomersupportDownloadingtheexamplecode

Errata

Piracy

Questions

1. GettingStartedwithJava9GettingstartedwithJava

InstallingJavaInstallationonWindows

InstallationonMACOSX

InstallationonLinux

SettingJAVA_HOME

ExecutingjshellLookingatthebytecode

PackagingclassesintoaJARfile

ManagingtherunningJavaapplication

UsinganIDENetBeans

Eclipse

IntelliJ

IDEservicesIDEscreenstructure

Editingfiles

Managingprojects

Page 21:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Buildthecodeandrunit

DebuggingJava

Summary

2. TheFirstRealJavaProgram-SortingNamesGettingstartedwithsorting

Bubblesort

GettingstartedwithprojectstructureandbuildtoolsMake

AntInstallingAnt

UsingAnt

MavenInstallingMaven

UsingMaven

GradleInstallingGradle

SettinguptheprojectwithMaven

Codingthesort

UnderstandingthealgorithmandlanguageconstructsBlocks

Variables

Types

Arrays

Expressions

Loops

Conditionalexecution

Finalvariables

Classes

Inner,nested,local,andanonymousclasses

Packages

Methods

Interfaces

Page 22:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Argumentpassing

Fields

Modifiers

Objectinitializersandconstructors

Compilingandrunningtheprogram

Summary

3. OptimizingtheSort-MakingCodeProfessionalThegeneralsortingprogram

AbriefoverviewofvarioussortingalgorithmsQuicksort

ProjectstructureandbuildtoolsMavendependencymanagement

CodethesortCreatingtheinterfaces

CreatingBubbleSort

Amendingtheinterfaces

Architecturalconsiderations

CreatingunittestsAddingJUnitasdependency

WritingtheBubbleSortTestclass

GoodunittestsAgoodunittestisreadable

Unittestsarefast

Unittestsaredeterministic

Assertionsshouldbeassimpleaspossible

Unittestsareisolated

Unittestscoverthecode

Refactorthetest

Collectionswithwrongelements

Handlingexceptions

Generics

TestDrivenDevelopment

Page 23:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ImplementingQuickSortThepartitioningclass

Recursivesorting

Non-recursivesorting

ImplementingtheAPIclass

CreatingmodulesWhymodulesareneeded

WhatisaJavamodule

Summary

4. Mastermind-CreatingaGameTheGame

Themodelofthegame

JavacollectionsInterfacecollection

SetHashfunctions

Methodequals

MethodhashCode

ImplementingequalsandhashCode

HashSet

EnumSet

LinkedHashSet

SortedSet

NavigableSetTreeSet

ListLinkedList

ArrayList

Queue

Deque

MapHashMap

IdentityHashMap

Page 24:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Dependencyinjection

ImplementingthegameColorManager

Theclasscolor

JavaDocandcodecomments

Row

Table

GuesserUniqueGuesser

GeneralGuesser

TheGameclass

Creatinganintegrationtest

Summary

5. ExtendingtheGame-RunParallel,RunFasterHowtomakeMastermindparallel

Refactoring

Processes

Threads

Fibers

java.lang.Thread

PitfallsDeadlocks

Raceconditions

Overusedlocks

Starving

ExecutorServiceForkJoinPool

Variableaccess

TheCPUheartbeat

Volatilevariables

Synchronizedblock

Page 25:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Waitandnotify

LockCondition

ReentrantLock

ReentrantReadWriteLock

Atomicclasses

BlockingQueueLinkedBlockingQueue

LinkedBlockingDeque

ArrayBlockingQueue

LinkedTransferQueue

IntervalGuesser

ParallelGamePlayer

Microbenchmarking

Summary

6. MakingOurGameProfessional-DoitasaWebappWebandnetwork

IP

TCP/IP

DNS

TheHTTPprotocolHTTPmethods

Statuscodes

HTTP/2.0

Cookies

Clientserverandwebarchitecture

WritingservletsHelloworldservlet

JavaServerPages

HTML,CSS,andJavaScript

MastermindservletStoringstate

Page 26:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HTTPsession

Storingstateontheclient

DependencyinjectionwithGuice

TheMastermindHandlerclass

Storingstateontheserver

TheGameSessionSaverclass

RunningtheJettywebservlet

LoggingConfigurability

Performance

Logframeworks

Java9logging

Loggingpractice

Othertechnologies

Summary

7. BuildingaCommercialWebApplicationUsingRESTTheMyBusinesswebshop

Samplebusinessarchitecture

Microservices

Serviceinterfacedesign

JSON

REST

ModelViewController

SpringframeworkArchitectureofSpring

Springcore

Serviceclasses

Compilingandrunningtheapplication

TestingtheapplicationIntegrationtest

Applicationtest

Page 27:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Servletfilters

AuditloggingandAOP

Dynamicproxy-basedAOP

Summary

8. ExtendingOurE-CommerceApplicationTheMyBusinessordering

Settinguptheproject

OrdercontrollerandDTOs

Consistencychecker

AnnotationsAnnotationretention

Annotationtarget

Annotationparameters

Repeatableannotations

Annotationinheritance

@Documentedannotations

JDKannotations

UsingreflectionGettingannotations

Invokingmethods

Settingfields

FunctionalprogramminginJavaLambda

Streams

Functionalinterfaces

Methodreferences

ScriptinginJava9

Summary

9. BuildinganAccountingApplicationUsingReactiveProgrammingReactive...what?

Reactiveprogramminginanutshell

Page 28:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReactivesystemsResponsive

Resilient

Elastic

Message-driven

Back-pressure

Reactivestreams

ReactiveprogramminginJavaImplementinginventory

Summary

10. FinalizingJavaKnowledgetoaProfessionalLevelJavadeeptechnologies

Javaagent

PolyglotprogrammingPolyglotconfiguration

Polyglotscripting

BusinessDSL

Problemswithpolyglot

Annotationprocessing

ProgrammingintheenterpriseStaticcodeanalysis

Sourcecodeversioncontrol

Softwareversioning

Codereview

Knowledgebase

Issuetracking

TestingTypesoftests

Testautomation

Blackboxversuswhitebox

SelectinglibrariesFitforthepurpose

License

Page 29:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Documentation

Projectalive

Maturity

Numberofusers

The"Ilikeit"factor

Continuousintegrationanddeployment

Releasemanagement

Coderepository

Walkinguptheladder

Summary

Page 30:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 31:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PrefaceJavadrasticallychangedwiththeintroductionofJava8,andthischangehasbeenelevatedtoawholenewlevelwiththenewversion,Java9.Javahasawell-establishedpast,beingmorethan20yearsold,butatthesametime,itisnew,functional,reactive,andsexy.Thisisalanguagethatdeveloperslove,andatthesametime,itisthenumberonechoiceofdeveloperlanguageformanyenterpriseprojects.

ItisprobablymorelucrativetolearnJavanowthaneverbefore,startingwithJava9.WeencourageyoutostartyourprofessionaldevelopercareerbylearningJava9,andwehavedoneourbestinthisbooktohelpyoualongthisroad.Weassembledthetopicsofthebooksothatitiseasytostart,andyoucanfeelthethingsworkingandmovingverysoon.Atthesametime,wehavetriedtoreachveryfar,signalingtheroadaheadforaprofessionaldeveloper.

Thesandsoftimekeptmoving,andIdiscoveredfunctionalprogramming.

Icouldverywellseewhywritingside-effect-freecodeworked!IwashookedandstartedplayingwithScala,Clojure,andErlang.Immutabilitywasthenormhere.

However,Iwonderedhowtraditionalalgorithmswouldlookinafunctionalsettingandstartedlearningaboutit.

Adatastructureisnevermutatedinplace.Instead,anewversionofthedatastructureiscreated.Thestrategyofcopyandwritewithmaximizedsharingwasanintriguingone!Allthatcarefulsynchronizationissimplynotneeded!

Thelanguagescomeequippedwithgarbagecollection.So,ifaversionisnotneededanymore,runtimewouldtakecareofreclaimingthememory.

Allingoodtime,though!Readingthisbookwillhelpyouseethatweneednotsacrificealgorithmicperformancewhileavoidingin-placemutation!

Page 32:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 33:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhatthisbookcoversChapter1,GettingStartedwithJava9,givesyouajumpstartinJava,helpingyouinstallitonyourcomputerandrunyourfirstinteractiveprogramsusingthenewJshell.

Chapter2,TheFirstRealJavaProgram-SortingNames,teachesyouhowtocreateadevelopmentproject.Thistime,wewillcreateprogramfilesandcompilethecode.

Chapter3,OptimizingtheSort-MakingCodeProfessional,developsthecodefurthersothatthecodeisreusableandnotonlyatoy.

Chapter4,Mastermind-CreatingaGame,iswhensomefunstarts.Wedevelopagameapplicationthatisinterestingandnotastrivialasitfirstseems,butwewilldoit.

Chapter5,ExtendingtheGame-RunParallel,RunFaster,showsyouhowtoutilizethemulti-processorcapabilitiesofmodernarchitecture.Thisisaveryimportantchapterthatdetailstechnologies,thatonlyafewdeveloperstrulyunderstand.

Chapter6,MakingOurGameProfessional-DoitasaWebapp,transformstheuserinterfacefromcommand-linetowebbrowser-based,deliveringbetteruserexperience.

Chapter7,BuildingaCommercialWebApplicationUsingREST,takesyouthroughthedevelopmentofanapplicationthathasthecharacteristicsofmanycommercialapplications.WewillusethestandardRESTprotocolwhichhasgainedgroundinenterprisecomputing.

Chapter8,ExtendingOurE-CommerceApplication,helpsyoudeveloptheapplicationfurtherutilizingmodernlanguagefeaturessuchasscriptingandlambdaexpressions.

Chapter9,BuildinganAccountingApplicationUsingReactiveProgramming,teachesyouhowtoapproachsomeproblemsusingreactiveprogramming.

Chapter10,FinalizingJavaKnowledgetoaProfessionalLevel,givesabird's-eyeviewofdevelopertopicsthatplayanimportantroleinthelifeofaJavadeveloper,andwhichwillguideyoufurtherinworkingasaprofessionaldeveloper.

Page 34:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 35:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Whatyouneedforthisbook

Toimmerseintothecontentofthisbookandtosoakupmostoftheskillsandknowledge,weassumethatyoualreadyhavesomeexperiencewithprogramming.Wedonotassumetoomuchbuthopethatyoualreadyknowwhatavariableis,thatcomputershavememory,disk,networkinterfaces,andwhattheygenerallyare.Inadditiontothesebasicskills,therearesometechnicalrequirementstotryoutthecodeandtheexamplesofthebook.Youneedacomputer—somethingthatisavailabletodayandcanrunWindows,Linux,orOSX.Youneedanoperatingsystemand,probably,thatisallyouneedtopayfor.Allothertoolsandservicesthatyouwillneedareavailableasopensourceandfreeofcharge.Someofthemarealsoavailableascommercialproductswithanextendedfeatureset,butforthescopeofthisbook,startingtolearnJava9programming,thosefeaturesarenotneeded.Java,adevelopmentenvironment,buildtools,andallothersoftwarecomponentsweuseareopensource.

Page 36:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 37:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhothisbookisforThisbookisforanyonewhowantstolearntheJavaprogramminglanguage.Youareexpectedtohavesomepriorprogrammingexperiencewithanotherlanguage,suchasJavaScriptorPython,butnoknowledgeofearlierversionsofJavaisassumed.

Page 38:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 39:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheirmeaning.

Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:"Thefollowingfunctionfhasasideeffect,though."

Ablockofcodeissetasfollows:

packagepackt.java9.by.example.ch03;

publicinterfaceSort{

voidsort(SortableCollectioncollection);

}

Ifthereisaline(orlines)ofcodethatneedstobehighlighted,itissetasfollows:

id=123

title=BookJava9byExample

description=anewbooktolearnJava9

weight=300

width=20

height=2

depth=18

Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:"ClickingtheNextbuttonmovesyoutothenextscreen."

Warningsorimportantnotesappearinaboxlikethis.

Tipsandtricksappearlikethis.

Page 40:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 41:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.

Tosendusgeneralfeedback,[email protected],andmentionthebook'stitleinthesubjectofyourmessage.

Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.

Page 42:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 43:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.

Page 44:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 45:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Downloadingtheexamplecode

Youcandownloadtheexamplecodefilesforthisbookfromyouraccountathttps://github.com/PacktPublishing/Java-9-Programming-By-Example.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

Youcandownloadthecodefilesbyfollowingthesesteps:

1. Loginorregistertoourwebsiteusingyoure-mailaddressandpassword.2. HoverthemousepointerontheSUPPORTtabatthetop.3. ClickonCodeDownloads&Errata.4. EnterthenameofthebookintheSearchbox.5. Selectthebookforwhichyou'relookingtodownloadthecodefiles.6. Choosefromthedrop-downmenuwhereyoupurchasedthisbookfrom.7. ClickonCodeDownload.

Oncethefileisdownloaded,pleasemakesurethatyouunziporextractthefolderusingthelatestversionof:

WinRAR/7-ZipforWindowsZipeg/iZip/UnRarXforMac7-Zip/PeaZipforLinux

ThecodebundleforthebookisalsohostedonGitHubathttps://github.com/PacktPublishing/Java-9-Programming-By_Example.Wealsohaveothercodebundlesfromourrichcatalogofbooksandvideosavailableathttps://github.com/PacktPublishing/.Checkthemout!

Page 46:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 47:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Errata

Althoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.

Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.

Page 48:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 49:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.

Pleasecontactusatcopyright@packtpub.comwithalinktothesuspectedpiratedmaterial.

Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.

Page 50:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 51:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

QuestionsIfyouhaveaproblemwithanyaspectofthisbook,[email protected],andwewilldoourbesttoaddresstheproblem.

Page 52:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 53:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GettingStartedwithJava9

YouwanttolearnJavaandyouhaveagoodreasonforit.Javaisamodernandwell-establishedapplicationprogramminglanguage,whichiswidelyusedinmanyindustries,beittelecommunication,finance,orsomethingelse.Javadeveloperpositionsarethemostnumerousand,probably,thebestpaid.This,amongotherthings,makesthelanguagelucrativeforyoungprofessionalstolearn.Ontheotherhand,thisisnotwithoutreason.Javalanguage,thetools,andthewholeinfrastructurearounditiscomplexandcompound.BecomingaJavaprofessionaldoesnothappeninadayorweek;itisaworkofmanyyears.TobeaJavaexpert,youneedtoknownotonlyabouttheprogramminglanguagebutalsoaboutobject-orientedprogrammingprinciples,opensourcelibraries,applicationservers,network,databases,andmanyotherthingsthatyoucanbecomeanexpertin.Nevertheless,learningthelanguageisanabsolutemustthatallotherpracticesshouldbuildon.Throughthisbook,youwillbeabletolearnJavaversion9andabitmore.

Inthischapter,youwillbeintroducedtotheJavaenvironmentandgivenstep-by-stepinstructionsonhowtoinstallit,editsamplecode,compile,andrunJava.Youwillgetacquaintedwiththebasictoolsthathelpdevelopment,betheyareapartofJavaorareprovidedbyothervendors.Wewillcoverthefollowingtopicsinthischapter:

IntroductiontoJavaInstallingWindows,Linux,andMacOSXExecutingjshellUsingotherJavatoolsUsingintegrateddevelopmentenvironment

Page 54:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 55:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GettingstartedwithJavaItislikegoingthroughapathinaforest.Youcanfocusonthegraveloftheroadbutitispointless.Instead,youcanenjoytheview,thetrees,thebirds,andtheenvironmentaroundyou,whichismoreenjoyable.ThisbookissimilarasIwon'tbefocusingonlyonthelanguage.Fromtimetotime,Iwillcovertopicsthatareclosetotheroadandwillgiveyousomeoverviewanddirectionsonwhereyoucangofurtherafteryoufinishthisbook.Iwillnotonlyteachyouthelanguagebutalsotalkabitaboutalgorithms,object-orientedprogrammingprinciples,toolsthatsurroundJavadevelopment,andhowprofessionalswork.Thiswillbemixedwiththecodingexamplesthatwewillfollow.Lastly,thefinalchapterwillbefullydevotedtothetopic,whattolearnnextandhowtogofurthertobecomeaprofessionalJavadeveloper.

Bythetimethisbookgetsintoprint,Javawillhavecompleted22years.http://www.oracle.com/technetwork/java/javase/overview/javahistory-index-198355.html.Thelanguagehaschangedalotduringthisperiodandgotbetter.Therealquestiontoaskisnothowlonghasitbeenhere,butratherhowlongwillitstay?Isitstillworthlearningthislanguage?TherearenumerousnewlanguagesthathavebeendevelopedsinceJavawasborn(http://blog.takipi.com/java-vs-net-vs-python-vs-ruby-vs-node-js-who-reigns-the-job-market/).Theselanguagesaremoremodernandhavefunctionalprogrammingfeatures,which,bytheway,Javahasalsohadsinceversion8.ManysaythatJavaisthepast—thefutureisScala,Swift,Go,Kotlin,JavaScript,andsoon.Youcanaddmanyotherlanguagestothislist,andforeach,youcanfindablogarticlethatcelebratestheburialofJava.Therearetwoanswerstothisconcern-oneisapragmaticbusinessapproach,theotherismoreengineering:

ConsideringthatCOBOLisstillactivelyusedinthefinanceindustryandCOBOLdevelopersareperhapsbetterpaidthanJavadevelopers,itisnottooriskytosaythatasaJavadeveloper,youwillfindpositionsinthenext40years.Personally,Iwouldbetmorethana100years,butconsideringmyage,itwillnotbefairpredictingmorethan20to40yearsahead.Javaisnotonlyalanguage;itisalsoatechnologythatyouwilllearnabitaboutfromthisbook.ThetechnologyincludestheJavaVirtualMachine(JVM),whichisusuallyreferredtoasJVM,andgivestheruntimeenvironmentformanylanguages.KotlinandScala,forexample,cannotrunwithoutJVM.EvenifJavawillbeadumbrated,JVMwillstillbeanumberoneplayerintheenterprisescene.

TounderstandandlearnthebasicoperationofJVMisalmostasimportantasthelanguageitself.Javaisacompiledandinterpretedlanguage.Itisaspecialbeastthatforgesthebestofbothworlds.BeforeJava,therewereinterpretedandcompiledlanguages.

Interpretedlanguagesarereadfromthesourcecodebytheinterpreterandthentheinterpreterexecutesthecode.Ineachoftheselanguages,thereissomepreliminarylexicalandsyntaxanalysisstep;however,afterthat,theinterpreter,which,asaprogramitself,isexecutedbytheprocessorandtheinterpretercontinuously,interpretstheprogramcodetoknowwhattodo.Compiledlanguagesaredifferent.Insuchacase,thesourcecodeiscompiledtobinary(.exefileonWindowsplatforms),whichtheoperatingsystemloadsandtheprocessordirectlyexecutes.Compiledprogramsusuallyrunfaster,butthereisusuallyaslowercompilationphasethatmaymakethedevelopmentslower,andtheexecutionenvironmentisnotso

Page 56:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

flexible.Javacombinedthetwoapproaches.

ToexecuteaJavaprogram,theJavasourcecodehastobecompiledtotheJVMbytecode(.classfile),whichisloadedbyJVMandisinterpretedorcompiled.Hmm...isitinterpretedorcompiled?ThethingthatcamewithJavaistheJustinTime(JIT)compiler.Thismakesthephaseofthecompilationthatiscalculation-intensiveandthecompilationforcompiledlanguagesrelativelyslow.JVMfirststartstointerprettheJavabytecodeand,whiledoingthat,itkeepstrackofexecutionstatistics.Whenitgathersenoughstatisticsaboutcodeexecutions,itcompilestonativecode(forexample,x86codeonanIntel/AMDplatform)fordirectexecutionofthepartsofcodethatareexecutedfrequentlyandkeepsinterpretingthecodefragmentsthatarerarelyused.Afterall,whywasteexpensiveCPUtimetocompilesomecodethatishardlyeverused?(Forexample,codethatreadsconfigurationduringstartupanddoesnotexecuteagainunlesstheapplicationserverisrestarted.)Compilationtothebytecodeisfastandcodegenerationisdoneonlyforthesegmentsthatpayoff.

ItisalsointerestingthatJITusesthestatisticsofthecodeexecutiontooptimizethecode.If,forexample,itseesthatsomeconditionalbranchisexecutedin99%ofthecasesandtheotherbranchisexecutedonlyin1%,thenitwillgeneratenativecodethatrunsfast,thusfavoringthefrequentbranch.Ifthebehaviorofthatpartoftheprogramchangesbytimeandthestatisticshowsthattheratioschanged,theJITautomaticallyrecompilesthebytecodefromtimetotime.Thisisallautomaticandbehindthescenes.

Inadditiontotheautomaticcompilation,thereisalsoanextremelyimportantfeatureofJVM-itmanagesthememoryfortheJavaprogram.TheexecutionenvironmentofmodernlanguagesdothatandJavawasthefirstmainstreamlanguagethathadanautomaticgarbagecollection(GC).BeforeJava,IwasprogramminginCfor20yearsanditwasagreatpaintokeeptrackofallmemoryallocationandnottoforgettoreleasethememorywhentheprogramnolongerneededit.Forgettingmemoryallocationatasinglepointinthecodeandthelongrunningprogramwaseatingupallmemoryslowly.SuchproblemspracticallyceasedtoexistinJava.Thereisapricethatwehavetopayforit—GCneedsprocessorcapacityandsomeextramemory,butthatissomethingwearenotshortofinmostoftheenterpriseapplications.Somespecialprograms,likereal-timeembeddedsystemsthatcontrolthebrakesofaheavy-dutylorrymaynothavethatluxury.ThosearestillprogrammedinassemblyorC.Fortherestofus,wehaveJava,andthoughitmayseemstrangeformanyprofessionals,evenalmost-real-timeprograms,suchashigh-frequencytradingapplications,arewritteninJava.

Theseapplicationsconnectthroughthenetworktothestockexchangeandtheysellandbuystocksrespondingtomarketchangeinmilliseconds.Javaiscapableofdoingthat.TheruntimeenvironmentofJavathatyouwillneedtoexecuteacompiledJavacode,whichalsoincludestheJVMitself,containscodethatletsJavaprogramsaccessthenetwork,filesondisks,andotherresources.Todothis,theruntimecontainshigh-levelclassesthatthecodecaninstantiate,execute,andwhichdothelow-leveljobs.Youwillalsodothis.ItmeansthattheactualJavacodedoesnotneedtohandleIPpackets,TCPconnections,orevenHTTPhandlingwhenitwantstouseorprovideaRESTserviceinsomemicroservicesarchitecture.Itisalreadyimplementedintheruntimelibraries,andalltheapplicationprogrammerhastodoistoincludetheclassesinthecodeandusetheAPIstheyprovideonanabstractionlevelthatmatchestheprogram.WhenyouprograminJava,youcanfocusontheactualproblemyouwanttosolve,whichisthebusinesscodeandnotthelow-levelsystemcode.Ifitisnotinthestandardlibrary,youwillfinditinsomeproductinsomeexternallibrary,anditisalsoveryprobablethatyouwillfindanopensourcesolutionfortheproblem.

Page 57:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThisisalsoastrongpointofJava.Thereisavastnumberofopensourcelibrariesavailableforallthedifferentpurposes.Ifyoucannotfindalibraryfittingyourproblemifyoustarttocodesomelow-levelcode,thenprobablyyouaredoingsomethingwrong.Therearetopicsinthisbookthatareimportant,suchasclassloadersorreflection,notbecauseyouhavetousethemeverydaybutratherbecausetheyareusedbyframeworks,andknowingthemhelpsunderstandhowtheseframeworkswork.Ifyoucannotsolveyourproblemwithoutusingreflectionorwritingyourownclassloaderorprogrammultithreaddirectly,thenyouprobablychosethewrongframework.Thereisalmostcertainlyagoodone:Apacheproject,Google,andmanyotherimportantplayersinthesoftwareindustrypublishtheirJavalibrariesasopensource.

Thisisalsotrueformultithreadprogramming.Javaisamultithreadprogrammingenvironmentfromtheverybeginning.TheJVMandtheruntimesupportsprogramsthatexecutethecode.Theexecutionrunsparallelonmultiplethreads.Thereareruntimelanguageconstructsthatsupportparallelexecutingprogramsstartingattheverylowleveltohighabstraction.Multithreadcodeutilizesthemulticoreprocessors,whicharemoreeffective.Theseprocessorsaremoreandmorecommon.20yearsago,onlyhigh-endservershadmultipleprocessorsandonlyDigitalAlphaprocessorshad64-bitarchitectureandCPUclockabove100MHz.10yearsago,multiprocessorstructurewascommonontheserverside,andabout5yearsago,multicoreprocessorswereonsomedesktopsandonnotebooks.Today,evenmobilephoneshavethem.WhenJavawasstartedin1995,thegeniuseswhocreatedithadseenthisfuture.

TheyenvisionedJavatobeawriteonce,runanywherelanguage.Atthattime,thefirsttargetforthelanguagewasappletrunninginthebrowser.Today,manythink(andIalsosharethisopinion)thatappletswereawrongtarget,oratleastthingswerenotdoneintherightway.Asfornow,youwillmeetappletsontheInternetlessfrequentlythanFlashapplicationsordinosaurs.

However,atthesametime,theJavainterpreterwasalsoexecutingserverandclientapplicationswithoutanybrowser;furthermore,asthelanguageandtheexecutingenvironmentdeveloped,theseapplicationareasbecamemoreandmorerelevant.Today,themainuseofJavaisenterprisecomputingandmobileapplicationsmainlyfortheAndroidplatform;forthefuture,theuseoftheenvironmentisgrowinginembeddedsystemsastheInternetofthings(IoT)comesmoreandmoreintopicture.

Page 58:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 59:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallingJavaTodevelop,compile,andexecuteJavaprograms,youwillneedtheJavaexecutionenvironment.Astheoperatingsystemsthatweusuallyuseforsoftwaredevelopmentdonotcontainthelanguagepreinstalled,youwillhavetodownloadit.Although,thereismultipleimplementationofthelanguage,IrecommendthatyoudownloadtheofficialversionofthesoftwarefromOracle.Theofficialsiteforjavaishttp://java.comandthisisthesitefromwherethelatestreleaseofthelanguagecanbedownloaded.Atthetimeofwritingthisbook,the9thversionofJavaisnotyetreleased.Anearlypre-releaseversionisaccessibleviahttp://jdk9.java.net/download.Laterthereleaseversionswillalsobeavailablefromhere.

Whatyoucandownloadfromhereisasocalledearlyaccessversionofthecodethatisavailableonlytoexperimentwithit,andnoprofessionalsshoulduseitforrealprofessionalpurposes

Onthepage,youhavetoclickontheradiobuttontoacceptthelicense.Afterthat,youcanclickonthe

Page 60:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

linkthatdirectlystartsthedownloadoftheinstallationkit.Thelicenseisaspecialearlyaccesslicenseversionthatyou,asaprofessional,shouldcarefullyread,understand,andacceptonlyifyouareagreeablewiththeterms.

ThereisaseparateinstallationkitforWindows32and64bitsystems,MacOSX,Linux32and64bitversions,LinuxforARMprocessor,SolarisforSPARCprocessorsystems,andSolarisx86versions.AsitisnotlikelythatyouwilluseSolaris,IwilldetailtheinstallationprocedureonlyforWindows,Linux,andMacOSX.Inlaterchapters,thesampleswillalwaysbeMacOSX,butsinceJavaisawriteonce,runanywherelanguage,thereisnodifferenceaftertheinstallation.Thedirectoryseparatormaybeslanteddifferently,theclasspathseparatorcharacterisasemicolononWindowsinsteadofacolon,andthelookandfeeloftheTerminalorcommandapplicationisalsodifferent.However,whereitisimportant,Iwilltrynottoforgettomentionit.

Toconfuseyou,theJavadownloadforeachoftheseoperatingsystemversionslistsalinkfortheJREandonefortheJDK.JREstandsforJavaRuntimeEnvironmentanditcontainsallthetoolsandexecutablesthatareneededtorunJavaprograms.JDKistheJavaDevelopmentKitthatcontainsallthetoolsandexecutablesthatareneededtodevelopJavaprogramsincludingtheexecutionoftheJavaprogram.Inotherwords,JDKcontainsitsownJRE.Fornow,allyouneedtodoisdownloadtheJDK.

Thereisoneimportantpointoftheinstallationthatisthesameoneachofthethreeoperatingsystemsthatyouhavetobepreparedforbeforetheinstallation:toinstallJava,youshouldhaveadministrativeprivileges.

Page 61:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 62:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallationonWindowsTheinstallationprocessonWindowsstartsbydoubleclickingonthedownloadedfile.Itwillstarttheinstallerthatwillpresentyouawelcomescreen.

PressingtheNextbuttonwegetawindowwhereyoucanselectthepartsyouwanttoinstall.Let'sleaveherethedefaultselection,whichmeansthatweinstallallthedownloadedpartsofJavaandpressthebuttonNext.Thefollowingwindowiswherewecanselectthedestinationfolderfortheinstallation.

Asfornowwedonotchangethedirectoryselectedbytheinstaller.PressNext.Later,whenyoubecomeaprofessionalJavadeveloper,youmaydecidetoinstallJavatoadifferentlocationbutthenyouwillalreadyhavetoknowwhatyouaredoing.

YoumayneedtoclicktheNextbuttonafewtimesandthentheinstallerfinishes.Providetheadministrativepasswordwhenaskedandvoila!Javaisinstalled.ThisisreallytheveryusualWindowsinstallationprocess.

ThelaststepistosettheenvironmentvariableJAVA_HOME.TodothatinWindowswehavetoopenthe

Page 63:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

controlcenterandselecttheEditenvironmentvariablesforyouraccountmenu.

Thiswillopenanewwindowthatweshouldusetocreateanewenvironmentvariableforthecurrentuser.

ThenameofthenewvariablehastobeJAVA_HOMEandthevalueshouldpointtotheinstallationdirectoryoftheJDK.

ThisvalueonmostofthesystemsisC:ProgramFilesJavajdk-9.ThisisusedbymanyJavaprogramsandtoolstolocatetheJavaruntime.

Page 64:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 65:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallationonMACOSXInthissection,wewilltakelookathowtoinstallJavastep-by-steponanOSXplatform.Iwilldescribetheinstallationprocessforthereleasedversionavailableatthetimeofwritingthisbook.Asfornow,theJava9earlyaccessversionisabittrickytoinstall.ItisprobablethatversionJava9willhavesimilarorthesameinstallstepsasJava8update92has.

TheOSXversionofJavacomesintheformofa.dmgfile.ThisisapackagingformatofOSX.Toopenit,simplydoubleclickonthefileintheDownloadfolderwherethebrowsersavesitandtheoperatingsystemwillmountthefileasaread-onlydiskimage.

Thereisonlyonefileonthisdisk:theinstallationimage.DoubleclickonthefilenameoriconintheFinderapplicationandtheinstallationprocesswillstart.

Thefirstscreenopeningisawelcomescreen.ClickContinueandyouwillseetheSummarypagethatdisplayswhatwillbeinstalled.

Page 66:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ItisnotasurprisethatyouwillseeastandardJavainstallation.Thistime,thebuttoniscalledInstall.Clickonitandyouwillseethefollowing:

Thisisthetimewhenyouhavetoprovidetheloginparametersfortheadministrativeuser—ausernameandpassword.Whenprovided,installationstartsand,inafewseconds,youwillseeaSummarypage.

ClickCloseandyouareready.YouhaveJavainstalledonyourMac.Optionally,youcandismounttheinstallationdiskand,sometimelater,youcanalsodeletethe.dmgfile.Youwillnotneedthat,andincaseyoudo,youcandownloaditanytimefromOracle.

Thelastthingistocheckwhethertheinstallationwasokay.Proofofthepuddingiseatingit.StartaTerminalwindowandtypejava-versionatthepromptandJavawilltellyoutheversioninstalled.

OnthenextscreenshotyoucanseetheoutputonmyworkstationandalsotheMacOScommandsthatarehandytoswitchbetweenthedifferentversionsofJava:

Page 67:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Onthescreenshot,youcanseethatIhaveinstalledtheJavaJDK1.8u92versionand,atthesametime,IalsohaveaJava9earlyreleaseinstallation,whichIwillusetotestthenewfeaturesofJavaforthisbook.

Page 68:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 69:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallationonLinuxThereareseveralwaystoinstallJavaonLinux,dependingonitsflavor.Here,Iwilldescribeaninstallationmethodthatworksmoreorlessthesamewayonallflavors.TheoneIusedisDebian.

Firststepisthesameasinanyotheroperatingsystem:downloadtheinstallationkit.InthecaseofLinux,youshouldselectapackagethathasatar.gzending.Thisisacompressedarchiveformat.Youshouldalsocarefullyselectthepackagethatmatchestheprocessorinyourmachineandthe32/64bitversionoftheoperatingsystem.Afterthepackageisdownloaded,youhavetoswitchtorootmode,issuingthesucommand.Thisthefirstcommandyoucanseeonthescreenshotthatshowstheinstallationcommands.

Thetarcommanduncompressedthearchiveintoasubfolder.InDebian,thissubfolderhastobemovedto/opt/jdkandthemvcommandisusedforthispurpose.Thetwoupdate-alternativescommandisDebian-specific.ThesetelltheoperatingsystemtousethisnewlyinstalledJavaincasethereisalreadyanolderJavainstalled.TheDebianIwasusingtotestanddemonstratetheinstallationprocessonavirtualmachinecamewitha7yearoldversionofJava.

Thefinalstepoftheinstallationisthesameasanyotheroperatingsystem:checkingthattheinstallationwassuccessfulinissuingthejava-versioncommand.InthecaseofLinux,thisisevenmoreimportantbecausetheinstallationprocessdoesnotcheckthatthedownloadedversionmatchestheoperatingsystemandtheprocessorarchitecture.

Page 70:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 71:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SettingJAVA_HOMETheJAVA_HOMEenvironmentvariableplaysaspecialroleforJava.EventhoughtheJVMexecutable,java.exeorjava,isonthePATH(thusyoucanexecuteitbytypingthenamejavawithoutspecifyingdirectoryontheCommandPrompt)(Terminal),itisrecommendedthatyouusethecorrectJavainstallationtosetthisenvironmentvariable.ThevalueofthevariableshouldpointtotheinstalledJDK.TherearemanyJava-relatedprograms,forexample,TomcatorMaven,thatusethisvariabletolocatetheinstalledandcurrentlyusedJavaversion.InMacOSX,settingthisvariableisunavoidable.

InOSX,theprogramthatstartstoexecutewhenyoutypejavaisawrapperthatfirstlooksatJAVA_HOMEtodecidewhichJavaversiontostart.Ifthisvariableisnotset,thenOSXwilldecideonitsown,selectingfromtheavailableinstalledJDKversions.Toseetheavailableversions,youcanissuethefollowingcommand:~$/usr/libexec/java_home-VMatchingJavaVirtualMachines(10):9,x86_64:"JavaSE9-ea"/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home1.8.0_92,x86_64:"JavaSE8"/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home1.7.0_60,x86_64:"JavaSE7"/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home

YouwillthengetthelistofinstalledJDKs.Notethatthecommandislowercase,buttheoptioniscapital.Ifyoudonotprovideanyoptionsandargumenttotheprogram,itwillsimplyreturntheJDKitthinksisthenewestandmostappropriateforthepurpose.AsIcopiedtheoutputofthecommandfrommyTerminalwindow,youcanseethatIhavequiteafewversionsofJavainstalledonmymachine.

ThelastlineoftheprogramresponseisthehomedirectoryofJDK,whichisthedefault.YoucanusethistosetyourJAVA_HOMEvariableusingsomebashprogramming:exportJAVA_HOME=$(/usr/libexec/java_home)

Youcanplacethisfileinyour.bashrcfile,whichisexecutedeachtimeyoustartTerminalapplicationandthusJAVA_HOMEwillalwaysbeset.Ifyouwanttouseadifferentversion,youcanuse-v,withthelowercaseoptionthistime,tothesameutility,asfollows:exportJAVA_HOME=$(/usr/libexec/java_home-v1.8)

TheargumentistheversionofJavayouwanttouse.Notethatthisversioningbecomes:

exportJAVA_HOME=$(/usr/libexec/java_home-v9)

IfyouwanttouseJavaJDKEarlyAccessversionandnot1.9,thereisnoexplanationforthesame—factoflife.

NotethatthereisanotherenvironmentvariablethatisimportantforJava-CLASSPATH.Wewilltalkaboutitlater.

Page 72:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 73:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ExecutingjshellNowthatwehavespentalotoftimeinstallingJava,itistimetogetthefingersburntabit.AsweareusingJava9,thereisanewtoolthathelpsdeveloperstoplayaroundwiththelanguage.ThisisaRead-Eval-Print-Loop(REPL)toolthatmanylanguagetoolsetscontainandtherewerealsoimplementationsfromJava,butversion9isthefirstthatcontainsthisfeatureofftheshelf.

REPLisatoolthathasinteractivepromptandlanguagecommandsthatcanbedirectlyenteredwithouteditingsomestandalonefile.Theenteredcommandsareexecuteddirectlyandthentheloopstartsagain,waitingfortheusertotypeinthenextcommand.Thisisaveryeffectivetooltotryoutsomelanguageconstructswithoutthedelayofediting,compiling,andloading.ThestepsareautomaticallyandtransparentlydonebytheREPLtool.

TheREPLtoolinJava9iscalledjshell.Tostartit,justtypeitsname.IfitisnotonthePATH,thentypethefullpathtojshellthatcomesinstalledwithJava9,asshowninthefollowingexample:

$jshell

|WelcometoJShell--Version9-ea

|Foranintroductiontype:/helpintro

jshell>

Thejshellstartsupinaninteractivewayandthepromptitdisplaysisjshell>tohelpyourecognizethatjshellisrunningandwhatyoutypeisreadbytheprogramandnottheoperatingsystemshell.Asthisisthefirsttimeyouwillstartjshell,ittellsyoutotype/helpintro.Let'sdoit.Itwillprintoutashorttextaboutwhatjshellis,asshowninthefollowingcode:

jshell>/helpintro

|

|intro

|

|ThejshelltoolallowsyoutoexecuteJavacode,gettingimmediateresults.

|YoucanenteraJavadefinition(variable,method,class,etc),like:intx=8

|oraJavaexpression,like:x+x

|oraJavastatementorimport.

|TheselittlechunksofJavacodearecalled'snippets'.

|

|Therearealsojshellcommandsthatallowyoutounderstandand

|controlwhatyouaredoing,like:/list

|

|Foralistofcommands:/help

Okay,sowecantypeJavasnippetsand/list,butthatisonlyoneexampleoftheavailablecommands.Wecanhopeformoreinformationbytyping/help,asshowninthefollowingcode:

jshell>/help

|TypeaJavalanguageexpression,statement,ordeclaration.

|Ortypeoneofthefollowingcommands:

|/list[<nameorid>|-all|-start]--listthesourceyouhavetyped

|/edit<nameorid>--editasourceentryreferencedbynameorid

|/drop<nameorid>--deleteasourceentryreferencedbynameorid

|/save[-all|-history|-start]<file>--Savesnippetsourcetoafile.

...

Whatyougetisalonglistofcommands.Mostofitisnotpresentedheretosavepaperandyourattention.Wewillusemanyofthesecommandsonourjourneythroughthenextfewpages.Let'sstartwithasmallJavasnippetthatistheagelessHelloWorldexample:

Page 74:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

jshell>System.out.println("HelloWorld!")

HelloWorld!

ThisistheshortesteverHelloWorldprograminJava.TillJava9,ifyouwantedtodonothingmorethanprintoutHelloWorld!,youhadtocreateaprogramfile.Ithadtocontainthesourcecodeofaclassincludingthepublicstaticmainmethod,whichcontainedtheonelinewehadtotypeinwithJava9jshell.Itwascumbersomejustforasimpleprintoutofsamplecode.Nowitismucheasierandjshellisalsolenient,forgivingusthemissingsemicolonattheendoftheline.

Thenextthingweshouldtryisdeclaringavariable,asfollows:

jshell>inta=13

a==>13

jshell>

Wedeclaredavariable,nameda,andassignedthevaluetoit-13.Thetypeofthevariableisint,whichisanabbreviationforintegertypesinJava.Nowwehavethisvariablealreadyinoursnippet,sowecanprintitoutifwewanttoasshown:

jshell>System.out.println(a)

13

Itistimetowritesomethingmorecomplexintojshellthanaoneliner.

jshell>voidmain(String[]args){

...>System.out.println("HelloWorld")

...>}

|Error:

|';'expected

|System.out.println("HelloWorld")

|

Thejshellrecognizesthatthisisnotaone-linerandthatitcannotprocesswhatwetypedsofar,whenwepressEnterattheendofthefirstline,anditsignalsthatitexpectsmorecharactersfromus,soitdisplays...>asacontinuationprompt.Wetypeinthecommandsthatmakeupthewholehelloworldmainmethod,butthistimejshelldoesnotletusmissthesemicolon.Thatisallowedonlyinthecaseofone-linesnippets.Asjshellisinteractive,itiseasytocorrectthemistake;presstheuparrowkeyafewtimestogetbackthepreviouslinesand,thistime,addthesemicolonattheendofthesecondline:

jshell>voidmain(String[]args){

...>System.out.println("HelloWorld");

...>}

|createdmethodmain(String[])

Thismethodwascreatedforusasasnippetandnowwecancallit:

jshell>main(null)

HelloWorld

Anditworks.Youcanlistallthesnippetsthatwerecreated,asfollows:

jshell>/list

1:System.out.println("HelloWorld!")

2:inta=13;

3:System.out.println(a)

4:voidmain(String[]args){

System.out.println("HelloWorld");

}

Page 75:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

And,aswewanttogoonwritingafullJavaversionofhelloworld,wecansaveourworkfromjshelltoafile,asfollows:

jshell>/saveHelloWorld.java

Finally,weexitedfromjshellbytyping/exit.Asyougetbacktothesystemprompt,typecatHelloWorld.java(ortypeHelloWorld.javaonWindows)toseethecontentofthefile.Itisasfollows:

$catHelloWorld.java

System.out.println("HelloWorld!")

inta=13;

System.out.println(a)

voidmain(String[]args){

System.out.println("HelloWorld");

}

Thefilecontainsallthesnippetsthatwetypedinoneaftertheother.Ifyouthinkthatyouhavemesseduptheshellwithlotsofvariablesandcodesnippetsthatyoudonotneedanymore,youcanissuethe/resetcommand:

jshell>/reset

|Resettingstate.

Afterthiscommand,thejshellisascleanaswhenitwasstartedearlier

jshell>/list

jshell>

Listingjustdoesnotproduceanythingaswedeleteditall.Fortunately,wesavedthestateofjshelltoafileandwecanalsoloadthecontentofthefileissuingthe/opencommand:

jshell>/openHelloWorld.java

HelloWorld!

13

ItloadsthelinefromthefileandexecutesitjustasthecharactersweretypedintotheCommandPrompt.

Youmayrecallthatthe/listcommandprintedanumberinfrontofeachsnippet.Wecanuseittoeditthesnippetsindividually.Todoso,issuethe/editcommandfollowedbythenumberofthesnippet:

jshell>/edit1

YoumayrecallthatthefirstcommandweenteredwastheSystem.out.printlnsystemcallthatprintsouttheargumenttotheconsole.WhenyoupressEnterafterthe/edit1command,youdonotgetthepromptback.Instead,jshellopensaseparategraphicaleditorthatcontainsthesnippettoeditasshowninthefollowingimage:

Page 76:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Editthetextintheboxsothatitwilllooklikethis:

printf("HelloWorld!")

ClickonAcceptandthenExit.WhenyouclickonAccept,theTerminalwillexecutethesnippetanddisplaythefollowingresult:

HelloWorld!

Themethodthatweused,printf,standsforformattedprinting.Thismaybewellknownfrommanyotherlanguages.ItwasfirstintroducedbytheClanguageandthoughcryptic,thenamesurvived.ThisisalsopartofthestandardJavaclass,PrintStream,justlikeprintln.Incaseofprintln,wehadtowriteSystem.outinfrontofthemethodname.Incaseofprintf,wedidnot.Why?

Thereasonisthatjshelldefinesafewsnippetsthatareautomaticallyloadedwhenjshellstartsorresets.Youcanseetheseifyouissuethe/listcommandwiththe-startoption,asfollows:

jshell>/list-start

s1:importjava.util.*;

s2:importjava.io.*;

s3:importjava.math.*;

s4:importjava.net.*;

s5:importjava.util.concurrent.*;

s6:importjava.util.prefs.*;

s7:importjava.util.regex.*;

s8:voidprintf(Stringformat,Object...args){System.out.printf(format,args);}

Thesepredefinedsnippetshelptheuseofjshell.Mostoftheuserswillimporttheseclasses,andtoeasetheprinttoscreen,itdefinesamethodsnippetthathappenstohavethename,printf,whichisalsothenameofamethodinthePrintStreamclass.

Ifyouwanttolistallthesnippetsyouenteredaswellasthepredefinedsnippetsandalsothosethatcontainedsomeerrorandthuswerenotexecuted,youcanusethe-alloptiontothe/listcommand,asfollows:

jshell>/list-all

...

s7:importjava.util.regex.*;

...

1:System.out.println("HelloWorld!")

...

e1:System.out.println("HelloWorld!")

inta=14;

5:System.out.println("HelloWorld!");

...

Someofthelinesweredeletedfromtheactualoutputforbrevity.Thelinesthatarepreloadedarenumberedwiththesprefix.Thesnippetsthatcontainanerrorhaveanumberprefixedwithe.

Ifyouwanttoexecutesomeofthesnippetsagain,youonlyhavetotype/nwherenisthenumberofthesnippet,asfollows:

jshell>/1

System.out.println("HelloWorld!")

HelloWorld!

Page 77:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Youcannotre-executethepreloadedsnippetsorsnippetsthatcontainederrors.Thereisnoneedforanyofthoseanyway.Preloadedsnippetsdeclaresomeimportsanddefineasnippetmethod;erroneoussnippetsdonotexecutebecausetheyare,well...erroneous.

Youneednotrelyonthenumberofjshellwhenyouwanttore-executeasnippet.Whenyoualreadyhavealotofsnippetsinyourjshellsession,listingthemallwouldbetoocumbersome;thereisashortcuttore-executethelastn-thsnippet.Youhavetowrite/-n.Here,nisthenumberofthesnippetcountingfromthelastone.So,ifyouwanttoexecutetheverylastsnippet,thenyouhavetowrite/-1.Ifyouwanttoexecutetheonebeforethelastone,youhavetowrite/-2.Notethatifyoualreadytyped/-1,thenthelastoneisthere-executionofthelastsnippetandsnippetnumber-2willbecomenumber-3.

Listingallthesnippetscanalsobeavoidedinotherways.Whenyouareinterestedonlyincertaintypesofsnippets,youcanhavespecialcommands.

Ifwewanttoseeonlythevariablesthatwedefinedinthesnippets,thenwecanissuethe/varscommand,asfollows:

jshell>/vars

|inta=13

Ifwewanttoseeonlytheclasses,thecommand/typeswilldothat:

jshell>classs{}

|createdclasss

jshell>/types

|classs

Here,wejustcreatedanemptyclassandthenwelistedit.

Tolistthemethodsthatweredefinedinthesnippets,the/methodscommandcanbeissued:

jshell>/methods

|printf(String,Object...)void

|main(String[])void

Youcanseeintheoutputthatthereareonlytwomethods,whichareasfollows:

printf:Thisisdefinedinapreloadedsnippetmain:This,wedefined

Ifyouwanttoseeeverythingyoutyped,youhavetoissuethe/historycommandforallthesnippetsandcommandsthatyoutyped.(Iwillnotcopytheoutputhere;Idonotwanttoshamemyself.Youshouldtryyourselfandseeyourownhistory.)

Recallthatwecandeleteallthesnippetsissuingthe/resetcommand.Youcanalsodeletesnippetsindividually.Todoso,youshouldissuethe/dropncommand,wherenisthesnippednumber:

jshell>/drop1

|Thiscommanddoesnotacceptthesnippet'1':System.out.println("HelloWorld!")

|See/types,/methods,/vars,or/list

Oops!Somethingwentwrong.Thereisnothingdefinedwhensnippetnumber1wasexecutedandthe/drop

Page 78:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

commandactuallydropsthedefinedvariable,type,ormethod.Thereisnothingtobedroppedinthefirstsnippet.But,ifwereissuethe/listcommand,wewillgetthefollowingresults:

jshell>/list

1:System.out.println("HelloWorld!")

2:inta=13;

3:System.out.println(a)

4:voidmain(String[]args){

System.out.println("HelloWorld");

}

Wecanseethatwecandropthesecondorthefourthsnippet,too:

jshell>/drop2

|droppedvariablea

jshell>/drop4

|droppedmethodmain(String[])

Thejshellerrormessagesaystoseetheoutputofthe/types,/methods,/vars,or/listcommands.Theproblemwiththisisthat/types,/methods,and/varsdonotdisplaythenumberofthesnippet.ThisismostprobablyasmallbuginthejshellprereleaseversionandmaybefixedbythetimetheJDKisreleased.

Whenwewereeditingthesnippets,jshellopenedaseparategraphicaleditor.Itmayhappenthatyouarerunningjshellusingsshonaremoteserverandwhereitisnotpossibletoopenaseparatewindow.Youcansettheeditorusingthe/setcommand.Thiscommandcansetquiteafewconfigurationoptionsofthejshell.Tosettheeditortousetheubiquitousvi,issuethefollowingcommand:

jshell>/seteditor"vi"

|Editorsetto:vi

Afterthis,jshellwillopenthesnipped-inviinthesameTerminalwindowwhereyouissuethe/editcommand.

Itisnotonlytheeditorthatyoucanset.Youcansetthestartupfile,andthewayjshellprintsthefeedbacktotheconsoleafteracommandwasexecuted.

Ifyousetthestartupfile,thenthecommandslistedinthestartupfilewillbeexecutedinsteadofthebuilt-incommandsofjshellafterthe/resetcommand.Thisalsomeansthatyouwillnotbeabletousetheclassesdirectlythatareimportedbydefaultandyouwillnothavetheprintfmethodsnippet,unlessyourownstartupfilecontainstheimportsandthedefinitionofthesnippet.

Createthesample.startupfilewiththefollowingcontent:

voidprintln(Stringmessage){System.out.println(message);}

Startingupanewjshellandexecutingitisdoneasfollows:

jshell>/setstartsample.startup

jshell>/reset

|Resettingstate.

jshell>println("wuff")

wuff

Page 79:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

jshell>printf("Thiswon'twork...")

|Error:

|cannotfindsymbol

|symbol:methodprintf(java.lang.String)

|printf("Thiswon'twork...")

|^----^

Theprintlnmethodisdefinedbuttheprintfmethod,whichwasdefinedinthedefaultstartup,isnot.

Thefeedbackdefinesthepromptjshellprintsandthenwaitsfortheinput,thepromptforthecontinuationlines,andthemessagedetailsaftereachcommand.Therearepredefinedmodes,whichareasfollows:

NormalSilentConciseVerbose

Normalisselectedbydefault.Ifyouissue/setfeedbacksilent,thenpromptbecomes->andjshellwillnotprintdetailsaboutthecommands.The/setfeedbackconcisecodeprintsabitmoreinformationand/setfeedbackverboseprintsverboseinformationaboutthecommandsexecuted:

jshell>/setfeedbackverbose

|Feedbackmode:verbose

jshell>intz=13

z==>13

|modifiedvariablez:int

|updateoverwrotevariablez:int

Youcanalsodefineyourownmodes,givinganametothenewmodeusingthe/setmodexyzcommandwherexyzisthenameofthenewmode.Afterthis,youcansetprompt,truncation,andformatforthemode.Whentheformatisdefined,youcanuseitthesamewayasthebuilt-inmodes.

Last,butnotleast,themostimportantcommandofjshellis/exit.Thiswilljustterminatetheprogramandyouwillreturntotheoperatingsystemshellprompt.

Now,let'sedittheHelloWorld.javafiletocreateourfirstJavaprogram.Todoso,youcanusevi,notepad,Emacs,orwhateverisavailableonyourmachineandfitsyou.Lateron,wewillusesomeintegrateddevelopmentenvironment(IDE),NetBeans,Eclipse,orIntelliJ;however,fornow,asimpletexteditorisenough.

Editthefilesothatthecontentwillbeasfollows:

publicclassHelloWorld{

publicstaticvoidmain(String[]args){

System.out.println("HelloWorld");

}

}

Tocompilethesourcecodetobytecode,whichisexecutablebyJVM,wehavetousetheJavacompilernamedjavac:

javacHelloWorld.java

Page 80:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Thisgeneratesthejava.classfileinthecurrentdirectory.Thisisacompiledcodethatcanbeexecutedasfollows:

$javaHelloWorld

HelloWorld

Withthisone,youhavecreatedandexecutedyourfirstfullJavaprogram.Youmaystillwonderwhatweweredoing.Howandwhy,Iwillexplainit;butfirst,Iwantedyoutohaveafeelingthatitworks.

Thefileweeditedcontainedonlythesnippetandwedeletedmostofthelines,exceptthedeclarationofthemainmethodandweinsertedthedeclarationoftheclassaroundit.

InJava,youcannothavestandalonemethodsorfunctions,likeinmanyotherlanguages.Everymethodbelongstosomeclassandeveryclassshouldbedeclaredinaseparatefile(well,almost,butfornow,let'sskiptheexceptions).Thenameofthefilehastobethesameasthenameoftheclass.Thecompilerrequiresthisforpublicclasses.Evenfornon-publicclassesweusuallyfollowthisconvention.IfyourenamedthefilefromHelloWorld.javatoHello.java,thecompilerwilldisplayanerrorwhenyoutrytocompilethefilewiththenewname.

$mvHelloWorld.javaHello.java

~/Dropbox/java_9-by_Example$javacHello.java

Hello.java:2:error:classHelloWorldispublic,shouldbedeclaredinafilenamedHelloWorld.java

publicclassHelloWorld{

^

1error

So,let'smoveitbacktotheoriginalname:mvHello.javaHelloWorld.java.

Thedeclarationoftheclassstartswiththekeywordclass,thenthenameoftheclass,anopeningcurlybrace,andlastsuntilthematchingclosingbrace.Everythinginbetweenbelongstotheclass.

Fornow,let'sskipwhyIwrotepublicinfrontoftheclassandfocusonthemainmethodinit.Themethoddoesnotreturnanyvalue,therefore;thereturnvalueofitisvoid.Theargument,namedargs,isastringarray.WhenJVMstartsthemainmethod,itpassesthecommand-lineargumentstotheprograminthisarray.However,thistimewedonotuseit.ThemainmethodcontainsthelinethatprintsoutHelloWorld.Now,let'sexaminethislineabitmore.

Inotherlanguages,printingsomethingtotheconsolerequiresonlyaprintstatementoraverysimilarcommand.IrememberthatsomeBASICinterpretersevenallowedustotype?insteadofprintbecauseprintingtothescreenwassocommon.Thishaschangedalotduringthelast40years.Weusegraphicalscreens,Internet,andmanyotherinputandoutputchannels.Thesedays,itisnotverycommontowritetotheconsole.

Usually,inprofessionallarge-scaleenterpriseapplications,thereisnotevenasinglelinethatdoesthat.Instead,wewilldirectthetexttologfiles,sendmessagestomessagequeues,andsendrequestsandreplywithresponsesoverTCP/IPprotocol.Asthisissoinfrequentlyused,thereisnoreasontocreateashortcutforthepurposeinthelanguage.Afterthefirstfewprograms,whenyougetacquaintedwiththedebuggerandloggingpossibilities,youwillnotprintanythingdirectlytotheconsoleyourself.

Still,Javahasfeaturesthatletyousendtextdirectlytothestandardoutputofaprocessthegoodoldway,

Page 81:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

asitwasinventedoriginallyforUNIX.ThisisimplementedinaJavawaywhereeverythinghastobeanobjectorclass.Togetaccesstothesystemoutput,thereisaclassnamedSystemandit,amongotherthings,hasthefollowingthreevariables:

in:Thisisthestandardinputstreamout:Thisisthestandardoutputstreamerr:Thisisthestandarderrorstream

Torefertotheoutputstreamvariable,becauseitisnotinourclassbutinSystem,wewillhavetospecifytheclassnamesowewillrefertoitasSystem.outinourprogram.ThetypeofthisvariableisPrintStream,whichisalsoaclass.ClassandtypearesynonymsinJava.EveryobjectthatisoftypePrintStreamhasamethodnamedprintlnthatacceptsaString.Iftheactualprintstreamisthestandardoutput,andweareexecutingourJavacodefromthecommandline,thenthestringissenttotheconsole.

ThemethodisnamedmainandthisisaspecialnameinJavaprograms.WhenwestartaJavaprogramfromthecommandline,JVMinvokesthemethodnamedmainfromtheclassthatwespecifyonthecommandline.Itcandothatbecausewedeclaredthismethodpublicsothatanyonecanseeandinvokeit.Ifitwasprivate,itwouldbeseenandcallableonlyfromwithinthesameclass,orclasses,thataredefinedinthesamesourcefile.

Themethodisalsodeclaredasstatic,whichmeansthatitcanbeinvokedwithoutanactualinstanceoftheclassthatcontainsthemethods.Usingstaticmethodsisusuallyseenasnotagoodpracticethesedays,unlesstheyareimplementingfunctionsthatcannotreallyeverberelatedtoaninstance,orhavedifferentimplementationssuchasthefunctionsinthejava.lang.Mathclass;but,somewhere,thecodeexecutionhastostartandtheJavaruntimewillnotusuallycreateinstancesofclassesforusautomatically.

Tostartthecode,thecommandlineshouldbeasfollows:

java-cp.HelloWorld

The-cpoptionstandsforclasspath.Theclasspathisafairlycomplexideaforjavabut,fornow,let'smakeitsimpleandsaythatitisalistofdirectoriesandJARfilesthatcontainourclasses.Thelistseparatorfortheclasspathis:(colon)onUNIX-likesystemsand;(semicolon)onWindows.Inourcase,theclasspathistheactualdirectory,asthatistheplacewheretheJavacompilercreatedHelloWorld.class.Ifwedonotspecifyclasspathonthecommandline,Javawillusethecurrentdirectoryasadefault.Thatisthereasonourprogramwasworkingwithoutthe-cpoptioninthefirstplace.

Bothjavaandjavachandlemanyoptions.Togetalistoftheoptionstypejavac-helporjava-help.WeusetheIDEtoeditthecodeand,manytimes,tocompile,build,andrunitduringdevelopment.Theenvironmentinthiscasesetsthereasonableparameters.Forproductionweusebuildtoolsthatalsosupporttheconfigurationoftheenvironment.Becauseofthis,werarelymeetthesecommandlineoptions.Nevertheless,professionalshavetounderstandtheirmeaningsatleastandknowwheretolearntheiractualuseincaseitisneeded.

Page 82:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 83:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LookingatthebytecodeTheclassfileisabinaryfile.ThemainroleofthisformatistobeexecutedbytheJVMandtoprovidesymbolicinformationfortheJavacompilerwhenacodeusessomeoftheclassesfromalibrary.WhenwecompileourprogramthatcontainsSystem.out.println,thecompilerlooksatthecompiled.classfilesandnotatthesourcecode.IthastofindtheclassnamedSystem,thefieldnamedout,andthemethodprintln.Whenwedebugapieceofcodeortrytofindoutwhyaprogramdoesnotfindaclassormethod,wewillneedawaytolookintothebinaryofthe.classfiles.Thisisnotaneverydaytaskandittakessomeadvancedknowledge

Todoso,thereisadecompilerthatcandisplaythecontentofa.classfileinamoreorlessreadableformat.Thiscommandiscalledjavap.Toexecuteit,youcanissuethefollowingcommand:

$javapHelloWorld.class

Compiledfrom"HelloWorld.java"

publicclassHelloWorld{

publicHelloWorld();

publicstaticvoidmain(java.lang.String[]);

}

TheoutputoftheprogramshowsthattheclassfilecontainsJavaclassthathassomethingcalledHelloWorld();itseemstobeamethodhavingthesamenameastheclassanditalsocontainsthemethodwehavewritten.

Themethodthathasthesamenameastheclassistheconstructoroftheclass.Aseveryclassinjavacanbeinstantiated,thereisaneedforaconstructor.Ifwedonotgiveone,thentheJavacompilerwillcreateoneforus.Thisisthedefaultconstructor.Thedefaultconstructordoesnothingspecialbutreturnsanewinstanceoftheclass.Ifweprovideaconstructoronourown,thentheJavacompilerwillnothavebotheredcreatingone.

ThejavapdecompilerdoesnotshowwhatisinsidethemethodsorwhatJavacodeitcontainsunlessweprovidethe-coption:

$javap-cHelloWorld.class

Compiledfrom"HelloWorld.java"

publicclassHelloWorld{

publicHelloWorld();

Code:

0:aload_0

1:invokespecial#1//Methodjava/lang/Object."<init>":()V

4:return

publicstaticvoidmain(java.lang.String[]);

Code:

0:getstatic#2//Fieldjava/lang/System.out:Ljava/io/PrintStream;

3:ldc#3//Stringhali

5:invokevirtual#4//Methodjava/io/PrintStream.println:(Ljava/lang/String;)V

8:return

}

Itisverycrypticandisnotforordinaryhumans.Onlyafewexperts,whodealwiththeJavacodegeneration,canfluentlyreadthat.But,tohavealookatithelpsyougetaglimpseofwhatbytecodemeans.Itissomethinglikeagoodoldassembly.Althoughthisisbinarycode,thereisnothingsecretinit:Javaisopensource,theclassfileformatiswelldocumentedanddebuggablefortheexperts.

Page 84:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 85:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PackagingclassesintoaJARfileWhenyoudeliveraJavaapplication,usuallythecodeispackagedintoJAR,WAR,EAR,orsomeotherpackagedformat.Welearnsomethingagainthatseemstobeobscureatfirstsight,butinreality,thisisnotthatcomplex.TheyareallZIPfiles.YoucanopenanyofthesefilesusingWinZiporsomeotherzipmanagerthatyouhavealicensefor.Theextrarequirementisthat,forexample,inthecaseofaJARfile,thearchiveshouldcontainadirectorynamedMETA-INFandinsideitafilenamedMANIFEST.MF.Thisfileisatextfileandcontainsmetainformationintheformat,whichisasfollows:Manifest-Version:1.0Created-By:9-ea(OracleCorporation)

Therecanbealotofotherinformationinthefile,butthisistheminimumthattheJavaprovidedtooljarputsthereifwepackageourclassfileintoajarissuingthefollowingcommand:

jar-cfhello.jarHelloWorld.class

The-coptiontellstheJARarchivertocreateanewJARfileandtheoptionfisusedtospecifythenameofthenewarchive.Theonewespecifiedhereishello.jarandthefileaddedtoitistheclassfile.

ThepackagedJARfilecanalsobeusedtostarttheJavaapplication.JavacanreaddirectlyfromJARarchivesandloadclassesfromthere.Theonlyrequirementisthattheyareontheclasspath.

Notethatyoucannotputindividualclassesontheclasspath,onlydirectories.AsJARfilesarearchiveswithaninternaldirectorystructureinthem,theybehavelikeadirectory.

CheckthattheJARfilewascreatedusinglshello.jarandremovethermHelloWorld.classclassfilejusttoensurethatwhenweissuethecommandline,thecodeisexecutedfromtheJARfileandnottheclass.

$java-cphello.jarHelloWorld

HelloWorld

ToseethecontentoftheJARfile,however,itisrecommendedthatyouusetheJARtoolandnotWinZipeventhoughthatmaybecozier.RealprofessionalsusetheJavatoolstohandleJavafiles.

$jar-tfhello.jar

META-INF/

META-INF/MANIFEST.MF

HelloWorld.class

Page 86:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 87:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ManagingtherunningJavaapplicationTheJavatoolsetthatcomeswiththeJDKsupportstheexecutionandmanagementofrunningJavaapplicationsaswell.Tohavesomeprogramthatwecanmanagewhileexecuting,wewillneedacodethatrunsnotonlyforafewmillisecondsbut,whileitruns,italsoprintssomethingtotheconsole.Let'screateanewprogramcalledHelloWorldLoop.javawiththefollowingcontent:

publicclassHelloWorldLoop{

publicstaticvoidmain(String[]args){

for(;;){

System.out.println("HelloWorld");

}

}

}

Theprogramcontainsaforloop.Loopsallowrepeatedexecutionofacodeblock,andwewilldiscusstheminChapter2,TheFirstRealJavaProgram-SortingNames.Theloopwecreatedhereisaspecialonethatneverterminatesbutrepeatstheprintingmethodcall,printingHelloWorlduntilwekilltheprogrambypressingCtrl+corissuingakillcommandonLinuxoronOSX,orterminatetheprograminthetaskmanagerunderWindows.

CompileandstartitinonewindowandopenanotherTerminalwindowtomanagetheapplication.

Thefirstcommandthatweshouldgetfamiliarwithisjps.http://docs.oracle.com/javase/7/docs/technotes/tools/share/jps.htmlItliststheJavaprocessesthatrunonthemachine,whichareasfollows:

$jps

21873sun.tools.jps.Jps

21871HelloWorldLoop

Youcanseethattherearetwoprocesses—oneistheprogramweexecuteandtheotheristhejpsprogramitself.Notsurprisingly,thejpstoolisalsowritteninJava.Youcanalsopassoptionstojps,whicharedocumentedontheweb.

Therearemanyothertoolsandwewillexamineoneofthem,whichisaverypowerfulandeasy-to-usetool—JavaVisualVM.

Page 88:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

VisualVMisacommand-linegraphicaltoolthatconnectstotherunningJavaprocessanddisplaysthedifferentperformanceparameters.TostarttheVisualVMtool,youwillissuethejvisualvmcommandwithoutanyparameters.Soon,awindowwillappearwithanexploringtreeontheleft-handsideandawelcomepaneontheright.TheleftsideshowsalltherunningJavaprocessesunderthebranchnamedLocal.IfyoudoubleclickonHelloWorldLoop,itwillopenthedetailsoftheprocessontherightpane.Ontheheadertabs,youcanselectOverview,Monitor,Threads,Sampler,andProfiler.ThefirstthreetabsarethemostimportantandgiveyouagoodviewofwhatishappeninginJVMregardingthenumberofthreads,CPUusage,memoryconsumption,andsoon.

Page 89:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 90:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

UsinganIDEIntegrateddevelopmentenvironmentsareoutstandingtoolsthathelpthedevelopmentbyoffloadingthemechanicaltasksfromthedeveloper'sshoulders.Theyrecognizemanyoftheprogrammingerrorsaswetypethecode,helpusfindtheneededlibrarymethods,displaythedocumentationofthelibraries,andprovideextratoolsforstylechecking,debugging,andsoon.

Inthissection,wewilllookatsomeIDEsandhowtoleveragethefunctionstheyprovide.

TogetanIDE,youwillhavetodownloadandinstallit.ItdoesnotcomewiththeJavadevelopmenttoolsbecausetheyarenotpartofthelanguageenvironment.But,don'tworry.Theycanbedownloadedfreeofchargeandareeasytoinstall.Theymaybemorecomplextostartupthananotepadeditor,butevenafterafewhoursofwork,theywillpaybackthetimeyoudevotetolearningthem.Afterall,itisnotwithoutreasonthatnodeveloperiscodingJavainnotepadorvi.

ThethreetopmostIDEsareNetBeans,Eclipse,andIntelliJ.Allareavailableincommunityversions,whichmeansthatyouneednotpayforthem.IntelliJhasafullversionthatyoucanalsobuy.Thecommunityeditionwillbeusableforlearningthelanguage.IncaseyoudonotlikeIntelliJ,youcanuseEclipseorNetBeans.Theseareallfreeofcharge.Personally,IusetheIntelliJcommunityeditionformostofmyprojectsandthescreensamplesthatshowanIDEinthisbookwillfeaturethisIDE.But,itdoesnotnecessarilymeanthatyouhavetosticktothisIDE.

Inthedevelopercommunity,therearetopicsthatcanbeheavilydebated.Thesetopicsareaboutopinions.Weretheyaboutfactsthedebatewouldeasilybesoonover.Onesuchtopicis:"WhichisthebestIDE?"Itisamatteroftaste.Thereisnodefiniteanswer.Ifyoulearnhowtouseone,youwilllikethatandyouwillbereluctanttolearnanotherone,unlessyouseethattheotheroneissomuchbetter.ThatisthereasondeveloperslovetheIDEtheyuse(orjusthate,dependingontheirpersonality),buttheykeepusingthesameIDEusuallyforalongtime.ThereisnobestIDE.

TodownloadtheIDEofyourchoice,youcanvisiteitheroneofthefollowingwebsites:

https://netbeans.org/forNetBeanshttp://www.eclipse.org/forEclipsehttps://www.jetbrains.com/idea/forIntelliJ

Page 91:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 92:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

NetBeans

NetBeansissupportedbyOracleandiscontinuouslydeveloped.Itcontainscomponents,suchastheNetBeansprofiler,thatbecamepartoftheOracleJavadistribution.YoumaynoticethatwhenyoustartVisualVMandstarttheprofiling,theJavaprocessstartedhasnetbeansinitsname.

Generally,NetBeansisaframeworktodeveloprichclientapplicationsandtheIDEisonlyoneapplicationofthemanythatarebuiltontopoftheframework.Itsupportsmanylanguages,notonlyJava.YoucandevelopPHP,C,orJavaScriptcodeusingNetBeansandhavesimilarservicesforJava.Forthesupportofdifferentlanguages,youcandownloadpluginsoraspecialversionofNetBeans.ThesespecialversionsareavailablefromthedownloadpageoftheIDEandtheyarenothingmorethanthebasicIDEwithsomepreconfiguredplugins.IntheCpackage,thedevelopersconfigurethepluginsthatareneededwhenyouwanttodevelopC;inthePHPversion,theypluginforPHP.

Page 93:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 94:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Eclipse

EclipseissupportedbyIBM.SimilartoNetBeans,itisalsoaplatformforrichclientapplicationanditisbuiltaroundtheOSGicontainerarchitecture,whichitselfisatopicthatcanfillabooklikethis.MostofthedevelopersuseEclipseand,almostexclusively,itisthechoicewhendeveloperscreatecodefortheIBMWebSphereapplicationserver.TheEclipsespecialversioncontainsadeveloperversionofWebSphere.

EclipsealsohaspluginstosupportdifferentprogramminglanguagesandalsohasdifferentvariationssimilartoNetBeans.ThevariationsarepluginsprepackagedwiththebasicIDE.

Page 95:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 96:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IntelliJ

ThelastoneintheprecedingenumerationisIntelliJ.ThisIDEistheonlyonethatdoesnotwanttobeaframework.IntelliJisanIDE.Italsohasplugins,butmostofthepluginsthatyouwillneedtodownloadtouseinNetBeansorEclipsearepreconfigured.Whenyouwanttousesomemoreadvancedplugin,itmayhoweverbesomethingyouhavetopayfor,whichshouldnotbeaproblemwhenyouaredoingprofessional,paidwork,shouldit?Thesethingsarenotthatexpensive.Forlearningthesubjectsinthisbook,youwillnotneedanypluginthatisnotinthecommunityedition.Asinthisbook,IwilldevelopthesamplesusingIntelliJandIrecommendthatyoufollowmeduringyourlearningexperience.

IwanttoemphasizethattheexamplesinthisbookareindependentoftheactualIDEtobeused.YoucanfollowthebookusingNetBeans,Eclipse,orevenEmacs,notepad,orvi.

Page 97:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 98:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IDEservices

Integrateddevelopmentenvironmentsprovideuswithservices.Themostbasicserviceisthatyoucaneditfileswiththem,buttheyalsohelpbuildthecode,findbugs,runthecode,deploytotheapplicationserverindevelopmentmode,debug,andsoon.Inthefollowingsections,wewilllookatthesefeatures.IwillnotgiveanexactandpreciseintroductiononhowtouseoneortheotherIDE.Abooklikethisisnotagoodmediumforsuchatutorial.

IDEsdifferonmenuplacement,keyboardshortcuts,andtheymayevenchangeasnewerversionsarereleased.ItisbesttolookattheactualIDEtutorialvideooronlinehelp.Theirfeatures,ontheotherhand,areverysimilar.IntelliJhasthevideodocumentationathttps://www.jetbrains.com/idea/documentation/.

Page 99:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 100:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IDEscreenstructureThedifferentIDEslooksimilar,andhavethesamescreenstructuremoreorless.Inthefollowingscreenshot,youcanseeanIntelliJIDE:

Ontheleftside,youcanseethefilestructureofaJavaproject.AJavaprojecttypicallycontainsmanyfilesindifferentdirectorieswhichwewilldiscussinthenextchapter.ThesimpleHelloWorldapplicationcontainsapom.xmlprojectdescriptionfile.ThisfileisneededfortheMavenbuildtool,whichisalsoatopicforthenextchapter.Fornow,youshouldonlyknowthatitisafilethatdescribestheprojectstructureformaven.TheIDEalsokeepstrackofsomeadministrativedataforitself.ItisstoredinHelloWorld.iml.Themainprogramfileisstoredinthesrc/main/javadirectoryandnamedHelloWorld.java.

Ontherightside,youcanseethefiles.Inthescreenshot,wehaveonlyonefileopened.Incasethereismorethanonefileopened,thentherearetabs-oneforeachfile.Now,theactivefileisHelloWorld.javathatcanbeeditedinthesourcecodeeditor.

Page 101:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 102:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

EditingfilesWhenediting,youcantypeincharactersordeletecharacters,words,andlines,butthisissomethingthatalleditorscando.IDEsofferextra.IDEsanalyzethesourcecodeandformatit,which,inturn,automaticallyindentsthelines.Italsocontinuouslycompilesthecodeinthebackgroundwhileyouedititandifthereissomesyntaxerror,thenitunderlinesitwitharedwaivingline.Whenyoufixtheerror,theredunderliningdisappears.

Theeditoralsoautomaticallygivessuggestionsforfurthercharactersasyoutype.Youcanignorethewindowthatpopsupandcontinuetyping.However,manytimes,itiseasiertostopafteracharacterandusetheupanddownarrowstoselectthewordthatneedsfinishingbeforepressingEnter:thewordwillbeinsertedintothesourcecodeautomatically.

Inthescreenshot,youcanseethatIwroteSystem.oandtheeditorimmediatelysuggestedthatIwantedtowriteout.TheotheralternativesaretheotherstaticfieldsandmethodsthatareintheclassSystemandwhichcontainthelettero.

TheIDEeditorgivesyouhintsnotonlywhenitcantypeforyou,butalsowhenitcannottypeinsteadofyou.Inthescreenshot,theIDEtellsyoutotypesomeexpressionasargumenttotheprintln()methodthatisboolean,char,int,andsoon.TheIDEhasabsolutelynoideawhattotypethere.Youhavetoconstructtheexpression.Still,itcantellyouthatitneedstobeofacertaintype.

Itisnotonlythebuilt-intypesthattheeditorknows.TheeditorintegratedwiththeJDKcontinuouslyscansthesourcefilesandknowswhatclasses,methods,andfieldsarethereinthesourcecodewhichare

Page 103:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

usableattheplaceofediting.

Thisknowledgeisalsoheavilyusedwhenyouwanttorenameamethodorvariable.Theoldmethodwastorenamethefieldormethodinthesourcefileandthendoanexhaustivesearchforallreferencestothevariable.UsingtheIDE,themechanicalworkisdonebyit.Itknowsalltheusesofafieldormethodandautomaticallyreplacestheoldidentifierwiththenewone.Italsorecognizeswhetheralocalvariablehappenstohavethesamenameastheonethatwerename,andtheIDEonlyrenamesthoseoccurrencesthatarereallyreferringtotheonewearerenaming.

Youcanusuallydomorethanjustrenaming.Therearemoreorlessmechanicaltasksthatprogrammerscallrefactoring.ThesearesupportedbytheIDEsusingsomekeyboardshortcutandcontextsensitivemenuintheeditor—rightclickonthemouseandclickMenu.

TheIDEalsohelpsyoutoreadthedocumentationofthelibrariesandsourcecodeasshowninthefollowingimage:

LibrariesprovideJavadocdocumentationforthepublicmethodsandyoushouldalsowriteJavadocforyourownmethod.JavadocdocumentationisextractedfromspecialcommentsinthesourcecodeandwewilllearnhowtocreatethoseinChapter4,Mastermind-CreatingaGame.Thesearelocatedincommentsinfrontoftheactualmethodhead.Ascreatingcompileddocumentationispartofthecompilationflow,theIDEalsoknowsthedocumentationanditdisplaysasahoveringboxoverthemethodnames,classnames,orwhateverelementyouwanttouseinthesourcefilewhenyoupositionthecursorontheelement.

Page 104:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 105:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ManagingprojectsOntheleftsideoftheIDEwindow,youcanseethedirectorystructureoftheproject.TheIDEknowsthedifferenttypesoffilesandshowstheminawaythatismeaningfulfromtheprogrammingpointofview.Forexample,itdoesnotdisplayMain.javaasafilename.Instead,itdisplaysMainandaniconthatsignalsthatMainisaclass.ItcanalsobeaninterfacestillinafilenamedMain.javabut,inthatcase,theiconwillshowthatthisisaninterface.ThisisagaindonebytheIDEcontinuouslyscanningandcompilingthecode.

ThefilesarestructuredintosubdirectorieswhenwedevelopaJavacode.Thesesubdirectoriesfollowthepackagingstructureofthecode.Manytimes,inJava,weusecompoundandlongpackagenames,anddisplayingitasadeepandnesteddirectorystructurewillnotbesoeasytohandle.

Packagesareusedtogroupthesourcefiles.Thesourcefilesforclassesthatarerelatedinsomewayshouldgointoonepackage.Wewilldiscussthenotionofpackagesandhowtousetheminthenextchapter

TheIDEiscapableofshowingthepackagestructureinsteadofthenesteddirectoriesforthosedirectoriesoftheprojectthatcontainsourcefiles.

Whenyoumoveaclassoraninterfacefromonepackagetoanother,ithappensinasimilarwayasrenamingorotherrefactoring.Allreferencestotheclassorinterfaceinthesourcefilesgetrenamedtothenewpackage.Ifafilecontainsanimportstatementreferringtotheclass,thenameoftheclassinthestatementiscorrected.Tomoveaclass,youcanopenthepackageandusethegoodolddraganddrop.

PackagehierarchyisnottheonlyhierarchydisplayedintheIDE.Theclassesareinpackagesbut,atthesametime,thereisaninheritancehierarchy.Classesmayimplementinterfacesandcanextendotherclasses.TheJavaIDEshelpusbyshowingtypehierarchieswhereyoucannavigateacrossagraphicalinterfacealongtheinheritancerelations.

ThereisanotherhierarchythatIDEscanshowtohelpuswithdevelopment:methodcallhierarchy.Afteranalyzingthecode,theIDEcanshowusthegraphdisplayingtherelationsbetweenthemethods:whichmethodcallswhichothermethods.Sometimes,thiscallgraphisalsoimportantinshowingthe

Page 106:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

dependenciesofmethodsoneachother.

Page 107:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 108:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

BuildthecodeandrunitTheIDEsusuallycompilethecodeforanalysistohelpusspotsyntaxerrorsorundefinedclassesandmethodsonthefly.Thiscompilationisusuallypartial,coveringapartofthecode,andasitrunsallthetime,thesourcecodechangesandisneveractuallycomplete.Tocreatethedeployablefile,thatis,thefinaldeliverablecodeoftheproject,aseparatebuildprocesshastobestarted.MostoftheIDEshavesomebuilt-intoolforthat,butit'snotrecommendedtousetheseexceptforthesmallestprojects.ProfessionaldevelopmentprojectsuseAnt,Maven,orGradleinstead.HereisanexampleofMaven.

TheIDEsarepreparedtousesuchanexternaltool,andtheycanhelpusinstartingthem.Thisway,thebuildprocesscanrunonthedevelopermachinewithoutstartinganewshellwindow.IDEscanalsoimportthesettingsfromtheconfigurationfileoftheseexternalbuildtoolstorecognizetheprojectstructure,wheresourcefilesare,andwhattocompiletosupporttheerrorcheckingwhileediting.

Thebuildingprocessusuallycontainstheexecutionofcertainchecksonthecode.AbunchoftheJavasourcefilemaycompilesmoothlyandthecodemaystillcontainalotofbugsandmaybewritteninbadstyle,whichwillmaketheprojectbecomesunmaintainableinthelongrun.Toavoidsuchproblems,wewilluseunittestsandstaticcodeanalysistools.Thesedonotguaranteeerrorfreecodebutthechancesaremuchbetter.

IDEshavepluginstorunthestaticcodeanalysistoolsaswellasunittests.BeingintegratedintotheIDEhasahugeadvantage.Whenthereisanyproblemidentifiedbytheanalysistool,orbysomeunittests,theIDEprovidesanerrormessagethatalsofunctionslikealinkonawebpage.Ifyouclickonthemessage,usuallyblueandunderlined,exactlylikeonawebpage,theeditoropenstheproblematicfileandplacesthecursorwheretheissueis.

Page 109:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 110:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

DebuggingJavaDevelopingcodeneedsdebugging.Javahasverygoodfacilitiestodebugcodeduringdevelopment.JVMsupportsdebuggersviatheJavaPlatformDebuggerArchitecture.ThisletsyouexecutecodeindebugmodeandJVMwillacceptexternaldebuggertoolstoattachtoitviaanetwork,oritwilltrytoattachtoadebuggerdependingoncommand-lineoptions.JDKcontainsaclient,thejdbtool,whichcontainsadebugger;however,itissocumbersometousewhencomparedtothegraphicalclientbuiltintotheIDEsthatIhaveneverheardofanyoneusingitforrealwork.

TostartaJavaprogramindebugmodesothatJVMwillacceptadebuggerclienttoattachtheoptionstoit,executethefollowingcommand:-Xagentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=7896

TheXagentliboptioninstructstheJavaruntimetoloadthejdwpagent.Thepartoftheoptionthatfollows-Xagentlib:jdwp=isinterpretedbythedebuggeragent.Theseoptionsareasfollows:

transport:Thisshouldspecifywhichtransporttouse.Itcanbeasharedmemory(dt_shmem)socketoraTCP/IPsockettransportbut,inpractice,youwillalwaysusethelatter.Thisisspecifiedintheprecedingdt_socketsample.server:ThisspecifiesifthedebuggedJVMstartsinservermodeorclientmode.WhenyoustarttheJVMinservermode,itstartstolistenonasocketandacceptsthedebuggertoconnecttoit.Ifitisstartedinclientmode,thenittriestoconnectadebuggerthatissupposedtobestartedinservermode,listeningonaport.Thevalueoftheoptionisymeaningservermodeornmeaningnonserver,a.k.a.clientmode.suspend:Thiscanalsobeyorn.IfJVMisstartedinsuspendmode,itwillnotstarttheJavacodeuntiladebuggerisattachedtoit.Ifitisstartedwithsuspend=n,thentheJVMstartsandwhenadebuggerattaches,itstopsassoonasabreakpointisreached.IfyoustartastandaloneJavaapplication,youwillusuallystartthedebuggingwithsuspend=y,whichisthedefault.Ifyouwanttodebuganapplicationinanapplicationserverorservlet-containerenvironment,thenitisbettertostartwithsuspend=n;otherwise,theserverdoesnotstartuntilthedebuggerattachestoit.StartingtheJavaprocessinsuspend=ymodeincaseservletapplicationisonlyusefulwhenyouwanttodebugtheservletstaticinitializercode,whichisexecutedwhentheserverisstartingup.Withoutsuspendmode,youwillberequiredtoattachthedebuggerveryfast.ItisbetterthatJVMjustwaitsforyouinthatsituation.address:ThisshouldspecifytheaddressthatJVMcommunicateswith.IftheJVMstartedinclientmode,thenitwillstarttoconnecttothisaddress.IftheJVMrunsinservermode,thenitwillacceptconnectionsfromthedebuggeronthataddress.Theaddressmayspecifyonlytheport.Inthiscase,theIPaddressisthatofthelocalmachine.

Theotheroptionsthedebuggeragentmayhandleareforspecialcases.Forthetopicscoveredinthisbook,theprecedingoptionsareenough.

ThefollowingscreenshotshowsatypicaldebuggingsessionwherewedebugthesimplestprograminIntelliJIDE:

Page 111:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhenyoustartaprogramfromtheIDEindebugmode,alltheseoptionsareautomaticallysetforyou.Youcansetbreakpointjustbyclickingonthesourcecodeintheeditor.Youcanhaveaseparateformtoadd,remove,andeditbreakpoints.Breakpointscanbeattachedtospecificlinesorspecificevents,likewhenanexceptionisthrown.Breakpointsattachedtoaspecificlinecanalsohaveconditionsthattellthedebuggertostoptheexecutionofthecodeonlywhentheconditionistrue;forexample,ifavariablehassomepredefinedvalue.

Page 112:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 113:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

InthischapterwewereintroducedtoeachotherwithJava.Wedonotknowtoomuchfromeachotherbutwegotacquainted.WehaveinstalledtheJavaenvironment:Java,JDKandintegrateddevelopmentenvironment.Wehavewrittenasmallprogramandhadabrieflookatwhatcanbedoneusingthedevelopmenttools.Thisisfarfrommasterybuteventhelongestjourneystartswithafirststep,whichissometimesthehardesttomake.WehavedoneitinourJavajourney.Westartedrollingandfortheenthusiaststhatweare,nothingcanstopuswalkingallthewaylong.

Page 114:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 115:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheFirstRealJavaProgram-SortingNames

Inthepreviouschapter,wegotacquaintedwithJava,andespeciallywithusingtheREPLtoolandinteractivelyexecutingsomesimplecode.Thatisagoodstart,butweneedmore.Inthischapter,wewilldevelopasimplesortprogram.Usingthiscodeasanexample,wewilllookatdifferentbuildtools,whicharefrequentlyusedforJavaprojects,andlearnthebasicfeaturesoftheJavalanguage.Thischapterwillcoverthefollowingtopics:

ThesortingproblemTheprojectstructureandbuildtoolsTheMake,Ant,Maven,andGradlebuildtoolsJavalanguagefeaturesrelatedtothecodeexample

Page 116:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 117:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GettingstartedwithsortingThesortingproblemisoneoftheoldestprogrammingtasksthatanengineerdealswith.Wehaveasetofrecordsandweknowthatwewanttofindaspecificonesometimelater,andwewanttofindthatonefast.Tofindit,wesorttherecordsinaspecificorderthathelpsusfindtherecordwewantquickly.

Asanexample,wehavethenamesofstudentswiththeirmarksonsomecards.Whenstudentscometotheofficeaskingfortheirresults,welookthroughallofthecardsoneaftertheothertofindthenameoftheenquiringstudent.However,itisbetterifwesortthecardsbythenamesofthestudentsalphabetically.Whenastudentmakesanenquiry,wecansearchthemarkattachedtothenamemuchfaster.

Wecanlookatthemiddlecard;ifitshowsthenameofthestudent,thenwearehappytohavefoundthenameandthemark.Ifthecardprecedesthenameofthestudentalphabetically,thenwewillcontinuesearchinginthesecondhalf;otherwise,wewillcheckthefirsthalf.

Followingthatapproach,wecanfindthenameofthestudentinafewsteps.Thenumberofstepscannotbemorethanthenumberasmanytimesthepackofcardscanbehalved.Ifwehavetwocards,thenitistwostepsatmost.Ifitisfour,thenwewillneedthreestepsatmost.Ifthereareeightcards,thenwemayneedfoursteps,butnotmore.Ifthereare1,000cards,thenwemayneedatmost11steps,whiletheoriginal,non-sortedsetwillneed1,000steps,worstcase.Thatis,approximately,itspeedsupthesearch100times,sothisisworthsortingthecards,unlessthesortingitselftakestoomuchtime.Thealgorithmfindinganelementinthealreadysortedsetwejustdescribediscalledbinarysearch(https://en.wikipedia.org/wiki/Binary_search_algorithm).

Inmanycases,itisworthsortingthedataset,andtherearemanysortingalgorithmstodothat.Therearesimplerandmorecomplexalgorithms,and,asinmanycases,morecomplexalgorithmsaretheonesthatrunfaster.

AswearefocusingontheJavaprogrammingpartandnotthealgorithmforging,inthischapter,wewilldevelopaJavacodethatimplementsasimpleandnot-that-fastalgorithm.

Page 118:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 119:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Bubblesort

Thealgorithmthatwewillimplementinthischapteriswell-knownasbubblesort.Theapproachisverysimple.Beginatthestartofthecardsandcomparethefirstandthesecondcard.Ifthefirstcardislaterinlexicographicorderthanthesecondone,thenswapthetwocards.Thenrepeatthisforthecardthatisatthesecondplacenow,thenthethird,andsoon.Thereisacardthatislexicographicallythelatest,sayWilson.Whenwegetthiscardandstarttocompareitwiththenextone,wewillalwaysswapthem;thisway,Wilson'scardwilltraveltothelastplacewhereithastobeafterthesort.Allwehavetodoisrepeatthistravellingfromthestartanddotheoccasionalswappingofcardsagain,butthistimeonlytothelastbutoneelement.Thistime,thesecondlatestelementwillgettoitsplace—say,WilkinsonwillberightbeforeWilson.Ifwehavencards,andwerepeatthisn-1times,allcardswillgettotheirplace.

Inthefollowingsections,wewillcreateaJavaprojectthatimplementsthisalgorithm.

Page 120:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 121:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GettingstartedwithprojectstructureandbuildtoolsWhenaprojectismorecomplexthanasingleclass,anditusuallyis,thenitiswisetodefineaprojectstructure.Wewillhavetodecidewherewestorethesourcefiles,wheretheresourcefiles(thosethatcontainsomeresourcefortheprogram,butarenotJavasource)are,wherethe.classfilesshouldbewrittenbythecompiler,andsoon.Generally,thestructureismainlythedirectorysetupandtheconfigurationofthetoolsthatperformthebuild.

Thecompilationofcomplexprogramscannotbefeasiblydoneusingthecommandlineissuingjavaccommands.Ifwehave100Javasourcefiles,thecompilationwillrequirethatmanyjavaccommandstobeissued.Itcanbeshortenedusingwildcards,suchasjavac*.java,orwecanwriteasimplebashscriptoraBATcommandfilethatdoesthat.First,itwillbejust100lines,eachcompilingonesourceJavafiletoclassfile.Then,wewillrealizethatitisonlytime,CPU,andpowerconsumingtocompilethefilesthatarenotchangedsincethelastcompilationssowecanaddsomebashprogrammingthatchecksthetimestamponthesourceandgeneratedfiles.Then,wewillprobablyrealizethat...whatever.Attheend,wewillendupwithatoolthatisessentiallyabuildtool.Buildtoolsareavailablereadymade;itisnotworthreinventingthewheel.

Insteadofcreatingone,wewilluseabuildtoolthatisready.Thereareafewofthemthatcanbefoundathttps://en.wikipedia.org/wiki/List_of_build_automation_software.Inthischapter,wewilluseonecalledMaven;however,beforejumpingintothedetailsofthistool,wewilllookatsomeothertoolsthatyouarelikelytomeetasaJavaprofessionalinenterpriseprojects.

Inthefollowingsections,wewilldiscussabitofthefourbuildtools:

MakeAntMavenGradle

WewillmentionMakeonlybrieflybecauseitisnotusedinJavaenvironmentsthesedays.However,Makewasthefirstbuildtool,andmanyideasthatmodernJavabuildtoolsarebasedoncomefromthegoodoldmake.You,asaprofessionalJavadeveloper,shouldalsobefamiliarwithMakesothatyouwillnotfreakoutifyouhappentoseetheuseofitinaprojectforsomepurpose,andcanknowwhatitisandwhereitsdetaileddocumentationcanbefound.

AntwasthefirstbuildtoolwidelyusedforJavamanyyearsago,anditisstillusedinmanyprojects.

MavenisnewerthanAnt,anditusesadifferentapproach.Wewilllookatitindetail.MavenisalsotheofficialbuildtooloftheApachesoftwarefoundationfortheJavaproject.WewillalsouseMavenasabuildtoolinthischapter.

Gradleisevennewer,andithasstartedtocatchuptoMaventhesedays.Wewillusethistoolinlater

Page 122:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

chaptersinmoredetail.

Page 123:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 124:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MakeThemakeprogramwasoriginallycreatedinApril1976,sothisisnotanewtool.ItisincludedintheUnixsystem,sothistoolisavailablewithoutanyextrainstallationonLinux,MacOSX,oranyotherUnix-basedsystem.Additionally,therearenumerousportsofthetoolonWindows,andsomeversionis/wasincludedintheVisualStudiocompilertoolset.

TheMakeisnottiedtoJava.ItwascreatedwhenthemajorprogramminglanguagewasC,butitisnottiedtoCoranyotherlanguage.Themakeisadependencydescriptionlanguagethathasaverysimplesyntax.Themake,justlikeanyotherbuildtool,iscontrolledbyaprojectdescriptionfile.Inthecaseofmake,thisfilecontainsaruleset.ThedescriptionfileisusuallynamedMakefile,butincasethenameofthedescriptionfileisdifferent,itcanbespecifiedasacommand-lineoptiontothemakecommand.

RulesinMakefilefolloweachotherandconsistofoneormorelines.Thefirstlinestartsatthefirstposition(thereisnotaborspaceatthestartoftheline)andthefollowinglinesstartwithatabcharacter.Thus,Makefilemaylooksomethinglikethefollowingcode:

run:hello.jar

java-cphello.jarHelloWorld

hello.jar:HelloWorld.class

jar-cfhello.jarHelloWorld.class

HelloWorld.class:HelloWorld.java

javacHelloWorld.java

Thisfiledefinesthreeso-calledtargets:run,hello.jar,andHelloWorld.class.TocreateHelloWorld.class,typethefollowinglineatthecommandprompt:

makeHelloWorld.class

MakewilllookattheruleandseethatitdependsonHelloWorld.java.IftheHelloWorld.classfiledoesnotexist,orHelloWorld.javaisnewerthantheJavaclassfile,makewillexecutethecommandthatiswrittenonthenextlineanditwillcompiletheJavasourcefile.IftheclassfilewascreatedfollowingthelastmodificationofHelloWorld.java,thenmakeknowsthatthereisnoneedtorunthecommand.

InthecaseofcreatingHelloWorld.class,themakeprogramhasaneasytask.Thesourcefilewasalreadythere.Ifyouissuethemakehello.jarcommand,theprocedureismorecomplex.Themakecommandseesthatinordertocreatehello.jar,itneedsHelloWorld.class,whichitselfisalsoatargetonanotherrule.Thus,itmayneedtobecreated.

First,itstartstheproblemthesamewayasbefore.IfHelloWorld.classisthere,andisolderthanhello.jar,thereisnothingtodo.Ifitisnotthere,orisnewerthanhello.jar,thenthejar-cfhello.jarHelloWorld.classcommandneedstobeexecuted,althoughnotnecessarilyatthemomentwhenitrealizesthatithastobeperformed.ThemakeprogramremembersthatthiscommandhastobeexecutedsometimeinthefuturewhenallthecommandsthatareneededtocreateHelloWorld.classarealreadyexecutedsuccessfully.Thus,itcontinuestocreatetheclassfileexactlythesamewayasIdescribedearlier.

Page 125:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Ingeneral,arulecanhavethefollowingformat:

target:dependencies

command

Themakecommandcancreateanytargetusingthemaketargetcommandbyfirstcalculatingwhichcommandstoexecuteandthenexecutingthemonebyone.ThecommandsareshellcommandsexecutinginadifferentprocessandmayposeproblemsunderWindows,whichmayrendertheMakefilefiles'operatingsystemdependent.

Notethattheruntargetisnotanactualfilethatmakecreates.Atargetcanbeafilenameorjustanameforthetarget.Inthelattercase,makewillneverconsiderthetargettobereadilyavailable.

AswedonotusemakeforaJavaproject,thereisnoreasontogetintomoredetails.Additionally,Icheatedabitbymakingthedescriptionofarulesimplerthanitshouldbe.Themaketoolhasmanypowerfulfeaturesoutofthescopeofthisbook.Therearealsoseveralimplementationsthatdifferalittlefromeachother.YouwillmostprobablymeettheonemadebytheFreeSoftwareFoundation—theGNUmake.And,ofcourse,justincaseofanyUnixcommand-linetool,manisyourfriend.Themanmakecommandwilldisplaythedocumentationofthetoolonthescreen.

Themainpointsthatyoushouldrememberaboutmakeareasfollows:

Itdefinesthedependenciesoftheindividualartifacts(targets)inadeclarativewayItdefinestheactionstocreatethemissingartifactsinanimperativeway

Thisstructurewasinventeddecadesagoandhassurvivedupuntilnowformostofthebuildtools,asyouwillseeinthenextfewchapters.

Page 126:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 127:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AntTheantbuildtoolwasbuiltespeciallyforJavaprojectsaroundtheyear2000.TheaimofJavatobeawrite-once-run-anywherelanguageneededatoolthatcanalsobeusedindifferentenvironments.AlthoughmakeisavailableonUnixmachines,andWindowsaswell,Makefileswerenotalwayscompatible.Therewasasmallproblemwiththeuseofthetabcharacterthatsomeeditorsreplacedwithspace,renderingMakefileunusable,butthiswasnotthemajorreason.ThemainproblemwithmakethatignitedthedevelopmentofAntisthatthecommandsareshellcommands.Eveniftheimplementationofthemakeprogramwasmadetobecompatibleondifferentoperatingsystems,theusedcommandsweremanytimesincompatible,andthatwassomethingmakeitselfcouldnotchange.Becausemakeissuesexternalcommandstobuildthetargets,developersarefreetouseanyexternaltoolthatisavailableforthemonthedevelopmentmachine.Anothermachineusingthesameoperatingsystemjustmaynothavethesamesetoftoolsinvokedbymake.Thisunderminestheportabilityofthemakebuiltprojects.

Atthesametime,Antisfollowingthemajorprinciplesofmake.Therearetargetsthatmaydependoneachotherandtherearecommandsthatneedtobeexecutedinanappropriatesequencetocreatethetargetsoneaftertheother,followingthedependencyorder.ThedescriptionofthedependenciesandthecommandsisXML(tabissuesolved)andthecommandsareimplementedinJava(systemdependencyissolved,well...moreorless).

AsAntisneitherpartoftheoperatingsystemnortheJDK,youwillhavetodownloadandinstallitseparatelyifyouwanttouseit.

Page 128:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 129:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallingAntAntcanbedownloadedfromitsofficialwebsite(http://ant.apache.org).Youcandownloadthesourceortheprecompiledversion.Theeasiestwayistodownloadthebinaryinatar.gzformat.

WheneveryoudownloadsoftwarefromtheInternet,itishighlyrecommendedthatyouchecktheintegrityofthedownloadedfile.TheHTTPprotocoldoesnotcontainerrorchecking,anditmayhappenthatanetworkerrorremainshiddenoramalevolentinternalproxymodifiesthedownloadedfile.Downloadsitesusuallyprovidechecksumsforthedownloadablefiles.TheseareusuallyMD5,SHA1,SHA512,orsomeotherchecksums.

WhenIdownloadedtheApacheAnt1.9.7versionintar.gzformat,IalsoopenedthepagethatledtotheMD5checksum.Thechecksumvalueisbc1d9e5fe73eee5c50b26ed411fb0119.

Thedownloadedfilecanbecheckedusingthefollowingcommandline:$md5apache-ant-1.9.7-bin.tar.gz

MD5(apache-ant-1.9.7-bin.tar.gz)=bc1d9e5fe73eee5c50b26ed411fb0119

ThecalculatedMD5checksumisthesameastheoneonthewebsite,whichsaysthatthefileintegrityisnotharmed.OntheWindowsoperatingsystem,notooltocalculateMD5digestisincluded.ThereisatoolthatMicrosoftprovides,calledFileIntegrityChecksumVerifierUtility,whichisavailableviathepagehttps://support.microsoft.com/en-us/help/841290/availability-and-description-of-the-file-checksum-integrity-verifier-utility.IfyouuseLinux,itmayhappenthatthemd5ormd5sumutilityisnotinstalled.Inthatcase,youcaninstallitusingthecommandapt-getorwhateverinstallationtoolyourLinuxdistributionsupports.

Afterthefileisdownloaded,youcanexplodeittoasubdirectoryusingthefollowingcommand:

tarxfzapache-ant-1.9.7-bin.tar.gz

ThecreatedsubdirectoryistheusablebinarydistributionofAnt.Usually,Imoveitunder~/bin,makingitavailableonlyformyuseronOSX.Afterthat,youshouldsettheenvironmentvariableasANT_HOMEtopointtothisdirectoryandalsoaddthebindirectoryoftheinstallationtothePATH.Todothat,youshouldeditthe~/.bashrcfileandaddthefollowinglinestoit:

exportANT_HOME=~/bin/apache-ant-1.9.7/

exportPATH=${ANT_HOME}bin:$PATH

Then,restarttheterminalapplication,orjusttype.~/.bashrcandtesttheinstallationofAntbytypingthefollowingcommand:

$ant

Buildfile:build.xmldoesnotexist!

Buildfailed

Iftheinstallationwascorrect,youshouldseetheprecedingerrormessage.

Page 130:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 131:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

UsingAntWhenyouseeaprojecttobebuiltbyAnt,youwillseeabuild.xmlfile.Thisistheprojectbuildfile,theonethatAntwasmissingwhenyoucheckedthattheinstallationwascorrect.Itcanhaveanyothername,andyoucanspecifythenameofthefileasacommand-lineoptionforAnt,butthisisthedefaultfilename,asMakefilewasformake.Abuild.xmlsamplelookslikethefollowing:

<projectname="HelloWorld"default="jar"basedir=".">

<description>

ThisisasampleHelloWorldprojectbuildfile.

</description>

<propertyname="buildDir"value="build"/>

<propertyname="srcDir"value="src"/>

<propertyname="classesDir"value="${buildDir}/classes"/>

<propertyname="jarDir"value="${buildDir}/jar"/>

<targetname="dirs">

<mkdirdir="${classesDir}"/>

<mkdirdir="${jarDir}"/>

</target>

<targetname="compile"depends="dirs">

<javacsrcdir="${srcDir}"destdir="${classesDir}"/>

</target>

<targetname="jar"depends="dirs,compile">

<jardestfile="${jarDir}/HelloWorld.jar"basedir="${classesDir}"/>

</target>

</project>

Thetop-levelXMLtagisproject.Eachbuildfiledescribesoneproject,hencethename.Therearethreepossibleattributestothetag,whichareasfollows:

name:ThisdefinesthenameoftheprojectandisusedbysomeIDEstodisplayitintheleftpanelidentifyingtheprojectdefault:ThisnamesthetargettousewhennotargetisdefinedonthecommandlinestartingAntbasedir:Thisdefinestheinitialdirectoryusedforanyotherdirectorynamecalculationinthebuildfile

Thebuildfilecancontainadescriptionfortheproject,aswellaspropertiesinpropertytags.Thesepropertiescanbeusedasvariablesintheattributesofthetasksbetweenthe${and}characters,andplayanimportantroleinthebuildprocess.

ThetargetsaredefinedintargetXMLtags.Eachtagshouldhaveanamethatuniquelyidentifiesthetargetinthebuildfileandmayhaveadependstagthatspecifiesoneormoreothertargetsthatthistargetdependson.Incasethereismorethanonetarget,thetargetsarecommaseparatedintheattribute.Thetasksbelongingtothetargetsareexecutedinthesameorderasthetargetsdependencychainrequires,inaverysimilarwayaswesawinthecaseofmake.

YoucanalsoaddadescriptionattributetoatargetthatisprintedbyAntwhenthecommand-lineoption,-projecthelp,isused.Thishelpstheusersofthebuildfiletoknowwhattargetsarethereandwhichdoeswhat.Buildfilestendtogrowlargewithmanytargets,andwhenyouhavetenormoretargets,itishardtoremembereachandeverytarget.

Page 132:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThesampleprojectwithHelloWorld.javaisnowarrangedinthefollowingdirectories:

build.xmlintherootfolderoftheprojectHelloWorld.javainthesrcfolderoftheprojectThebuild/folderdoesnotexist;itwillbecreatedduringthebuildprocessThebuild/classesandbuild/jaralsodonotexistyet,andwillbecreatedduringthebuildprocess

WhenyoustartthebuildfortheHelloWorldprojectthefirsttime,youwillseethefollowingoutput:

$ant

Buildfile:/Users/verhasp/Dropbox/java_9-by_Example/sources/ch02/build.xml

dirs:

[mkdir]Createddir:/Users/verhasp/Dropbox/java_9-by_Example/sources/ch02/build/classes

[mkdir]Createddir:/Users/verhasp/Dropbox/java_9-by_Example/sources/ch02/build/jar

compile:

...

[javac]Compiling1sourcefileto/Users/verhasp/Dropbox/java_9-by_Example/sources/ch02/build/classes

jar:

[jar]Buildingjar:/Users/verhasp/Dropbox/java_9-by_Example/sources/ch02/build/jar/HelloWorld.jar

BUILDSUCCESSFUL

Totaltime:0seconds

Someunimportantlinesaredeletedfromtheactualoutput.

Antrealizesthatfirstithastocreatethedirectories,thenithastocompilethesourcecode,andfinallyitcanpackthe.classfilesintoa.jarfile.NowitisuptoyoutorememberthecommandtoexecutetheHelloWorldapplication.Itwaslistedalreadyinthefirstchapter.Notethatthistime,theJARfileisnamedHelloWorld.jar,anditisnotinthecurrentdirectory.YoucanalsotrytoreadtheonlinedocumentationofAntandcreateatargetrunthatexecutesthecompiledandpackedprogram.

Anthasabuilt-intasknamedjavathatexecutesaJavaclassinalmostthesamewayasyoutypedthejavacommandintheterminal.

Page 133:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 134:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MavenAsAntwascreatedtoovercometheshortagesofmake,Mavenwascreatedwithasimilarintention—toovercometheshortagesofAnt.Youmayrecallthatmakecouldnotguaranteebuildportabilitybecausethecommandsmakeexecutesarearbitraryshellcommandsthatmaybesystemspecific.AnAntbuild,ifallthetasksareavailableontheclasspath,isportableaslongasJavarunsthesamewayonthedifferentplatforms.

TheproblemwithAntisabitdifferent.Whenyoudownloadthesourcecodeofaprojectandyouwanttobuild,whatwillthecommandbe?YoushouldaskAnttolistallthetargetsandselecttheonethatseemstobethemostsuitable.Thenameofthetaskdependsontheengineerwhocraftedthebuild.xmlfile.Therearesomeconventions,buttheyarenotstrictrules.

WherewillyoufindtheJavasourcefiles?Aretheyinthesrcdirectoryornot?WilltherealsobesomeGroovyorotherprogramminglanguagefilesincasetheprojectispolyglot?Thatdepends.Again,theremaybesomeconventionsthatsomegroupsorcompanyculturessuggest,butthereisnogeneralbestindustrypractice.

WhenyoustartanewprojectwithAnt,youwillhavetocreatethetargetsforcompilation,testexecution,andpackaging.Itissomethingthatyouwillhavealreadydoneforotherprojects.Afterthesecondorthirdproject,youwilljustcopyandpasteyourpreviousbuild.xmltoyournewproject.Isthataproblem?Yes,itis.Itiscopy/pasteprogramming,evenifitisonlysomebuildfiles.

DevelopersrealizedthatasignificanteffortoftheprojectsutilizingAntisdevotedtoprojectbuildtoolconfiguration,includingrepetitivetasks.Whenanewjoinercomestotheteam,theywillfirsthavetolearnhowthebuildisconfigured.Ifanewprojectisstarted,thebuildconfigurationhastobecreated.Ifitisarepetitivetask,thenbetterletthecomputersdoit.Thatisgenerallywhatprogrammingisallabout,isn'tit?

Mavenapproachesthebuildissueabitdifferently.WewanttobuildJavaprojects.Sometimes,someGroovyorJythonthings,buttheyarealsoJVMlanguages;thus,sayingthatwewanttobuildJavaprojectsisnotreallyahugerestriction.JavaprojectscontainJavafiles,sometimessomeotherprogramminglanguage'ssourcefiles,resourcefiles,andgenerally,thatisit.Antcandoanything,butwedonotwanttodojustanythingwithabuildtool.Wewanttobuildprojects.

Okay,afterwerestrictedourselvesandacceptedthatwedonotneedabuildtoolthatcanbeusedforanything,wecangoon.Wecanrequirethatthesourcefilesbeunderthesrcdirectory.Therearefilesthatareneededfortheoperationalcodeandtherearefilesthatcontainsometestcodeanddata.Therefore,wewillhavetwodirectories,src/testandsrc/main.Javafilesareinsrc/main/javaaswellassrc/test/java.Resourcefilesareundersrc/main/resourcesandsrc/test/resources.

Ifyouwanttoputyoursourcefilessomewhereelse,thendon't.Imeanit.Itispossible,butIwillnoteventellyouhow.Nobodydoesit.IdonotevenhaveanyideawhyMavenmakesitpossible.WheneveryouseeaprojectthatisusingMavenasabuildtool,thesourcesareorganizedlikethat.Thereisnoneedtounderstandthedirectorystructureenvisionedbytheproject'sbuildengineer.Itisalwaysthesame.

Page 135:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Howaboutthetargetsandthetasks?TheyarealsothesameforallMaven-basedprojects.WhatelsewouldyouliketodowithaJavaprojectotherthancompile,test,package,ordeployit?Mavendefinestheseprojectlifecyclesforus.WhenyouwanttocompileaprojectusingMavenasabuildtool,youwillhavetotype$mvncompiletocompiletheproject.Youcandothatevenbeforeunderstandingwhattheprojectactuallyis.

Aswehavethesamedirectorystructureandthesamegoals,theactualtasksleadingtothegoalsarealsoallthesame.WhenwecreateaMavenproject,wedonothavetodescribewhatthebuildprocesshastodoandhowithastodoit.Wewillhavetodescribetheproject,andonlythepartsthatareprojectspecific.

ThebuildconfigurationofaMavenprojectisgiveninanXMLfile.Thenameofthisfileisusuallypom.xml,anditshouldbeintherootdirectoryoftheproject,whichshouldbethecurrentworkingdirectorywhenfiringupMaven.ThewordPOMstandsforProjectObjectModel,anditdescribestheprojectsinahierarchicalway.Thesourcedirectories,thepackaging,andotherthingsaredefinedinaso-calledsuperPOM.ThisPOMispartoftheMavenprogram.AnythingthatthePOMdefines,overridesthedefaultsdefinedinthesuperPOM.Whenthereisaprojectwithmultiplemodules,thePOMsarearrangedintoahierarchy,andtheyinherittheconfigurationvaluesfromtheparentdowntothemodules.AswewilluseMaventodevelopoursortingcode,wewillseesomemoredetailslater.

Page 136:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 137:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallingMavenMavenisneitherapartoftheoperatingsystemnortheJDK.IthastobedownloadedandinstalledinaverysimilarwaytoAnt.YoucandownloadMavenfromitsofficialwebsite(https://maven.apache.org/)underthedownloadsection.Currently,thelateststableversionis3.3.9.Whenyoudownloadit,theactualreleasemaybedifferent;instead,usethelateststableversion.Youcandownloadthesourceortheprecompiledversion.Theeasiestwayistodownloadthebinaryintar.gzformat.

Icannotskipdrawingyourattentiontotheimportanceofcheckingthedownloadintegrityusingchecksums.IhavedetailedthewaytodoitinthesectionaboutAntinstallation.

Afterthefileisdownloaded,youcanexplodeittoasubdirectoryusingthefollowingcommand:

tarxfzapache-maven-3.3.9-bin.tar.gz

ThecreatedsubdirectoryistheusablebinarydistributionofMaven.Usually,Imoveitunder~/bin,makingitavailableonlyformyuseronOSX.Afterthat,youshouldaddthebindirectoryoftheinstallationtothePATH.Todothat,youshouldeditthe~/.bashrcfileandaddthefollowinglinestoit:

exportM2_HOME=~/bin/apache-maven-3.3.9/

exportPATH=${M2_HOME}bin:$PATH

Then,restarttheterminalapplication,orjusttype.~/.bashrcandtesttheinstallationofMaventyping,asfollows:

$mvn-v

ApacheMaven3.3.9(bb52d8502b132ec0a5a3f4c09453c07478323dc5;2015-11-10T17:41:47+01:00)

Mavenhome:/Users/verhasp/bin/apache-maven-3.3.9

Javaversion:9-ea,vendor:OracleCorporation

Javahome:/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home

Defaultlocale:en_US,platformencoding:UTF-8

OSname:"macosx",version:"10.11.6",arch:"x86_64",family:"mac"

YoushouldseeasimilarmessageonthescreenthatdisplaystheinstalledMavenversionandotherinformation.

Page 138:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 139:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

UsingMavenUnlikeAnt,Mavenhelpsyoucreatetheskeletonofanewproject.Todothat,youwillhavetotypethefollowingcommand:

$mvnarchetype:generate

Mavenwillfirstdownloadtheactuallyavailableprojecttypesfromthenetworkandpromptyoutoselecttheoneyouwanttouse.ThisapproachseemedtobeagoodideawhileMavenwasnew.WhenIfirststartedMaven,thenumberoflistedprojectswassomewherebetween10and20.Today,asIwritethisbook,itlists1,635differentarchetypes.Thisnumberseemsmorelikeahistoricaldate(theconstitutionoftheFrenchAcademyofScience)thanausablesizelistofdifferentarchetypes.However,donotfreakout.Mavenoffersadefaultvaluewhenitasksforyourchoice,anditisgoodfortheHelloWorldwegofor.

Chooseanumber:817:

Theactualnumbermaybedifferentonyourinstallation.Whateveritis,acceptthesuggestionandpressEnter.Afterthat,Mavenwillaskyoufortheversionoftheproject:

Chooseversion:

1:1.0-alpha-1

2:1.0-alpha-2

3:1.0-alpha-3

4:1.0-alpha-4

5:1.0

6:1.1

Chooseanumber:6:5

Selectthe1.0versionthatislistedasnumber5.ThenextthingMavenasksforisthegroupIDandtheartifactIDoftheproject.Thedependencymanagementthatwewilldiscusslaterusesthese.IselectedagroupIDbasedonthebookandthepublisher.TheartifactoftheprojectisSortTutorialaswewillstartourchapterexampleinthisproject.

Definevalueforproperty'groupId'::packt.java9.by.example

Definevalueforproperty'artifactId'::SortTutorial

Thenextquestionisthecurrentversionoftheproject.Wehavealreadyselected1.0andMavenoffers1.0-SNAPSHOT.Here,Iselected1.0.0-SNAPSHOTbecauseIprefersemanticversioning.

Definevalueforproperty'version':1.0-SNAPSHOT::1.0.0-SNAPSHOT

Semanticversioning,definedonhttp://semver.org/,isaversioningschemethatsuggeststhreedigitversionnumbersasM.m.p.forMajor,minor,andpatchversionnumbers.Thisisveryusefulforlibraries.Youwillincrementthelastversionnumberifthereisonlyabugfixsincethepreviousrelease.Youwillincrementtheminornumberwhenthenewreleasealsocontainsnewfeatures,butthelibraryiscompatiblewiththepreviousversion;inotherwords,anyprogramthatisusingtheolderversioncanstillusethenewerversion.Themajorreleasenumberisincreasedwhenthenewversionissignificantlydifferentfromthepreviousone.Inthecaseofapplicationprograms,thereisnocodethatusestheapplicationAPI;thus,theminorversionnumberisnotthatimportant.Itdoesnothurt,though,anditoften

Page 140:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

provestobeusefultosignalsmallerchangesintheapplication.Wewilldiscusshowtoversionsoftwareinthelastchapter.

Mavenhandlestheversionsthathavethe-SNAPSHOTpostfixasnon-releaseversions.Whilewedevelopthecode,wewillhavemanyversionsofourcode,allhavingthesamesnapshotversionnumber.Ontheotherhand,non-snapshotversionnumberscanonlybeusedonlyforasingleversion.

Definevalueforproperty'package':packt.java9.by.example::

ThelastquestionfromtheprogramskeletongenerationisthenameoftheJavapackage.ThedefaultisthevaluewegaveforgroupId,andwewillusethis.Itisarareexceptiontousesomethingelse.

Whenwehavespecifiedalltheparametersthatareneeded,thefinalrequestistoconfirmthesetting:

Confirmpropertiesconfiguration:

groupId:packt.java9.by.example

artifactId:SortTutorial

version:1.0.0-SNAPSHOT

package:packt.java9.by.example

Y::Y

AfterenteringY,Mavenwillgeneratethefilesthatareneededfortheprojectanddisplaythereportaboutthis:

[INFO]-----------------------------------------------------------

[INFO]UsingfollowingparametersforcreatingprojectfromOld(1.x)Archetype:maven-archetype-quickstart:1.0

[INFO]-----------------------------------------------------------

[INFO]Parameter:basedir,Value:.../mavenHelloWorld

[INFO]Parameter:package,Value:packt.java9.by.example

[INFO]Parameter:groupId,Value:packt.java9.by.example

[INFO]Parameter:artifactId,Value:SortTutorial

[INFO]Parameter:packageName,Value:packt.java9.by.example

[INFO]Parameter:version,Value:1.0.0-SNAPSHOT

[INFO]***EndofdebuginfofromresourcesfromgeneratedPOM***

[INFO]projectcreatedfromOld(1.x)Archetypeindir:.../mavenHelloWorld/SortTutorial

[INFO]-----------------------------------------------------------

[INFO]BUILDSUCCESS

[INFO]-----------------------------------------------------------

[INFO]Totaltime:01:27min

[INFO]Finishedat:2016-07-24T14:22:36+02:00

[INFO]FinalMemory:11M/153M

[INFO]-----------------------------------------------------------

Youcantakelookatthefollowinggenerateddirectorystructure:

Youcanalsoseethatitgeneratedthefollowingthreefiles:

SortTutorial/pom.xmlthatcontainstheProjectObjectModel

Page 141:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SortTutorial/src/main/java/packt/java9/by/example/App.javathatcontainsaHelloWorldsampleapplicationSortTutorial/src/test/java/packt/java9/by/example/AppTest.javathatcontainsaunittestskeletonutilizingthejunit4library

Wewilldiscussunittestsinthenextchapter.Fornow,wewillfocusonthesortingapplication.AsMavenwassokindandgeneratedasampleclassfortheapp,wecancompileandrunitwithoutactualcoding,justtoseehowwecanbuildtheprojectusingMaven.ChangethedefaultdirectorytoSortTutorialissuingcdSortTutorialandissuethefollowingcommand:

$mvnpackage

Wewillgetthefollowingoutput:

Mavenfiresup,compiles,andpackagestheprojectautomatically.Ifnot,pleasereadthenextinfobox.

WhenyoufirststartMaven,itdownloadsalotofdependenciesfromthecentralrepository.Thesedownloadstaketime,andarereportedonthescreen,sotheactualoutputmaybedifferentfromwhatyousawintheprecedingcode.MavencompilescodewiththedefaultsettingsforJavaversion1.5.Itmeansthatthe

Page 142:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

generatedclassfileiscompatiblewithJavaversion1.5,andalsothatthecompileronlyacceptslanguageconstructsthatwereavailablealreadyinJava1.5.Ifwewanttousenewerlanguagefeatures,andinthisbookweusealot,thepom.xmlfileshouldbeeditedtocontainthefollowinglines:

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<configuration>

<source>1.9</source>

<target>1.9</target>

</configuration>

</plugin>

</plugins>

</build>

WhenusingJava9'sdefaultsettingsforMaven,itbecomesevenmorecomplex,becauseJava9doesnotgenerateclassformatnorrestrictsourcecompatibilityearlierthanJava1.6.Atthisverymoment,asIwritetheselines,thelatestMavenreleaseis3.3.9.WhenItrytocompiletheprecedingcodewithoutthemodifications,theJavacompilerstopswithanerrordisplayingthefollowing:[ERROR]Sourceoption1.5isnolongersupported.Use1.6orlater.

[ERROR]Targetoption1.5isnolongersupported.Use1.6orlater.Later,Mavenreleasesmaybehavedifferentlyinthefuture.

Now,youcanstartthecodeusingthefollowingcommand:

$java-cptarget/SortTutorial-1.0.0-SNAPSHOT.jarpackt.java9.by.example.App

Youcanseetheresultofasampleruninthefollowingpicture:

Page 143:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 144:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 145:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GradleAntandMavenaretwoworlds,andusingoneortheothermayleadtoheateddebatesonInternetforums.Antgivesfreedomtodeveloperstocreateabuildprocessthatfitstheirtaste.Mavenrestrictstheteamtouseabuildprocessthatismorestandard.Somespecialprocessesthatdonotmatchanystandardbuild,butwhicharesometimesneededinsomeenvironments,arehardtoimplementusingMaven.InAnt,youcanscriptalmostanythingusingthebuilt-intasks,almostthesamewayasyoucanprogrambash.UtilizingMavenisnotthatsimple,and,itoftenrequireswritingaplugin.Eventhoughwritingapluginisnotrocketscience,developersusuallyliketohavethepossibilityofmakingthingsinasimplerway:Scripting.Wehavetwoapproaches,twomindsetsandstyles,andnotasingletooltofulfillalltheneeds.NosurprisethatbytheJavatechnologiesweredeveloped,anewbuildtoolwasemerging.

Gradletriestousethebestofbothworlds,utilizingtechniquesthatwerenotavailablebythetimeMavenandAntwerefirstdeveloped.

Gradlehasbuilt-intargetsandlifecycle,butatthesametime,youcanalsowriteyourowntargets.Youcanconfigureaproject,justlikeusingMaven,withoutscriptingthetaskstodoso,butatthesametime,youcanalsoscriptyourowntargetjustlikeinAnt.Whatismore,GradleintegratedAnt,soanytaskimplementedforAntisavailableforGradleaswell.

MavenandAntuseXMLfilestodescribethebuild.Today,XMLisatechnologyofthepast.Westilluseit,andadevelopershouldbefluentinhandling,reading,andwritingXMLfiles,butamoderntooldoesnotuseXMLforconfiguration.New,fancyformatssuchasJSONaremorepopular.Gradleisnoexception.TheconfigurationfileofGradleusesadomain-specificlanguage(DSL)basedonGroovy.Thislanguageismorereadableforprogrammersandgivesmorefreedomtoprogrambuildprocesses.And,thisisalsothedangerofGradle.

HavingthepowerfulJVMlanguageGroovyinthehandsofdeveloperstocreatebuildtoolsgivesafreedomandtemptationtocreatecomplexbuildprocessesthatseemtobeagoodideaatthestart,butlatermayprovetobejusttoocomplexandhard,and,therefore,expensivetomaintain.ThisisexactlywhyMavenwasimplementedinthefirstplace.

Ihavetostopbeforegettingintoanotherareathatisthegroundforheatedandpointlessdebates.Gradleisanextremelypowerfulbuildtool.Youshoulduseitcarefully,justlikeyouwoulduseaweapon—don'tshootyourlegs.

Page 146:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 147:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InstallingGradleToinstallGradle,youwillhavetodownloadthecompiledbinariesfromthehttps://gradle.org/gradle-download/website.

Again,I'dliketoemphasizetheimportanceofcheckingthedownloadintegrityusingchecksums.IhavegivenadetailedwaytodoitinthesectionaboutAntinstallation.Unfortunately,theGradlewebsitedoesnotprovidethechecksumvaluesforthedownloadablefiles.

GradleisdownloadableintheZIPformat.Tounpackthefile,youwillhavetousetheunzipcommand:

$unzipgradle-3.3-bin.zip

ThecreatedsubdirectoryistheusablebinarydistributionofGradle.Usually,Imoveitunder~/bin,makingitavailableonlyformyuseronOSX.Afterthat,youshouldaddthebindirectoryoftheinstallationtothePATH.Todothat,youshouldeditthe~/.bashrcfileandaddthefollowinglines:

exportGRADLE_HOME=~/bin/gradle-3.3/

exportPATH=${GRADLE_HOME}bin:$PATH

Then,restarttheterminalapplication,orjusttype.~/.bashrcandtesttheinstallationofGradle,typingthefollowing:

$gradle-version

Wegettothefollowingoutput,ascanbeseeninthisscreenshot:

Page 148:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 149:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SettinguptheprojectwithMavenTostarttheproject,wewillusethedirectorystructureandpom.xmlthatwascreatedbyMavenitselfwhenwestartedwiththefollowingcommandline:$mvnarchetype:generate

Itcreatedthedirectories,thepom.xmlfile,andanApp.javafile.Now,wewillextendthisprojectbycreatingnewfiles.Wewillcodethesortingalgorithmfirstinthepackt.java9.by.example.stringsortpackage:

WhenwecreatethenewpackageintheIDE,theeditorwillautomaticallycreatethestringsortsubdirectoryunderthealreadyexistingsrc/main/java/packt/java9/by/exampledirectory:

CreatingthenewSortclassusingtheIDEwillalsoautomaticallycreateanewfilenamedSort.javainthisdirectory,anditwillfillintheskeletonoftheclass:packagepackt.java9.by.example.stringsort;

publicclassSort{}

WewillnowhaveApp.javacontainingthefollowingcode:

packagepackt.java9.by.example;

publicclassApp

{

publicstaticvoidmain(String[]args)

{

System.out.println("HelloWorld!");

}

}

Mavencreateditasastartingversion.Wewilleditthisfiletoprovideasamplelistthatthesortingalgorithmcansort.IrecommendthatyouusetheIDEtoeditthefileandalsotocompileandrunthecode.TheIDEprovidesashortcutmenutostartthecodeandthisisabiteasierthantypingthecommandinTerminal.Generally,itisrecommendedthatyougetacquaintedwiththeIDEfeaturestosavetimeavoidingrepetitivetasks,suchastypingterminalcommands.Professionaldevelopersusethecommandlinealmostexclusivelytotestcommand-linefeaturesandusetheIDEwheneveritispossible.

Page 150:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 151:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 152:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CodingthesortMavenandtheIDEcreatedthefilesforthesortprogram.Theyformtheskeletonforourcode,andnowitistimetogrowsomemusclesonthemtoletitmove.Wespentquitesometimetosetuptheprojectbyvisitingthedifferentbuildtools,onlytolearnhowtocompilethecode.Ihopethatthisdidnotdistractyoumuch,butanyhow,wedeservetoseesomerealcode.

First,wewillcreatethecodeforthesortingcode,andafterthat,thecodethatinvokesthesorting.Thecodethatinvokesthesortingisakindoftestingcode.Forsimplicity,wewillnowsimplyuseapublicstaticvoidmainmethodtostartthecode.Wewillusethetestframeworkinlaterchapters.

Asfornow,thecodeforthesortingwilllooklikethis:

packagepackt.java9.by.example.stringsort;

publicclassSort{

publicvoidsort(String[]names){

intn=names.length;

while(n>1){

for(intj=0;j<n-1;j++){

if(names[j].compareTo(names[j+1])>0){

finalStringtmp=names[j+1];

names[j+1]=names[j];

names[j]=tmp;

}

}

n--;

}

}

}

Thisistheclassthatdoesthesorting.Thereisonlyonemethodinthisclassthatdoesthesorting.Theargumenttothemethodisanarraycontainingthestrings,andthemethodsortsthisarray.Themethodhasnoreturnvalue.Thisisdenotedinthedeclarationusingthepseudotypevoid.Methodsusetheirargumentstoperformsometasks,andmayreturnonevalue.Theargumentstothemethodarepassedbyvalue,whichmeansthatthemethodcannotmodifythevariablepassedasargument.However,itcanmodifytheobjectstheargumentscontain.Inthiscase,thearrayismodifiedandwewillsortit.Ontheotherhand,theactualNamesvariablewillpointtothesamearrayandthesortmethodcannotdoanythingtomakethisvariablepointtoadifferentarray.

Thereisnomainmethodinthisclass,whichmeansthatitcannotbestartedfromthecommandlineonitsown.Thisclasscanonlybeusedfromsomeotherclass,aseveryJavaprogramshouldhaveaclassthathasapublicstaticvoidmainmethodthatwecreatedseparately.

Icouldalsoputamainmethodintotheclasstomakeitexecutable,butthatisnotagoodpractice.Realprogramsarecomposedofmanyclasses,andoneclassshouldnotdomanythings.Rather,it'stheopposite.Thesingleresponsibilityprinciplesaysthatasingleclassshouldberesponsibleforonesinglething;therefore,classsortdoesthesorting.Executingtheapplicationisadifferenttask,andthusithastobeimplementedinadifferentclass.

Often,wedonotimplementtheclasscontainingthemainmethod.Often,aframeworkprovidesit.For

Page 153:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

example,writingaservletthatrunsinaservletcontainerrequirescontainingaclassthatimplementsthejavax.servlet.Servletinterface.Inthiscase,theprogramseeminglydoesnothaveamainmethod.Theactualimplementationoftheservletcontainerdoes.TheJavacommandlinestartsthecontainerandthecontainerloadstheservletswhentheyareneeded.

Inthefollowingexamplecode,weimplementedtheAppclasscontainingthemainmethod:

packagepackt.java9.by.example;

importpackt.java9.by.example.stringsort.Sort;

publicclassApp{

publicstaticvoidmain(String[]args){

String[]actualNames=newString[]{

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

};

finalSortsorter=newSort();

sorter.sort(actualNames);

for(finalStringname:actualNames){

System.out.println(name);

}

}

}

Thiscodecontainsastringarrayinitializedtocontainconstantvalues,createsanewinstanceoftheSortclass,invokesthesortmethod,andthenprintsoutthecodetothestandardoutput.

Inrealprograms,wealmostneverhavesuchconstantsinprogramcodes;weputthemintoresourcefilesandhavesomecodetoreadtheactualvalues.Thisseparatesthecodefromdataandeasesmaintenance,eliminatingtheriskofaccidentalmodificationofcodestructurewhenonlythedataistobechanged.Similarly,wewillalmostneverwriteanythingtostandardoutputusingSystem.out.Usually,wewilluseloggingpossibilitiesthatareavailablefromdifferentsources.TherearedifferentlibrariesthatprovideloggingfunctionalitiesandloggingisalsoavailablefromtheJDKitself.

Asfornow,wewillfocusonsimplesolutionssoastonotdistractyourfocusfromJavabytheplethoraofdifferentlibrariesandtools.Inthefollowingsection,wewilllookattheJavalanguageconstructsthatweusedtocodethealgorithm.First,wewilllookatthemgenerally,andthen,inabitmoredetail.Theselanguagefeaturesarenotindependentofeachother:onebuildsupontheother,andtherefore,theexplanationwillfirstbegeneral,andwewillgointodetailsinthesubsections.

Page 154:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

intn=names.length;<br/>while(n>1){<br/>for(intj=0;j<n-1;j++){<br/>if(names[j].compareTo(names[j+1])>0){<br/>finalStringtmp=names[j+1];<br/>names[j+1]=names[j];<br/>names[j]=tmp;<br/>}<br/>}<br/>n--;<br/>}

Thenvariableholdsthelengthofthearrayatthestartofthesorting.ArraysinJavaalwayshaveapropertythatgivesthelengthanditiscalledlength.Whenwestartthesorting,wewillgofromthestartofthearraytotheendofitand,asyoumayrecall,thelastelement,Wilson,willwalkuptothelastpositionduringthisfirstiteration.Subsequentiterationswillbeshorterand,therefore,thevariablenwillbedecreased.

Page 155:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 156:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Blocks

ThecodeinJavaiscreatedincodeblocks.Anythingthatisbetweenthe{and}charactersisablock.Intheprecedingexample,thecodeofthemethodisablock.Itcontainscommands,andsomeofthem,likethewhileloop,alsocontainablock.Insidethatblock,therearetwocommands.Oneofthemisaforloop,againwithablock.Althoughwecanhavesingleexpressionstoformthebodyofaloop,weusuallyuseblocks.Wewilldiscussloopsindetailinjustafewpages.

Aswecouldseeintheprecedingexample,theloopscanbenested,andthusthe{and}charactersformpairs.Ablockcanbeinsideanotherblock,buttwoblockscannotoverlap.Whenthecodecontainsa}character,itisclosingtheblockthatwasopenedlast.

Page 157:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 158:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Variables

InJava,justlikeinalmostanyprogramminglanguage,weusevariables.ThevariablesinJavaaretyped.Itmeansthatavariablecanholdavalueofasingletype.ItisnotpossibleforavariabletoholdaninttypeatsomepointintheprogramandlateraStringtype.Whenvariablesaredeclared,theirtypeiswritteninfrontofthevariablename.

Variablesalsohavevisibilityscope.Localvariablesinmethodscanonlybeusedinsidetheblockinwhichtheyaredefined.Avariablecanbeusedinsidemethodsortheycanbelongtoaclassoranobject.Todifferentiatethetwo,weusuallycallthesevariablesfields.

Page 159:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 160:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TypesEachvariablehasonetype.InJava,therearetwomajorgroupsoftype:primitiveandreferencetypes.Theprimitivetypesarepredefined,andyoucannotdefineorcreateanewprimitivetype.Thereareeightprimitivetypes:byte,short,int,long,float,double,boolean,andchar.

Thefirstfourtypes,byte,short,int,andlong,aresignednumericintegertypes,capableofstoringpositiveandnegativenumberson8,16,32,and64bits.

Thefloatanddoubletypesstorefloatingpointnumberson32and64bitsintheIEEE754floating-pointformat.

Thebooleantypeisaprimitivetypethatcanonlybetrueorfalse.

Thechartypeisacharacterdatatypethatstoresasingle16-bitUnicodecharacter.

Foreachprimitivetype,thereisaclassthatcanstorethesametypeofvalue.Whenaprimitivetypehastobeconvertedtothematchingclasstypeitisdoneautomatically.Itiscalledautoboxing.ThesetypesareByte,Short,Integer,Long,Float,Double,Boolean,andCharacter.Take,forexample,thefollowingvariabledeclaration:

Integera=113;

Thisconvertsthevalue113,whichisanintnumber,toanIntegerobject.

Thesetypesarepartoftheruntime,andalsopartofthelanguage.Althoughthereisnoprimitivecounterpartofit,thereisaveryimportantandubiquitousclassthatwehavealreadyused:String.Astringcontainscharacters.

Themajordifferencesbetweenprimitivetypesandobjectsarethatprimitivetypescannotbeusedtoinvokemethods,buttheyconsumelessmemory.Thedifferencebetweenthememoryconsumptionanditsconsequencesforspeedisimportantinthecaseofarrays.

Page 161:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 162:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ArraysVariablescanbeaprimitivetypeaccordingtotheirdeclaration,ortheymayholdareferencetoanobject.Aspecialobjecttypeisanarray.Whenavariableholdsareferencetoanarray,thenitcanbeindexedwiththe[and]characters,alongwithanintegralvalueconsistingof0orapositivevaluerangingtoonelessthanthearray'slength,toaccessacertainelementofthearray.Multi-dimensionalarraysarealsosupportedbyJavawhenanarrayhaselementsthatarealsoarrays.ArraysareindexedfromzeroinJava.Underoroverindexingischeckedatruntime,andtheresultisanexception.

Anexceptionisspecialconditionthatinterruptsthenormalexecutionflowandstopstheexecutionofthecodeorjumpstotheclosestenclosingcatchstatement.Wewilldiscussexceptionsandhowtohandletheminthenextchapter.

Whenacodehasanarrayofaprimitivetype,thearraycontainsmanymemoryslots,eachholdingthevalueofthetype.Whenthearrayhasareferencetype,inotherwords,whenitisanarrayofobjects,thenthearrayelementsarereferencestoobjects,eachcontainingthetype.Inthecaseofintforexample,eachelementofthearrayis32-bit,whichis4bytes.IfthearrayisatypeofInteger,thentheelementsarereferencestoobjects,pointers,sotosay,whichisusually64-bitusing64-bitJVMand32-biton32-bitJVM.Inadditiontothat,thereisanIntegerobjectsomewhereinmemorythatcontainsthe4-bytevalueandalsoanobjectheaderthatmaybeasmuchas24bytes.

Theactualsizeoftheextrainformationneededtoadministereachobjectisnotdefinedinthestandard.ItmaybedifferentondifferentimplementationsoftheJVM.Theactualcoding,oreventheoptimizationofthecodeinanenvironment,shouldnotdependontheactualsize.However,thedevelopersshouldbeawarethatthisoverheadexistsandisintherangeofaround20orsobytesforeveryobject.Objectsareexpensiveintermsofmemoryconsumption.

Memoryconsumptionisoneissue,butthereissomethingelse.Whentheprogramworkswithalargeamountofdataandtheworkneedstheconsecutiveelementsofthearray,thentheCPUloadsachunkofmemoryintotheprocessorcache.ItmeansthattheCPUcanaccesselementsofthearraythatareconsecutivelyfaster.Ifthearrayisofaprimitivetype,itisfast.Ifthearrayisofsomeclasstype,thentheCPUhastoaccessmemorytogettheactualvalue,whichmaybeasmuchas50timesslower.

Page 163:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 164:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ExpressionsExpressionsinJavaareverymuchlikeinotherprogramminglanguages.YoucanusetheoperatorsthatmaybesimilarfromlanguagessuchasCorC++.Theyareasfollows:

Unaryprefixandpostfixincrementoperators(--and++beforeandafteravariable)Unarysign(+and-)operatorsLogical(!)andbitwise(~)negationMultiplication(*),division(/),andmodulo(%)Additionandsubtraction(+and-again,butthistimeasbinaryoperators)Shiftoperatorsmovethevaluesbitwise,andthereisleft(<<)andright(>>)shiftandunsignedrightshift(>>>)Thecomparingoperatorsare<,>,<=,>=,==,!=andinstanceofthatresultinbooleanvalueTherearebitwiseor(|),and(&),exclusiveor(^)operators,andsimilarlylogicalor(||),and(&&)operators

Whenlogicaloperatorsareevaluated,theyareshortcutevaluated.Itmeanstheright-handoperandisevaluatedonlyiftheresultcannotbeidentifiedfromtheresultoftheleftoperand.

Theternaryoperatorisalsosimilartotheone,likeitisonC,selectingfromoneoftheexpressionsbasedonsomecondition:condition?expression1:expression2.Usually,thereisnoproblemwiththeternaryoperator,butsometimesyouhavetobecarefulasthereisacomplexrulecontrollingthetypeconversionsincasethetwoexpressionsarenotofthesametype.It'salwaysbettertohavethetwoexpressionsbeofthesametype.

Finally,thereisanassignmentoperator(=)thatassignsthevalueofanexpressiontoavariable.Foreachbinaryoperator,thereisanassignmentversionthatcombines=withabinaryoperatortoperformanoperationinvolvingtherightoperandandassigntheresulttotheleftoperand,whichmustbeavariable.Theseare+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>=,and>>>=.

Theoperatorshaveprecedenceandcanbeoverriddenbyparentheses,asusual.

Animportantpartofexpressionsisinvokingmethods.Staticmethodscanbeinvokedbythenameoftheclassandthenameofthemethod.Forexample,tocalculatethesineof1.22,wecanwritethefollowingline:

doublez=Math.sin(1.22);

Here,Mathistheclassfromthepackagejava.lang.ThemethodsinisinvokedwithoutusinganyinstanceofMath.Thismethodisstatic,anditisnotlikelythatwewilleverneedanyotherimplementationofitthantheoneprovidedintheclassMath.

Non-staticmethodscanbeinvokedusinganinstanceandthenameofthemethodwithadotseparatingthetwo.Forexample,takethefollowingcodelineasanexample:

System.out.println("HelloWorld");

Page 165:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheprecedingcodeusesaninstanceoftheclassPrintStreamthatisreadilyavailablethroughastaticfieldintheclassSystem.Thisvariableiscalledout,andwhenwewriteourcode,wehavetoreferenceitasSystem.out.ThemethodprintlnisdefinedintheclassPrintStreamandweinvokeitontheobjectreferencedbythevariableout.Thisexamplealsoshowsthatstaticfieldscanalsobereferencedthroughthenameoftheclassandthefieldseparatedbyadot.Similarly,whenweneedtoreferenceanon-staticfield,wecandoitthroughaninstanceoftheclass.

Staticmethodsdefinedinthesameclassfromwhereitisinvokedorinheritedcanbeinvokedwithouttheclassname.Invokinganon-staticmethoddefinedinthesameclassorbeinginheritedcanbeinvokedwithoutaninstance.Inthiscase,theinstanceisthecurrentobjecttheexecutionisin.Thisobjectisalsoavailablethroughthethiskeyword.Similarly,whenweuseafieldofthesameclasswhereourcodeis,wesimplyusethename.Incaseofastaticfield,theclassweareinbydefault.Inthecaseofanon-staticfield,theinstanceistheobjectreferencedbythethiskeyword.

Youcanalsoimportastaticmethodintoyourcodeusingtheimportstaticlanguagefeature,inwhichcaseyoucaninvokethemethodwithoutthenameoftheclass.

Theargumentsofthemethodcallsareseparatedusingcommas.Methodsandmethodargumentpassingisanimportanttopicthatwewillmentionindetailinaseparatesubsection.

Page 166:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 167:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LoopsTheforloopinsidethewhileloopwillgothroughalltheelementsfromthefirst(indexedwithzeroinJava)uptillthelast(indexedwithn-1).Generally,theforloophasthesamesyntaxasinC:

for(initialexpression;condition;incrementexpression)

block

First,theinitialexpressionisevaluated.Itmaycontainvariabledeclaration,asinourexample.Thevariablejintheprecedingexampleisvisibleonlyinsidetheblockoftheloop.Afterthis,theconditionisevaluated,andaftereachexecutionoftheblock,theincrementexpressionisexecuted.Thelooprepeatssolongastheconditionistrue.Iftheconditionisfalserightaftertheexecutionoftheinitialexpression,theloopdoesnotexecuteatall.Theblockisalistofcommandsseparatedbysemicolonsandenclosedbetweenthe{and}characters.

Insteadof{and},enclosedblockJavaletsyouuseasinglecommandfollowingtheheadoftheforloop.Thesameistrueinthecaseofthewhileloop,andalsofortheif...elseconstructs.Practiceshowsthatthisisnotsomethingaprofessionalshoulduse.Professionalcodealwaysusescurlybraces,evenwhenthereisonlyasinglecommandwheretheblockisinplace.Thispreventsthedanglingelseproblemandgenerallymakesthecodemorereadable.ThisissimilartomanyC-likelanguages.Mostofthemallowasinglecommandattheseplaces,andprofessionalprogrammersavoidusingasinglecommandintheselanguagesforreadabilitypurposes.Itisironicthattheonlylanguagethatstrictlyrequirestheuseofthe{and}bracesattheseplacesisPerl—theonelanguageinfamousforunreadablecode.

Theloopinthefor(intj=0;j<n-1;j++){samplestartsfromzeroandgoeston-2.Writingj<n-1isthesame,inthiscase,asj<=n-2.Wewilllimitjtostopintheloopbeforetheendofthesectionofthearray,becausewereachbeyondtheindexjbyonecomparingandconditionallyswappingtheelementsindexedbyjandj+1.Ifwewentoneelementfurther,wewouldtrytoaccessanelementofthearraythatdoesnotexist,anditwouldcausearuntimeexception.Tryandmodifytheloopconditiontoj<norj<=n-1andyouwillgetthefollowingerrormessage:

Page 168:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 169:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ItisanimportantfeatureofJavathattheruntimechecksmemoryaccessandthrowsanexceptioninthecaseofbadarrayindexing.Inthegoodolddays,whilecodinginC,often,wefacedunexplainableerrorsthatstoppedourcodemuchlaterandattotallydifferentcodelocationsfromwheretherealerrorwas.ArrayindexinCsilentlycorruptedthememory.Javastopsyouassoonasyoumakeamistake.Itfollowsthefail-fastapproachthatyoualsoshoulduseinyourcode.Ifsomethingiswrong,theprogramshouldfail.Nocodeshouldtrytolivewithorovercomeanerrorthatcomesfromacodingerror.Codingerrorsshouldbefixedbeforetheycauseevenmoredamage.

TherearealsotwomoreloopconstructsinJava:thewhileloopandthedoloop.Theexamplecontainsawhileloop:itistheouterloopthatrunssolongasthereareatleasttwoelementsthatmayneedswappinginthearray:

while(n>1){

Thegeneralsyntaxandsemanticsofthewhileloopisverysimple,asseenhere:

while(condition)block

Repeattheexecutionoftheblocksolongastheconditionistrue.Iftheconditionisnottrueattheverystartoftheloop,thendonotexecutetheblockatall.Thedoloopisalsosimilar,butitcheckstheconditionaftereachexecutionoftheblock:

doblockwhile(condition);

Forsomereason,programmersrarelyusedoloops.

Page 170:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 171:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ConditionalexecutionTheheartofthesortistheconditionandthevalueswappinginsidetheloop.

if(names[j].compareTo(names[j+1])>0){

finalStringtmp=names[j+1];

names[j+1]=names[j];

names[j]=tmp;

}

ThereisonlyoneconditionalcommandinJava,theifcommand.Ithasthefollowingformat:

if(condition)blockelseblock

Themeaningofthecodestructureisquitestraightforward.Iftheconditionistrue,thenthefirstblockisexecuted,otherwise,thesecondblockisexecuted.Theelsekeyword,alongwiththesecondblock,isoptional.Ifthereisnothingtobeexecutedincasethattheconditionisfalse,thenthereisnoneedfortheelsebranch,justlikeintheexample.Ifthearrayelementindexedwithjislaterinthesortorderthantheelementj+1,thenweswapthem,butiftheyarealreadyinorder,thereisnothingtodowiththem.

Toswapthetwoarrayelements,wewilluseatemporaryvariablenamedtmp.ThetypeofthisvariableisString,andthisvariableisdeclaredtobefinal.ThefinalkeywordhasdifferentmeaningsdependingonwhereitisusedinJava.Thismaybeconfusingforbeginnersunlessyouarewarnedaboutit,justlikenow.Afinalclassormethodisatotallydifferentthingthanafinalfield,whichisagaindifferentthanafinallocalvariable.

Page 172:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 173:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

FinalvariablesInourcase,tmpisafinallocalvariable.Thescopeofthisvariableislimitedtotheblockfollowingtheifstatement,andinsidethisblock,thisvariablegetsavalueonlyonce.Theblockisexecutedmanytimesduringthecodeexecution,andeachtimethevariablegetsintoscope,itgetsavalue.However,thisvaluecannotbechangedintheblock.Thismaybeabitconfusing.Youcanthinkaboutitashavinganewtmpeachtimetheblockexecutes.Thevariablegetsdeclaredandhasanundefinedvalueandcangetavalueonlyonce.

Finallocalvariablesdonotneedtogetthevaluewheretheyaredeclared.Youcanassignavaluetoafinalvariablesometimelater.Itisimportantthatthereshouldnotbeacodeexecutionthatassignsavaluetoafinalvariablethatwasalreadyassignedavaluebefore.Thecompilerchecksitanddoesnotcompilethecodeifthereisapossibilityofthereassignmentofafinalvariable.

Todeclareavariabletobefinalisgenerallytoeasereadabilityofthecode.Whenyouseeavariableinacodedeclaredtobefinal,youcanassumethatthevalueofthevariablewillnotchangeandthemeaningofthevariablewillalwaysbethesamewhereveritwasusedinthemethod.ItwillalsohelpyouavoidsomebugswhenyoutrytomodifysomefinalvariablesandtheIDEwillimmediatelycomplainaboutit.Insuchsituations,itislikelytobeaprogrammingmistakethatisdiscoveredextremelyearly.

Inprinciple,itispossibletowriteaprogramwhereallvariablesarefinal.Itisgenerallyagoodpracticetodeclareallfinalvariablesthatcanbedeclaredtobefinaland,incasesomevariablemaynotbedeclaredfinal,thentrytofindsomewayofcodingthemethodabitdifferently.

Ifyouneedtointroduceanewvariabletodothat,itprobablymeansyouwereusingonevariabletostoretwodifferentthings.Thesethingsareofthesametypeandstoredinthesamevariableatdifferenttimesbut,logically,theystillaredifferentthings.Donottrytooptimizetheuseofvariables.Neveruseavariablebecauseyoualreadyhaveavariableofthetypeinyourcodethatisavailable.Ifitislogicallyadifferentthing,thendeclareanewvariable.Whilecoding,alwaysprefersourcecodeclarityandreadability.InJava,especially,theJustInTimecompilerwilloptimizeallthisforyou.

Althoughwedonotexplicitlytendtousethefinalkeywordontheargumentlistofamethod,itisgoodpracticetomakesurethatyourmethodscompileandworkiftheargumentsaredeclaredfinal.Someexperts,includingme,believethatthemethodparametersshouldhavebeenmadefinalbydefaultinthelanguage.ThisissomethingthatwillnothappeninanyversionofJava,solongasJavafollowsthebackwardcompatibilityphilosophy.

Page 174:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 175:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ClassesNowthatwehavelookedattheactualcodelinesandhaveunderstoodhowthealgorithmworks,let'slookatthemoreglobalstructuresofthecodethatbringsittogether:classesandpackagesenclosingthemethods.

EveryfileinaJavaprogramdefinesaclass.AnycodeinaJavaprogramisinsideaclass.ThereisnothinglikeglobalvariablesorglobalfunctionsasinC,Python,Go,orotherlanguages.Javaistotallyobjectoriented.

Therecanbemorethanoneclassinasinglefile,butusuallyonefileisoneclass.Later,wewillseethatthereareinnerclasseswhenaclassisinsideanotherclass,but,fornow,wewillputoneclassintoonefile.

TherearesomefeaturesintheJavalanguagethatwedonotuse.Whenthelanguagewascreated,thesefeaturesseemedtobeagoodidea.CPU,memory,andotherresources,includingmediocredevelopers,werealsomorelimitedthantoday.Someofthefeatures,perhaps,mademoresensebecauseoftheseenvironmentalconstraints.Sometimes,Iwillmentionthese.Inthecaseofclasses,youcanputmorethanoneclassintoasinglefilesolongasonlyoneispublic.Thatisbadpractice,andwewillneverdothat.Javaneverobsoletesthesefeatures.ItisaphilosophyofJavatoremaincompatiblewithallpreviousversions.Thisphilosophyisgoodforthealreadywritten,hugeamountoflegacycode.Javacodewrittenandtestedwithanoldversionwillworkinanewerenvironment.Atthesametime,thosefeatureslurebeginnerstoawrongstyle.Forthisreason,sometimes,Iwillnotevenmentionthesefeatures.Forexample,here,Icouldsay:Thereisoneclassinafile.Thiswouldnotbeabsolutelycorrect.Atthesametime,itismoreorlesspointlesstoexplainingreatdetailafeaturethatIrecommendnottobeused.Later,Imaysimplyskipthemand"lie".Therearenottoomanyofthosefeatures.

Aclassisdefinedusingtheclasskeywordandeachclasshastohaveaname.Thenameshouldbeuniquewithinthepackage(seethenextsection)andhastobethesameasthenameofthefile.Aclasscanimplementaninterfaceorextendanotherclass,forwhichwewillseeanexamplelater.Aclasscanalsobeabstract,final,andpublic.Thesearedefinedwiththeappropriatekeywords,asyouwillseeinexamples.

Ourprogramhastwoclasses.Bothofthemarepublic.Thepublicclassesareaccessiblefromanywhere.Classesthatarenotpublicarevisibleonlyinsidethepackage.Innerandnestedclassescanalsobeprivatevisibleonlyinsidethetop-levelclassdefinedonthefilelevel.

ClassesthatcontainamainmethodtobeinvokedbytheJavaenvironmentshouldbepublic.ThatisbecausetheyareinvokedbytheJVM.

Theclassstartsatthebeginningofthefilerightafterthepackagedeclarationandeverythingbetweenthe{and}charactersbelongtotheclass.Themethods,fields,innerornestedclasses,andsoonarepartoftheclass.Generally,curlybracesdenotesomeblockinJava.ThiswasinventedintheClanguage,andmany

Page 176:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

languagesfollowthisnotation.Classdeclarationissomeblock,methodsaredefinedusingsomeblock,loops,andconditionalcommandsuseblocks.

Whenweusetheclasses,wewillhavetocreateinstancesofclasses.Theseinstancesareobjects.Inotherwords,objectsarecreatedinstantiatingaclass.Todothat,thenewkeywordisusedinJava.WhenthelinefinalSortsorter=newSort();isexecutedintheAppclass,itcreatesanewobjectinstantiatingtheSortclass.WewillalsosaythatwecreatedanewSortobjectorthatthetypeoftheobjectisSort.Whenanewobjectiscreated,aconstructoroftheobjectisinvoked.Abitsloppy,Imaysay,thattheconstructorisaspecialmethodintheclassthathasthesamenameastheclassitselfandhasnoreturnvalue.Thatisbecauseitreturnsthecreatedobject.Tobeprecise,constructorsarenotmethods.Theyareinitializersandtheydonotreturnthenewobject.Theyworkonthenot-ready-yetobject.Whenaconstructorexecutingtheobjectisnotfullyinitialized,someofthefinalfieldsmaynotbeinitializedandtheoverallinitializationstillcanfailiftheconstructorthrowsanexception.Inourexample,wedonothaveanyconstructorinthecode.Insuchacase,Javacreatesadefaultconstructorthatacceptsnoargumentanddoesnotmodifythealreadyallocatedbutuninitializedobject.IftheJavacodedefinesaninitializer,thentheJavacompilerdoesnotcreateadefaultone.

Aclasscanhavemanyconstructors,eachhavingdifferentparameterlist.

InadditiontoconstructorsJavaclassescancontaininitializerblocks.Theyareblocksontheclasslevel,thesamelevelastheconstructorandmethods.Thecodeintheseblocksiscompiledintotheconstructorsandisexecutedwhentheconstructorisexecuting.

Itisalsopossibletoinitializestaticfieldsinstaticinitializerblocks.Thesearetheblocksonthetoplevelinsidetheclasswiththestatickeywordinfrontofthem.Theyareexecutedonlyoncewhentheclassisloaded.

WenamedtheclassesinourexampleAppandSort.ThisisaconventioninJavatonamealmosteverythinginCamelCase.

CamelCaseiswhenthewordsarewrittenwithoutspacesbetweenthem.Thefirstwordmaystartwithlowercaseoruppercase,and,todenotethestartofthesecondandsubsequentwords,theystartwithuppercase.ForExampleThisIsALongCamelCasename.

Classnamesstartwithanuppercaseletter.Thisisnotarequirementofthelanguageformally,butthisisaconventionthateveryprogrammershouldfollow.Thesecodingconventionshelpyoucreatecodethatiseasiertounderstandbyotherprogrammers,andleadtoeasiermaintenance.Staticcodeanalyzertools,suchasCheckstyle(http://checkstyle.sourceforge.net/),alsocheckthattheprogrammersfollowtheconventions.

Page 177:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 178:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Inner,nested,local,andanonymousclassesIhavealreadymentionedinnerandnestedclassesintheprevioussection.Nowwelookattheminbitmoredetail.

Thedetailsofinnerandnestedclassesatthispointmaybedifficult.Don'tfeelashamedifyoudonotunderstandthissectionfully.Ifitistoodifficult,skiptothenextsectionandreadaboutpackagesandreturnherelater.Nested,inner,andlocalclassesarerarelyused,thoughtheyhavetheirrolesanduseinJava.AnonymousclasseswereverypopularinGUIprogrammingwiththeSwinguserinterfacethatalloweddeveloperstocreateJavaGUIapplications.WithJava8andthelambdafeature,anonymousclassesarenotsoimportantthesedays,andwiththeemergingJavaScriptandbrowsertechnology,theJavaGUIbecamelesspopular.

Whenaclassisdefinedinafileonitsown,itiscalledatop-levelclass.Classesthatareinsideanotherclassare,obviously,nottop-levelclasses.Iftheyaredefinedinsideaclassonthesamelevelasfields(variablesthatarenotlocaltosomemethodorotherblock),theyareinnerornestedclasses.Therearetwodifferencesbetweenthem.Oneisthatnestedclasseshavethestatickeywordbeforetheclasskeywordattheirdefinition,andinnerclassesdon't.

Theotherdifferenceisthatinstancesofnestedclassescanexistwithoutaninstanceofthesurroundingclass.Innerclassinstancesalwayshaveareferencetoaninstanceofthesurroundingclass.

Becauseinnerclassinstancescannotexistwithoutaninstanceofthesurroundingclass,theirinstancecanonlybecreatedbyprovidinganinstanceoftheouterclass.Wewillseenodifferenceifthesurroundingclassinstanceistheactualthisvariable,butifwewanttocreateaninstanceofaninnerclassfromoutsidethesurroundingclass,thenwehavetoprovideaninstancevariablebeforethenewkeywordseparatedbyadot,justlikeifnewwereamethod.Forexample,wecouldhaveaclassnamedTopLevelthathasaclassnamedInnerClass,likeinthefollowingcodesnippet:

publicclassTopLevel{

classInnerClass{}

}

ThenwecancreateaninstanceoftheInnerClassfromoutsidewithonlyaTopLevelobject,likeinthissnippet:

TopLeveltl=newTopLevel();

InnerClassic=tl.newInnerClass();

Asinnerclasseshaveanimplicitreferencetoaninstanceoftheenclosingclass,thecodeinsidetheinnerclasscanaccessthefieldsandthemethodsoftheenclosingclass.

Nestedclassesdonothaveanimplicitreferencetoanyinstanceoftheenclosingclass,andtheymaybeinstantiatedwiththenewkeywordwithoutanyreferencetoanyinstanceofanyotherclass.Becauseofthat,theycannotaccessthefieldsoftheenclosingclassunlesstheyarestaticfields.

Page 179:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Localclassesareclassesthataredefinedinsideamethod,constructor,oraninitializerblock.Wewillsoontalkaboutinitializerblocksandconstructors.Localclassescanbeusedinsidetheblockwheretheyaredefined.

Anonymousclassesaredefinedandinstantiatedinasinglecommand.Theyareashortformofanested,inner,orlocalclass,andtheinstantiationoftheclass.Anonymousclassesalwaysimplementaninterfaceorextendanamedclass.Thenewkeywordisfollowedbythenameoftheinterfaceortheclasswiththeargumentlisttotheconstructorbetweenparentheses.Theblockthatdefinesthebodyoftheanonymousclassstandsimmediatelyaftertheconstructorcall.Inthecaseofextendinganinterface,theconstructorcanonlybetheonewithoutargument.Theanonymousclasswithnonamecannothaveitsownconstructors.InmodernJavaweusuallyuselambdainsteadofanonymousclasses.

Lastbutnotleast—well,actually,leastIshouldmentionthatnestedandinnerclassescanalsobenestedindeeperstructures.Innerclassescannotcontainnestedclasses,butnestedclassescancontaininnerclasses.Why?Ihavenevermetanyonewhocouldreliablytellmetherealreason.Thereisnoarchitecturalreason.Itcouldbelikethat.Javadoesnotpermitthat.However,itisnotreallyinteresting.Ifyouhappentowritecodethathasmorethanonelevelofclassnestingthenjuststopdoingit.Mostprobablyyouaredoingsomethingwrong.

Page 180:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 181:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PackagesClassesareorganizedintopackagesandthefirstcodelineinafileshouldspecifythepackagethattheclassisin.

packagepackt.java9.by.example.stringsort;

Ifyoudonotspecifythepackage,thentheclasswillbeinthedefaultpackage.Thisshouldnotbeused,exceptinthesimplestcasewhenyouwanttotrysomecode.WithJava9,youcanusejshellforthispurpose,so,asopposedtopreviousversionsofJava,nowthesuggestionbecomesverysimple—neverputanyclassinthedefaultpackage.

Thenameofthepackagesishierarchical.Thepartsofthenamesareseparatedbydots.Usingpackagenameshelpsyouavoidnamecollisions.Namesoftheclassesareusuallykeptshortandputtingthemintopackageshelpstheorganizationoftheprogram.Thefullnameofaclassincludesthenameofthepackagetheclassisin.Usually,wewillputthoseclassesintoapackagethatareinsomewayrelated,andaddsomethingtoasimilaraspectofaprogram.Forexample,controllersinanMVCpatternprogramarekeptinasinglepackage.Packagesalsohelpyouavoidnamecollisionofclasses.However,thisonlypushestheproblemfromclassnamecollisiontopackagenamecollision.Wehavetomakesurethatthenameofthepackageisuniqueanddoesnotcauseanyproblemwhenourcodeisusedtogetherwithanyotherlibrary.Whenanapplicationisdeveloped,wejustcannotknowwhatotherlibrarieswillbeusedinlaterversions.Tobepreparedfortheunexpected,theconventionistonamethepackagesaccordingtosomeInternetdomainnames.Whenadevelopmentcompanyhasthedomainnameacmecompany.com,thentheirsoftwareisusuallyunderthecom.acmecompany...packages.Itisnotastrictlanguagerequirement.Itisonlyaconventiontowritethedomainnamefromrighttoleft,anduseitaspackagename,butthisprovestobefairlygoodinpractice.Sometimes,likeIdointhisbook,onecandeviatefromthispracticesoyoucanseethatthisruleisnotcarvedinstone.

Whentherubberhitstheroad,andthecodeiscompiledintobytecode,thepackagebecomesthenameoftheclass.Thus,thefullnameoftheSortclassispackt.java9.by.example.stringsort.Sort.Whenyouuseaclassfromanotherpackage,youcanusethisfullnameorimporttheclassintoyourclass.Again,thisisonthelanguagelevel.UsingthefullyqualifiednameorimportingmakesnodifferencewhenJavabecomesbytecode.

Page 182:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 183:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MethodsWehavealreadydiscussedmethods,butnotindetail,andtherearestillsomeaspectsthatweshouldmeetbeforewegoon.

Therearetwomethodsinthesampleclasses.Therecanbemanymethodsinaclass.Methodnamesarealsocamelcasedbyconvention,andthenamestartswithalowercaseletter,asopposedtoclasses.Methodsmayreturnavalue.Ifamethodreturnsavalue,themethodhastodeclarethetypeofthevalueitreturnsand,inthatcase,anyexecutionofthecodehastofinishwithareturnstatement.Thereturnstatementhasanexpressionafterthekeyword,whichisevaluatedwhenthemethodisexecutedandisreturnedbythemethod.Itisgoodpracticetohaveonlyonesinglereturnfromamethodbut,insomesimplecases,breakingthatcodingconventionmaybeforgiven.Thecompilerchecksthepossiblemethodexecutionpaths,anditisacompile-timeerrorifsomeofthepathsdonotreturnavalue.

Whenamethoddoesnotreturnanyvalue,ithastobedeclaredtobevoid.Thisisaspecialtypethatmeansnovalue.Methodsthatarevoid,suchasthepublicstaticvoidmainmethod,maysimplymissthereturnstatementandjustend.Ifthereisareturnstatement,thereisnoplaceforanyexpressiondefiningareturnvalueafterthereturnkeyword.Again,thisisacodingconventiontonotusethereturnstatementincaseofamethodthatdoesnotreturnanyvalue,butinsomecodingpatterns,thismaynotbefollowed.

Methodscanbeprivate,protected,public,andstatic,andwewilldiscusstheirmeaninglater.

Wehaveseenthatthemainmethodthatwasinvokedwhentheprogramstartedisastaticmethod.Suchamethodbelongstotheclassandcanbeinvokedwithouthavinganyinstanceoftheclass.Staticmethodsaredeclaredwiththestaticmodifier,andtheycannotaccessanyfieldormethodthatisnotstatic.

Inourexample,thesortmethodisnotstatic,butasitdoesnotaccessanyfieldanddoesnotcallanynon-staticmethod(asamatteroffact,itdoesnotcallanymethodatall),itcouldjustaswellbestatic.Ifwechangethedeclarationofthemethodtopublicstaticvoidsort(String[]names){(notethewordstatic),theprogramstillworks,buttheIDEwillgiveawarningwhileediting,forexample:

Staticmember'packt.java9.by.example.stringsort.Sort.sort(java.lang.String[])'accessedviainstancereference

ThatisbecauseyoucanaccessthemethodwithoutaninstancedirectlythroughthenameoftheSort.sort(actualNames);classwithouttheneedofthesortervariable.CallingastaticmethodviaaninstancevariableispossibleinJava(againsomethingthatseemedtobeagoodideaatthegenesisofJava,butisprobablynot),butitmaymisleadthereaderofthecodeintothinkingthatthemethodisaninstancemethod.

Makingthesortmethodstatic,themainmethodcanbeasfollows:

publicstaticvoidmain(String[]args){

String[]actualNames=newString[]{

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

};

Sort.sort(actualNames);

for(finalStringname:actualNames){

System.out.println(name);

Page 184:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

}

}

Itseemstobemuchsimpler(itis),and,incasethemethoddoesnotuseanyfield,youmaythinkthatthereisnoreasontomakeamethodnon-static.DuringthefirsttenyearsofJava,staticmethodswereinheavyuse.Thereisevenaterm,utilityclass,whichmeansaclassthathasonlystaticmethodsandshouldnotbeinstantiated.WiththeadventofInversionofControlcontainers,wetendtouselessstaticmethods.Whenstaticmethodsareused,itishardertousedependencyinjection,anditisalsomoredifficulttocreatetests.Wewilldiscusstheseadvancedtopicsinthenextfewchapters.Fornow,youareinformedastowhatstaticmethodsareandthattheycanbeused;however,usually,unlessthereisaveryspecialneedforthem,wewillavoidthem.

Later,wewilllookathowclassesareimplementedinthehierarchy,andhowclassesmayimplementinterfacesandextendotherclasses.Whenthesefeaturesarelookedat,wewillseethatthereareso-calledabstractclassesthatmaycontainabstractmethods.Thesemethodshavetheabstractmodifier,andtheyarenotdefined—onlythename,argumenttypes(andnames),andreturntypearespecified.Aconcrete(non-abstract)classextendingtheabstractclassshoulddefinethem.

Theoppositeofabstractmethodisthefinalmethoddeclaredwiththefinalmodifier.Afinalmethodcannotbeoverriddeninsubclasses.

Page 185:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 186:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InterfacesMethodsarealsodeclaredininterfaces.Amethoddeclaredinaninterfacedoesnotdefinetheactualbehaviorofthemethod;theydonotcontainthecode.Theyhaveonlytheheadofthemethod;inotherwords,theyareabstractimplicitly.Althoughnobodydoes,youmayevenusetheabstractkeywordinaninterfacewhenyoudefineamethod.

Interfaceslookverysimilartoclasses,butinsteadofusingtheclasskeyword,weusetheinterfacekeyword.Becauseinterfacesaremainlyusedtodefinemethods,themethodsarepublicifnomodifierisused.

Interfacescanalsodefinefields,butsinceinterfacescannothaveinstances(onlyimplementingclassescanhaveinstances),thesefieldsareallstaticandtheyalsohavetobefinal.Thisisthedefaultforfieldsininterfaces,thuswedonotneedtowritetheseifwedefinedfieldsininterfaces.

Itwasacommonpracticetodefineonlyconstantsinsomeinterfacesandthenusetheseinclasses.Todothat,theeasiestwaywastoimplementtheinterface.Sincetheseinterfacesdonotdefineanymethod,theimplementationisnothingmorethanwritingtheimplementskeywordandthenameoftheinterfaceintotheheaderoftheclassdeclaration.Thisisbadpracticebecausethiswaytheinterfacebecomespartofthepublicdeclarationoftheclass,althoughtheseconstantsareneededinsidetheclass.Ifyouneedtodefineconstantsthatarenotlocaltoaclassbutareusedinmanyclasses,thendefinetheminaclassandimportthefieldsusingimportstaticorjustusethenameoftheclassandthefield.

Interfacescanalsohavenestedclasses,buttheycannothaveinnerclasses.Theobviousreasonforthatisthatinnerclassinstanceshaveareferencetoaninstanceoftheenclosingclass.Inthecaseofaninterface,therearenoinstances,soaninnerclasscouldnothaveareferencetoaninstanceofanenclosinginterface,becausethatjustdoesnotexist.Thejoyfulpartofitisthatwedonotneedtousethestatickeywordinthecaseofnestedclassesbecausethatisthedefault,justasinthecaseoffields.

WiththeadventofJava8,youcanalsohavedefaultmethodsininterfacesthatprovidedefaultimplementationofthemethodfortheclassesthatimplementtheinterface.TherecanalsobestaticandprivatemethodsininterfacessinceJava9.

Methodsareidentifiedbytheirnameandtheargumentlist.Youcanreuseanameforamethodandhavedifferentargumenttypes;Javawillidentifywhichmethodtousebasedonthetypesoftheactualarguments.Thisiscalledmethodoverloading.Usually,itiseasytotellwhichmethodyoucall,butwhentherearetypesthatextendeachother,thesituationbecomesmorecomplex.Thestandarddefinesverypreciserulesfortheactualselectionofthemethodthatthecompilerfollows,sothereisnoambiguity.However,fellowprogrammerswhoreadthecodemaymisinterpretoverloadedmethodsor,atleast,willhavehardtimeidentifyingwhichmethodisactuallycalled.Methodoverloadingmayalsohinderbackwardcompatibilitywhenyouwanttoextendyourclass.Thegeneraladviceistothinktwicebeforecreatingoverloadedmethods.Theyarelucrative,butmaysometimesbecostly.

Page 187:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 188:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ArgumentpassingInJava,argumentsarepassedbyvalue.Whenthemethodmodifiesanargumentvariable,thenonlythecopyoftheoriginalvalueismodified.Anyprimitivevalueiscopiedduringthemethodcall.Whenanobjectispassedasanargument,thenthecopyofthereferencetotheobjectispassed.

Thatway,theobjectisavailabletobemodifiedforthemethod.Inthecaseofclassesthathavetheirprimitivecounterpart,andalsointhecaseofStringandsomeotherclasstypes,theobjectssimplydonotprovidemethodsorfieldstomodifythestate.Thisisimportantfortheintegrityofthelanguage,andtonotgetintotroublewhenobjectsandprimitivevaluesautomaticallygetconverted.

Inothercases,whentheobjectismodifiable,themethodcaneffectivelyworkontheveryobjectitwaspassedto.Thisisalsothewaythesortmethodinourexampleworksonthearray.Thesamearray,whichisalsoanobjectitself,ismodified.

Thisargumentpassingismuchsimplerthanitisinotherlanguages.Otherlanguagesletthedevelopermixthepassbyreferenceandthepassbyvalueargumentpassing.InJava,whenyouuseavariablebyitselfasanexpressiontopassaparametertoamethod,youcanbesurethatthevariableitselfisnevermodified.Theobjectitrefersto,however,incaseitismutable,maybemodified.

Anobjectismutableifitcanbemodified,alteringthevalueofsomeofitsfielddirectlyorviasomemethodcall.Whenaclassisdesignedinawaythatthereisnonormalwaytomodifythestateoftheobjectafterthecreationoftheobject,theobjectisimmutable.TheclassesByte,Short,Integer,Long,Float,Double,Boolean,Character,aswellasString,aredesignedintheJDKsothattheobjectsareimmutable.Itispossibletoovercomethelimitationofimmutabilityimplementationofcertainclassesusingreflection,butdoingthatishackingandnotprofessionalcoding.Doingthatcanbedoneforonesinglepurpose—gettingabetterknowledgeandunderstandingoftheinnerworkingsofsomeJavaclasses,butnothingelse.

Page 189:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 190:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

FieldsFieldsarevariablesontheclasslevel.Theyrepresentthestateofanobject.Theyarevariables,withdefinedtypeandpossibleinitialvalue.Fieldscanbestatic,final,transient,andvolatile,andtheaccessmaybemodifiedwiththepublic,protected,andprivatekeywords.

Staticfieldsbelongtotheclass.Itmeansthatthereisoneofthemsharedbyalltheinstancesoftheclass.Normal,non-staticfieldsbelongtotheobjects.Ifyouhaveafieldnamedf,theneachinstanceoftheclasshasitsownf.Iffisdeclaredstatic,thentheinstanceswillsharetheverysameffield.

Thefinalfieldscannotbemodifiedaftertheyareinitialized.Initializationcanbedoneonthelinewheretheyaredeclared,inaninitializerblockorintheconstructorcode.Thestrictrequirementisthattheinitializationhastohappenbeforetheconstructorreturns.Thisway,themeaningofthefinalkeywordisverydifferent,inthiscase,fromwhatitmeansinthecaseofaclassoramethod.Afinalclasscannotbeextendedandafinalmethodcannotbeoverriddeninanextendingclass,aswewillseeinthenextchapter.Thefinalfieldsareeitheruninitializedorgetavalueduringinstancecreation.Thecompileralsochecksthatthecodedoesinitializeallfinalfieldsduringtheobject-instancecreationorduringtheclassloading,incasethefinalfieldisstatic,andthatthecodeisnotaccessing/readinganyfinalfieldthatwasnotyetinitialized.

Itisacommonmisconceptionthatthefinalfieldshavetobeinitializedatthedeclaration.Itcanbedoneinaninitializercodeorinaconstructor.Therestrictionisthat,nomatterwhichconstructoriscalledincasetherearemore,thefinalfieldshavetobeinitializedexactlyonce.

Thetransientfieldsarenotpartoftheserializedstateoftheobject.Serializationisanactofconvertingtheactualvalueofanobjecttophysicalbytes.Deserializationistheoppositewhentheobjectiscreatedfromthebytes.Itisusedtosavethestateinsomeframeworks.Thecodethatdoestheserialization,java.lang.io.ObjectOutputStream,worksonlywithclassesthatimplementtheSerializableinterface,andusesonlythefieldsfromthoseobjectsthatarenottransient.Veryobviously,transientfieldsarealsonotrestoredfromthebytesthatrepresenttheserializedformoftheobjectbecausetheirvalueisnotthere.

Serializationisusuallyusedindistributedprograms.Agoodexampleisthesessionobjectofaservlet.Whentheservletcontainerrunsonaclusterednode,somefieldsofobjectsstoredintothesessionobjectmaymagicallydisappearbetweenHTTPhits.Thatisbecauseserializationsavesandreloadsthesessiontomovethesessionbetweenthenodes.Serialization,insuchasituation,mayalsobeaperformanceissueifadeveloperdoesnotknowthesideeffectsofthestoredlargeobjectsinthesession.

Thevolatilekeywordisakeywordthattellsthecompilerthatthefieldmaybeusedbydifferentthreads.Whenavolatilefieldisaccessedbyanycode,theJITcompilergeneratescodewhichensuresthatthevalueofthefieldaccessedisuptodate.Whenafieldisnotvolatile,thecompiler-generatedcodemaystorethevalueofthefieldinaprocessorcacheorregistryforfasteraccesswhenitseesthatthevaluewillbeneededsoonbysomesubsequentcodefragment.Inthecaseofvolatilefields,thisoptimizationcannotbedone.Additionally,notethatsavingthevaluetomemoryandloadingfromthereallthetimemaybe50ormoretimesslowerthanaccessingavaluefromaregistryorcache.

Page 191:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 192:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ModifiersMethods,constructors,fields,interfaces,andclassescanhaveaccessmodifiers.Thegeneralruleisthatincasethereisnomodifier,thescopeofthemethod,constructor,andsoon,isthepackage.Anycodeinthesamepackagecanaccessit.

Whentheprivatemodifierisused,thescopeisrestrictedtotheso-calledcompilationunit.Thismeanstheclassthatisinonefile.Whatisinsideonefilecanseeanduseanythingdeclaredtobeprivate.Thisway,innerandnestedclassescanhaveaccesstoeachother'sprivatevariables,whichmaynotreallybeagoodprogrammingstyle,butJavapermitsthat.

Theoppositeofprivateispublic.ItextendsthevisibilitytothewholeJavaprogram,oratleasttothewholemodule,iftheprojectisaJava9module.

Thereisamiddleway:protected.Anythingwiththismodifierisaccessibleinsidethepackageandalsoinclassesthatextendtheclass(regardlessofpackage)thattheprotectedmethod,field,andsoon,isin.

Page 193:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 194:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ObjectinitializersandconstructorsWhenanobjectisinstantiated,theappropriateconstructoriscalled.Theconstructordeclarationlookslikeamethodwiththefollowingdeviation:theconstructordoesnothaveareturnvalue.Thatisbecausetheconstructorsworkonthenot-fully-readyinstancewhenthenewcommandoperatorisinvokedanddoesnotreturnanything.Constructors,havingthesamenameastheclass,cannotbedistinguishedfromeachother.Ifthereisaneedformorethanoneconstructor,theyhavetobeoverloaded.Constructors,thus,cancalleachother,almostasiftheywerevoidmethodswithdifferentarguments.However,thereisarestriction—whenaconstructorcallsanother,ithastobetheveryfirstinstructionintheconstructor.Youusethis()syntaxwithanappropriateargumentlist,whichmaybeempty,toinvokeaconstructorfromanotherconstructor.

Theinitializationoftheobjectinstancealsoexecutesinitializerblocks.Theseareblockscontainingexecutablecodeinsidethe{and}charactersoutsidethemethodsandconstructors.Theyareexecutedbeforetheconstructorintheordertheyappearinthecode,togetherwiththeinitializationofthefieldsincasetheirdeclarationscontainvalueinitialization.

Ifyouseethestatickeywordinfrontofaninitializerblock,theblockbelongstotheclassandisexecutedwhentheclassisloadedalongwiththestaticfieldinitializers.

Page 195:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 196:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CompilingandrunningtheprogramFinally,wewillcompileandexecuteourprogramfromthecommandline.Thereisnothingnewinthisone;wewillonlyapplywhatwehavelearnedinthischapterusingthefollowingtwocommands:$mvnpackage

Thiscompilestheprogram,packagestheresultintoaJARfile,andfinallyexecutesthefollowingcommand:

$java-cptarget/SortTutorial-1.0.0-SNAPSHOT.jarpackt.java9.by.example.App

Thiswillprintthefollowingresultonthecommandline:

Page 197:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 198:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

Inthischapter,wehavedevelopedaverybasicsortalgorithm.ItwasmadepurposefullysimplesothatwecouldreiteratethebasicandmostimportantJavalanguageelements,classes,packages,variables,methods,andsoon.Wealsolookedatbuildtools,sowearenotemptyhandedinthenextchapterswhenprojectswillcontainmorethanjusttwofiles.WewilluseMavenandGradleinthefollowingchapters.

Intheverynextchapter,wewillmakethesortprogrammorecomplex,implementingmoreeffectivealgorithmsandalsomakingourcodeflexible,givingustheopportunitytolearnmoreadvancedJavalanguagefeatures.

Page 199:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 200:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

OptimizingtheSort-MakingCodeProfessionalInthischapter,wewilldevelopthesortingcodeandmakeitmoregeneral.WewanttosortnotonlyanarrayofStrings.Essentially,wewillwriteaprogramthatcansortanythingthatissortable.Thatway,wewillbringthecodingtoitsfullextenttowardoneofthemajorstrengthsofJava:abstraction.

Abstraction,however,doesnotcomewithoutapricetag.Whenyouhaveaclassthatsortsstringsandyouaccidentallymixanintegerorsomethingelse,whichisnotastring,intothesortabledata,thenthecompilerwillcomplainaboutit:JavadoesnotallowyoutoputanintintoaStringarray.Whenthecodeismoreabstract,suchprogrammingerrorsmayslipin.WewilllookathowtohandlesuchexceptionalcasescatchingandthrowingExceptions.

Toidentifythebugs,wewilluseunittesting,applyingtheindustrystandardJUnitversion4.AsJUnitheavilyusesannotation,andbecauseannotationsareimportant,youwilllearnaboutitabit.

Afterthat,wewillmodifythecodetousethegenericsfeatureofJavathatwasintroducedintothelanguageinversion5.Usingthatpossibility,wewillcatchthecodingerrorduringcompilationtime,whichisbetterthanduringruntime.Theearlierabugisidentified,thecheaperitistofix.

Forthebuild,wewillstilluseMaven,butthistime,wewillsplitthecodeintosmallmodules.Thus,wewillhaveamulti-moduleproject.Wewillhaveseparatemodulesforthedefinitionofasortingmoduleandforthedifferentimplementations.Thatway,wewilllookathowclassescanextendeachotherandimplementinterfaces,and,generally,wewillreallystarttoprogramintheobject-orientedway.

WewillalsodiscussTestDrivenDevelopment(TDD),andattheendofthesection,wewillstartusingthebrandnewfeatureofJava9:modulesupport.

Inthischapter,wewillcoverthefollowingtopics:

Object-orientedprogrammingprinciplesUnittestingpracticesAlgorithmiccomplexityandquicksortExceptionhandlingRecursivemethodsModulesupport

Page 201:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 202:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThegeneralsortingprogramInthepreviouschapter,weimplementedasimplesortalgorithm.ThecodecansortelementsofaStringarray.Wedidthistolearn.Forpracticaluse,thereisareadycookedsortsolutionintheJDKthatcansortmembersofcollections,whicharecomparable.

TheJDKcontainsautilityclasscalledCollections.ThisclasscontainsastaticCollections.sortmethodthatiscapableofsortinganyListthathasmembersthatareComparable.ListandComparableareinterfacesdefinedintheJDK.Thus,ifwewanttosortalistofStrings,thesimplestsolutionisasfollows:

publicclassSimplestStringListSortTest{

@Test

publicvoidcanSortStrings(){

ArrayListactualNames=newArrayList(Arrays.asList(

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

));

Collections.sort(actualNames);

Assert.assertEquals(newArrayList<String>(Arrays.<String>asList(

"Abraham","Dagobert","Johnson","Wilkinson","Wilson")),actualNames);

}

}

ThiscodefragmentisfromasampleJUnittest,whichisthereasonwehavethe@Testannotationinfrontofthemethod.Wewilldiscussthatindetaillater.Toexecutethattest,youcanissuethefollowingcommand:

$mvn-Dtest=SimplestStringListSortTesttest

Thissortimplementation,however,doesnotfitourneeds.Firstofall,becauseitisthereready(noneedtocode)andusingitdoesnotneedanythingnewthatyouhavenotlearnedinthepreviouschapters.Exceptfortheannotationinfrontofthemethod,thereisnothingnewinthecodethatyoucannotunderstand.YoumayrefreshBYturningsomepagesback,orelseconsulttheoracleonlinedocumentationoftheJDK(https://docs.oracle.com/javase/8/docs/api/),butthatisall.Youalreadyknowthesethings.

YoumaywonderwhyIwrotetheURLfortheJavaversion8APItothelink.Well,thenthisisthemomentofhonestyandtruth-whenIwrotethisbook,theJava9JDKwasnotavailableinitsfinalform.IcreatedmostoftheexamplesonmyMacBookusingJava8andIonlytestedthefeaturesthatareJava9specific.SupportatthemomentforJava9intheIDEsisnotperfect.Whenyoureadthisbook,Java9willbeavailable,soyoucantryandchangethatonesingledigitfrom8to9intheURLandgettothedocumentationoftheversion9.Atthemoment,IgetHTTPERROR404.Sometimes,youmayneedthedocumentationofolderversions.Youcanuse3,4,5,6,or7insteadof8intheURL.Documentationfor3and4isnotavailabletoreadonline,butitcanbedownloaded.Hopefully,youwillneverneedthatanymore.Version5,perhaps.Version6isstillwidelyusedatlargecorporations.

Althoughyoucanlearnalotfromreadingcodethatwaswrittenbyotherprogrammers,IdonotrecommendtryingtolearnfromtheJDKsourcecodeatthisearlystageofyourstudies.Theseblocksofcodeareheavilyoptimized,notmeanttobetutorialcodes,andold.Theydonotgetrustedduringtheyears,buttheywerenotrefactoredtofollowthecodingstylesofJavaasitmatured.Atsomeplaces,you

Page 203:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

canfindreallyuglycodeintheJDK.

Okay,sayingthatweneedtodevelopanewsortcodebecausewecanlearnfromit,isabitcontrived.TherealreasonwhyweneedasortimplementationisthatwewantsomethingthatcansortnotonlyListdatatypesandaListofsomethingthatimplementstheComparableinterface.Wewanttosortabunchofobjects.Allwerequireisthatthebunchcontainingtheobjectsprovidessimplemethodsthatarejustenoughtosortthemandhaveasortedbunch.

OriginallyIwantedtousethewordcollectioninsteadofbunch,butthereisaCollectioninterfaceinJavaandIwantedtoemphasizethatwearenottalkingaboutjava.util.Collectionofobjects.

WealsodonotwanttheobjectstoimplementtheComparableinterface.IfwerequiretheobjecttoimplementtheComparableinterface,itmayviolatetheSingleResponsibilityPrinciple(SRP).

Whenwedesignaclass,itshouldmodelsomeobjectclassoftherealworld.Wewillmodeltheproblemspacewithclasses.Theclassshouldimplementthefeaturesthatrepresentthebehavioroftheobjectsthatitmodels.Ifwelookattheexampleofstudentsfromthesecondchapter,thenaStudentclassshouldrepresentthefeaturesthatallstudentsshare,andisimportantfromthemodelingpointofview.AStudentobjectshouldbeabletotellthenameofthestudent,theage,theaveragescoresofthelastyear,andsoon.Allstudentshavefeet,andcertainlyeachofthosefeethavesizesowemaythinkthataStudentclassshouldalsoimplementamethodthatreturnsthesizeofthestudent'sfoot(onefortheleftandonefortherightjusttobeprecise),butwedonot.Wedonot,becausethesizeofthefootisirrelevantfromthemodelpointofview.IfwewanttosortalistcontainingStudentobjects,theStudentclasshastoimplementtheComparableinterface.Butwait!Howdoyoucomparetwostudents?Bynames,byage.orbytheaveragescoreofthem?

ComparingastudenttoanotherisnotafeatureoftheStudent.Everyclass,orforthatmatter,package,library,orprogrammingunitshouldhaveoneresponsibilityanditshouldimplementonlythatandnothingelse.Itisnotexact.Thisisnotmathematics.Sometimes,itishardtotellifafeaturefitsintotheresponsibilityornot.Therearesimpletechniques.Forexample,incaseofastudent,youcanasktherealpersonabouthisnameandage,andprobablytheycanalsotellyoutheiraveragescore.IfyouaskoneofthemtocompareTo(anotherstudent),astheComparableinterfacerequiresthismethod,theywillprobablyaskback,butbywhatattribute?Orhow?Orjust,what?Insuchacase,youcansuspectthatimplementingthefeatureisprobablynotintheareaofthatclassandthisconcern;thecomparisonshouldbesegregatedfromtheimplementationoftheoriginalclass.ThisisalsocalledSegregationofConcerns,whichiscloselyrelatedtoSRP.

JDKdeveloperswereawareofthis.Collections.sortthatsortsaListofComparableelementsisnottheonlysortingmethodinthisclass.ThereisanotherthatjustsortsanyListifyoupassasecondargumentandobjectthatimplementstheComparatorinterfaceandiscapableofcomparingtwoelementsofList.Thisisacleanpatterntoseparatetheconcerns.Insomecases,separatingthecomparisonisnotneeded.Inothercases,itisdesirable.TheComparatorinterfacedeclaresonesinglemethodthattheimplementingclasseshavetoprovide:compare.Ifthetwoargumentsareequal,thenthismethodreturns0.Iftheyaredifferent,itshouldreturnanegativeorapositiveintdependingonwhichargumentprecedeswhichone.

Page 204:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TherearealsosortmethodsintheJDKclass,java.util.Arrays.Theysortarrays,oronlyasliceofanarray.Themethodisagoodexampleofmethodoverloading.Therearemethodswiththesamename,butwithdifferentargumentstosortawholearrayforeachprimitivetype,forasliceofeach,andalsotwoforobjectarrayimplementingtheComparableinterface,andalsoforobjectarraytobesortedusingComparator.Asyousee,thereisawholerangeofsortimplementationsavailableintheJDK,andin99percentofthecases,youwillnotneedtoimplementasortyourself.Thesortsusethesamealgorithm,astablemergesortwithsomeoptimization.

Whatwewillimplementisageneralapproachthatcanbeusedtosortlists,arrays,orjustanythingthathaselementsanditispossibletoswapanytwoelementsofit;thesolutionwillbeabletousethebubblesortthatwehavealreadydevelopedandalsootheralgorithms.

Page 205:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 206:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AbriefoverviewofvarioussortingalgorithmsTherearemanydifferentsortingalgorithms.AsIsaid,therearesimplerandmorecomplexalgorithmsand,inmanycases,morecomplexalgorithmsaretheonesthatrunfaster.Inthischapter,wewillimplementthebubblesortandquicksort.Wehavealreadyimplementedthebubblesortforstringsinthepreviouschapter,sointhiscase,theimplementationwillmainlyfocusontherecodingforgeneralsortableobjectsorting.Implementingquicksortwillinvolveabitofalgorithmicinterest.

Bewarnedthatthissectionisheretogiveyouonlyatasteofalgorithmiccomplexity.ItisfarfrompreciseandIaminthevainhopethatnomathematicianreadsthisandputsacurseonme.Someoftheexplanationsarevague.Ifyouwanttolearncomputerscienceindepth,thenafterreadingthisbook,findsomeotherbooksorvisitonlinecourses.

Whenwetalkaboutthegeneralsortingproblem,wewillthinkaboutsomegeneralsetofobjectsthatcanbecomparedandanytwoofthemcanbeswappedwhilewesort.Wewillalsoassumethatthisisanin-placesort;thus,wedonotcreateanotherlistorarraytocollecttheoriginalobjectsinsortedorder.Whenwetalkaboutthespeedofanalgorithm,wearetalkingaboutsomeabstractthingandnotmilliseconds.Whenwewanttotalkaboutmilliseconds,actualreal-worldduration,weshouldalreadyhavesomeimplementationinsomeprogramminglanguagerunningonarealcomputer.

Algorithms,intheirabstractform,don'tdothatwithoutimplementation.Still,itisworthtalkingaboutthetimeandmemoryneedofanalgorithm.Whenwedothat,wewillusuallyinvestigatehowthealgorithmbehavesforalargesetofdata.Forasmallsetofdata,mostalgorithmsarejustfast.Sortingtwonumbersisusuallynotanissue,isit?

Incaseofsorting,wewillusuallyexaminehowmanycomparisonsareneededtosortacollectionofnelements.Bubblesortneedsapproximatelyn2(ntimesn)comparisons.Wecannotsaythatthisisexactlyn2becauseincaseofn=2,theresultis1,forn=3itis3,forn=4itis6,andsoon.However,asnstartstogetlarger,theactualnumberofcomparisonsneededandn2willasymptoticallybeofthesamevalue.WesaythatthealgorithmiccomplexityofthebubblesortisO(n2).Thisisalsocalledthebig-Onotation.IfyouhaveanalgorithmthatisO(n2)anditworksjustfinefor1,000elementsfinishinginasecond,thenyoushouldexpectthesamealgorithmfinishingfor1millionelementsinaroundtendaysorinamonth.Ifthealgorithmislinear,sayO(n),thenfinishing1,000elementinonesecondshouldmakeyouexpect1milliontobefinishedin1,000seconds.Thatisabitlongerthanacoffeebreakandtooshortforlunch.

Thismakesitfeasiblethatifwewantsomeseriousbusinesssortingobjects,wewillneedsomethingbetterthanbubblesort.Thatmanyunnecessarycomparisonsarenotonlywastingourtime,butalsoCPUpower,consumingenergy,andpollutingtheenvironment.Thequestion,however,is:howfastcanasortbe?Isthereaprovableminimumthatwecannotovercome?

Theanswerisyes.

Whenweimplementanysortingalgorithm,theimplementationwillexecutecomparisonsandelementswaps.Thatistheonlywaytosortacollectionofobjects.Theoutcomeofacomparisoncanhavetwovalues.Say,thesevaluesare0or1.Thisisonebitofinformation.Iftheresultofthecomparisonis1,

Page 207:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

thenweswap,iftheresultis0,thenwedonotswap.

Wecanhavetheobjectsindifferentordersbeforewestartthecomparisonandthenumberofdifferentordersisn!(nfactorial).Thatis,thenumbersmultipliedfrom1ton,inotherwordsn!=1*2*3*...*(n-1)*n.

Let'sassumethatwestoredtheresultoftheindividualcomparisonsinanumberasaseriesofbitsforeachpossibleinputforthesort.Now,ifwereversetheexecutionofthesortandrunthealgorithmstartingfromthesortedcollection,controltheswappingusingthebitsthatdescribedtheresultsofthecomparison,andweusethebitstheotherwayarounddoingthelastswapfirstandtheonethatwasdonefirstduringthesortingfirst,weshouldgetbacktheoriginalorderoftheobjects.Thisway,eachoriginalorderisuniquelytiedtoanumberexpressedasanarrayofbits.

Now,wecanexpresstheoriginalquestionthisway:howmanybitsareneededtodescribenfactorialdifferentnumbers?Thatisexactlythenumberofcomparisonswewillneedtosortnelements.Thenumberofbitsislog2(n!).Usingsomemathematics,wewillknowthatlog2(n!)isthesameaslog2(1)+log2(2)+...+log2(n).Ifwelookatthisexpression'sasymptoticvalue,thenwecansaythatthisisthesameO(n*logn).Weshouldnotexpectanygeneralsortingalgorithmtobefaster.

Forspecialcases,therearefasteralgorithms.Forexample,ifwewanttosort1millionnumbersthatareeachbetweenoneand10,thenweonlyneedtocountthenumberofthedifferentnumbersandthencreateacollectionthatcontainsthatmanyones,twos,andsoon.ThisisanO(n)algorithm,butthisisnotapplicableforthegeneralcase.

Again,thiswasnotaformalmathematicalproof.

Page 208:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 209:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

QuicksortSirCharlesAntonyRichardHoaredevelopedthequicksortalgorithmin1959.Itisatypicaldivideandconqueralgorithm.Tosortalongarray,pickanelementfromthearraythatwillbethepivotelement.Then,partitionthearraysothattheleftsidewillcontainalltheelementsthataresmallerthanthepivotandtherightsidewillcontainalltheelementsthatarelargerthan,orequaltothepivot.Whenthisisdone,theleftsideandtherightsideofthearraycanbesortedbycallingthesortrecursively.Tostoptherecursion,whenwehaveonesingleelementinthearray,wewilldeclareitsorted.

Wetalkaboutarecursivealgorithmwhenthealgorithmisdefinedpartiallyusingitself.ThemostfamousrecursivedefinitionistheFibonacciseriesthatis0and1forthefirsttwoelementsandanylaterelementthenthelementisthesumofthe(n-1)thandthe(n-2)thelement.Recursivealgorithmsaremanytimesimplementedinmodernprogramminglanguagesimplementingamethodthatdoessomecalculationbutsometimescallsitself.Whendesigningrecursivealgorithms,itisofutmostimportancetohavesomethingthatstopstherecursivecalls;otherwise,recursiveimplementationwillallocateallmemoryavailablefortheprogramstackandstoptheprogramwitherror.

Thepartitioningalgorithmgoesthefollowingway:wewillstarttoreadthearrayusingtwoindicesfromthestartandend.Wewillfirststartwiththeindexthatissmallandincreasetheindexuntilitissmallerthanthelargeindex,oruntilwefindanelementthatisgreaterthanorequaltothepivot.Afterthis,wewillstarttodecreasethelargerindexsolongasitisgreaterthanthesmallindexandtheelementindexedisgreaterthanorequaltothepivot.Whenwestop,weswapthetwoelementspointedbythetwoindices,iftheindicesarenotthesame,andwewillstartincreasinganddecreasingthesmallandlargeindices,respectively.Iftheindicesarethesame,thenwearefinishedwiththepartitioning.Theleftsideofthearrayisfromthestarttotheindexwheretheindicesmetminusone;therightsidestartswiththeindexandlastsuntiltheendoftheto-be-sortedarray.

ThisalgorithmisusuallyO(nlogn),butinsomecasesitcandegradetobeO(n2),dependingonhowthepivotischosen.Therearedifferentapproachesfortheselectionofthepivot.Inthisbook,wewillusethesimplest:wewillselectthefirstelementofthesortablecollectionasapivot.

Page 210:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

<project><br/>...<br/><modules><br/><module>SortInterface</module><br/><module>bubble</module><br/><module>quick</module><br/></modules><br/></project>

$tree<br/>|-SortInterface<br/>|---src/main/java/packt/java9/by/example/ch03<br/>|-bubble<br/>|---src<br/>|-----main/java/packt/java9/by/example/ch03/bubble<br/>|-----test/java/packt/java9/by/example/ch03/bubble<br/>|-quick/src/<br/>|-----main/java<br/>|-----test/java

Page 211:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 212:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MavendependencymanagementDependenciesarealsoimportantinthePOMfile.Thepreviousprojectdidnothaveanydependency,butthistimewewilluseJUnit.Dependenciesaredefinedinpom.xmlusingthedependenciestag.Forexample,thebubblesortmodulecontainsthefollowingpieceofcode:

<dependencies>

<dependency>

<groupId>packt.java9.by.example</groupId>

<artifactId>SortInterface</artifactId>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

</dependency>

</dependencies>

Theactualpom.xmlinthecodesetyoucandownloadwillcontainmorecodethanthis.Inprint,weoftenpresentaversionoronlyafractionthathelpstheunderstandingofthetopicthatwearediscussingatthatpoint.

IttellsMaventhatthemodulecodeusesclasses,interfaces,andenumtypesthataredefinedinthesemodulesthatareavailablefromsomerepository.

WhenyouuseMaventocompilethecode,thelibrariesthatareusedbyyourcodeareavailablefromrepositories.WhenAntwasdeveloped,thenotionofrepositorieswasnotinvented.Atthattime,thedeveloperscopiedtheusedversionofthelibraryintoafolderinthesourcecodestructure.Usually,thedirectorylibwasusedforthepurpose.Thereweretwoproblemswiththisapproach.Oneisthesizeofthesourcecoderepository.If,forexample,100differentprojectsusedJUnit,thentheJARfileoftheJUnitlibrarywascopiedthere100times.Theotherproblemwastogatherallthelibraries.Whenalibraryusedanotherlibrary,thedevelopershadtoreadthedocumentationofthelibrarythatdescribed(manytimesoutdatedandnotprecise)whatotherlibrariesareneededtousethislibrary.Thoselibrarieshadtobedownloadedandinstalledthesameway.Thiswastimeconsuminganderrorprone.Whenalibrarywasmissingandthedevelopersjustdidnotnoticeit,theerrorwasmanifestedduringcompiletimewhenthecompilercouldnotfindtheclassorevenonlyatruntimewhentheJVMwasnotabletoloadtheclass.

Tosolvethisissue,Mavencomeswithabuilt-inrepositorymanagerclient.Therepositoryisastoragethatcontainsthelibraries.Astherecanbeothertypesoffilesinarepository,notonlylibraries,Maventerminologyisartifact.ThegroupId,theartifactId,andtheversionnumberidentifyanartifact.Thereisaverystrictrequirementthatanartifactcanonlybeputintoarepositoryonce.Evenifthereisanerrorduringthereleaseprocessthatisidentifiedaftertheerroneousreleasewasuploaded,theartifactcannotbeoverwritten.ForthesamegroupId,artifactId,andversion,therecanonlybeonesinglefilethatwillneverchange.Iftherewasanerror,thenanewartifactistobecreatedwithnewversionnumberandtheerroneousartifactmaybedeletedbutnotreplaced.

Iftheversionnumberendswith-SNAPSHOT,thenthisuniquenessisnotguaranteedorrequired.Snapshotsareusuallystoredinseparaterepositoryandarenotpublishedfortheworld.

Page 213:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Repositoriescontaintheartifactsindirectoriesthatareorganizedinadefinedway.WhenMavenruns,itcanaccessdifferentrepositoriesusinghttpsprotocol.

Formerly,thehttpprotocolwasalsoused,andfornon-payingcustomers,thecentralrepositorywasavailableviahttponly.However,itwasdiscoveredthatmodulesdownloadedfromtherepositorycouldbetargetsformen-in-the-middlesecurityattacksandSonatype(http://www.sonatype.com)changedthepolicyandusedhttpsprotocolonly.Neverconfigureorusearepositorywiththehttpprotocol.NevertrustafilethatyoudownloadedfromHTTP.

Thereisalocalrepositoryonthedevelopermachine,usuallyunderthe~/.m2/repositorydirectory.Whenyouissuethemvninstallcommand,Mavenstoresthecreatedartifacthere.MavenalsostoresanartifactherewhenitisdownloadedfromarepositoryviaHTTPS.Thisway,subsequentcompilationsdonotneedtogoouttothenetworkfortheartifacts.

Companiesusuallysetuptheirownrepositorymanager(theonethatSonatype,thecompanybackingMaven,isprovidingNexus).Theseapplicationscanbeconfiguredtocommunicatewithseveralotherrepositoriesandcollecttheartifactsfromthereondemand,essentiallyimplementingproxyfunctionality.Artifactstraveltothebuildfromthefarendrepositoriestothecloseronesinahierarchicalstructuretothelocalrepoandessentiallytothefinalartifactifthepackagingtypeoftheprojectiswar,ear,orsomeotherformatthatenclosesthedependentartifacts.Thisisessentiallyfilecachingwithoutrevalidationandcacheeviction.Thiscanbedonebecauseofthestrictrulesofartifactuniqueness.Thisisthereasonforsuchastrictrule.

Iftheprojectbubblewereastandaloneproject,andnotpartofamulti-moduleone,thenthedependencywouldlooklikethis:

<dependencies>

<dependency>

<groupId>packt.java9.by.example</groupId>

<artifactId>SortInterface</artifactId>

<version>1.0.0-SNAPSHOT</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

</dependency>

</dependencies>

Ifversionisnotdefinedforadependency,Mavenwillnotbeabletoidentifywhichartifacttouse.Inthecaseofamulti-moduleproject,versioncanbedefinedintheparentandthemodulescaninherittheversion.Astheparentisnotdependentontheactualdependency,itonlydefinestheversionattachedtothegroupIdandartifactId;theXMLtagisnotdependencies,butdependencyManagement/dependenciesunderthetop-levelprojecttagasinthefollowingexample:

<dependencyManagement>

<dependencies>

<dependency>

<groupId>packt.java9.by.example</groupId>

<artifactId>SortInterface</artifactId>

<version>${project.version}</version>

</dependency>

<dependency>

<groupId>junit</groupId>

Page 214:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>

</dependencies>

</dependencyManagement>

IftheparentPOMusesthedependenciestagdirectly,Mavenisnotabletodecideiftheparentdependsonthatartifactorsomemodules.Whenthemoduleswanttousejunit,theyneednotspecifytheversion.Theywillgetitfromtheparentprojectdefinedas4.12,whichisthelatestfromJUnit4.Ifevertherewillbeanewversion4.12.1,withsomeseriousbugsfixed,thentheonlyplacetomodifytheversionnumberistheparentPOM,andthemoduleswillusethenewversionstartingwiththenextexecutionoftheMavencompilation.

Whenthenewversion,JUnit5,comesout,however,themoduleswillallhavetobemodifiedbecauseJUnitisnotjustanewversion.Version5ofJUnitissplitintoseveralmodulesand,thisway,groupIdandartifactIdwillalsochange.

ItisalsoworthnotingthatthemodulesthatimplementtheinterfacesfromtheSortInterfacemoduleareeventuallydependentonthismodule.Inthiscase,theversionisdefinedasfollows:

<version>${project.version}</version>

Thatseemstobeabittautological(itis,actually).The${project.version}propertyistheversionoftheprojectanditisinheritedbytheSortInterfacemodule.Thisistheversionoftheartifactthattheothermodulesdependon.Inotherwords,themodulesalwaysdependontheversionthatwearecurrentlydeveloping.

Page 215:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 216:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Codethesort

Toimplementthesort,first,wewilldefinetheinterfacesthatasortlibraryshouldimplement.Definingtheinterfacebeforetheactualcodingisagoodpractice.Whentherearemanyimplementations,itissometimesrecommendedtofirstcreateasimpleoneandstartusingitsothattheinterfacemayevolveduringthephase,andwhenthemorecompleximplementationsaredue,thentheinterfacetobeimplementedisalreadyfixed,moreorless.

Page 217:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

packagepackt.java9.by.example.ch03;<br/><br/>publicinterfaceSort{<br/>voidsort(SortableCollectioncollection);<br/>}

packagepackt.java9.by.example.ch03;<br/><br/>publicinterfaceSortableCollection{<br/>}

Page 218:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 219:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CreatingBubbleSortNow,wecanstartcreatingthebubblesortthatimplementstheSortinterface:

packagepackt.java9.by.example.ch03.bubble;

importpackt.java9.by.example.ch03.*;

importjava.util.Comparator;

publicclassBubbleSortimplementsSort{

@Override

publicvoidsort(SortableCollectioncollection){

intn=collection.size();

while(n>1){

for(intj=0;j<n-1;j++){

if(comparator.compare(collection.get(j),

collection.get(j+1))>0){

swapper.swap(j,j+1);

}

}

n--;

}

}

Normally,thealgorithmtoexecuteneedstwooperationsthatweimplementedinthecodelasttimespecifictoaStringarray:comparingtwoelementsandswappingtwoelements.Asthistimethesortimplementationitselfdoesnotknowwhattypetheelementsareusedandalsodoesnotknowifthesomethingitsortsisanarray,alistsorsomethingelse,itneedssomethingthatdoesitforthesortwhenneeded.Moreprecisely,itneedsacomparatorobjectcapableofcomparingtwoelementsanditneedsaswapperobjectthatiscapableofswappingtwoelementsinthecollection.

Togetthose,wecanimplementtwosettermethodsthatcansettheobjectsforthepurposebeforesortisinvoked.Asthisisnotspecifictothebubblesortalgorithmbutisrathergeneral,thesetwomethodsshouldalsobemadeapartoftheinterface,sotheimplementationisoverridingit.

privateComparatorcomparator=null;

@Override

publicvoidsetComparator(Comparatorcomparator){

this.comparator=comparator;

}

privateSwapperswapper=null;

@Override

publicvoidsetSwapper(Swapperswapper){

this.swapper=swapper;

}

}

The@OverrideannotationsignalsfortheJavacompilerthatthemethodisoverridingamethodoftheparentclass,or,asinthiscase,oftheinterface.Amethodcanoverrideaparentmethodwithoutthisannotation;however,ifweusetheannotation,thecompilationfailsifthemethoddoesactuallynotoverridesomething.Thishelpsyoudiscoverduringcompiletimethatsomethingwaschangedintheparentclassorintheinterfaceandwedidnotfollowthatchangeintheimplementation,orthatwejustmadesomemistakethinkingthatwewilloverrideamethodwhenweactuallydonot.Asannotationsareheavilyusedinunittests,wewilltalkaboutannotationsinabitmoredetaillater.

Page 220:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 221:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AmendingtheinterfacesThemodifiedSortinterfacewilllooklikethis:

publicinterfaceSort{

voidsort(SortableCollectioncollection);

voidsetSwapper(Swapperswap);

voidsetComparator(Comparatorcompare);

}

Thisalsomeansthatwewillneedtwonewinterfaces:SwapperandComparator.WeareluckythattheJavaruntimealreadydefinesaComparatorinterfacethatjustfitsthepurpose.Youmayhaveguessedthatfromthefollowingimportstatement:

importjava.util.Comparator;

Whenyouneedsomethingverybasic,likeacomparatorinterface,itismostprobablydefinedintheruntime.Itisadvisabletoconsulttheruntimebeforewritingyourownversion.TheSwapperinterface,however,wewillhavetocreate.

packagepackt.java9.by.example.ch03;

publicinterfaceSwapper{

voidswap(inti,intj);

}

AsitisusedtoswaptwoelementsspecifiedbytheindicesinSortableCollection,thereisamethod,quitetriviallynamedswapforthepurpose.But,wearenotreadyyet.Ifyoutrytocompiletheprecedingcode,thecompilerwillcomplainaboutthegetandsizemethods.Theyareneededbythealgorithmtoimplementthesort,buttheyarenotinherentlypartofthesortingitself.Thisisaresponsibilitythatshouldnotbeimplementedinthesort.Aswedonotknowwhattypeofcollectionswewillsort,itisnotonlyunadvisablebutalsoimpossibletoimplementthesefunctionalitiesinsidethesort.Itseemsthatwejustcannotsortanything.Therearesomerestrictionswewillhavetoset.Thesortingalgorithmmustknowthesizeofthecollectionwesortandalsoshouldhaveaccesstoanelementbyindexsothatitcanpassitontothecomparator.

TheserestrictionsareexpressedintheSortableCollectioninterfacethatwejustleftemptynotknowingbeforethefirstsortimplementationwhatisrequiredtobethere.

packagepackt.java9.by.example.ch03;

publicinterfaceSortableCollection{

Objectget(inti);

intsize();

}

Now,wearereadywiththeinterfacesandtheimplementationandwecangoontestingthecode.But,beforethat,wewillbrieflyreiteratewhatwedidandwhywedidthat.

Page 222:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 223:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ArchitecturalconsiderationsWecreatedaninterfaceandasimpleimplementationofit.Duringtheimplementation,wediscoveredthattheinterfaceneedsotherinterfacesandmethodsthatareneededtosupportthealgorithm.Thisusuallyhappensduringthearchitecturaldesignofthecode,beforeimplementation.Fordidacticalreasons,Ifollowedthebuild-upoftheinterfaceswhilewedevelopedthecode.Inreallife,whenIcreatedtheinterfaces,IcreatedthemallinonestepasIhaveenoughexperience.Iwrotemyfirstquicksortcodearound1983inFortran.However,itdoesnotmeanthatIhitthebull'seyewithjustanyproblemandcomeoutwiththefinalsolution.Itjusthappensthatsortisatoowellknownproblem.Ifyouneedtomodifytheinterfacesorotheraspectsofyourdesignduringdevelopment,donotfeelembarrassed.Itisanaturalconsequenceandaproofthatyouunderstandthingsbetterandbetterastimegoesby.Ifthearchitectureneedschange,itisbettertobedonethannot,andthesooneritis,thebetter.Inreallifeenterpriseenvironments,wewilldesigninterfacesjusttolearnduringdevelopmentthatthereweresomeaspectsthatweforgot.Theyareverytrueandbitmorecomplexoperationsthansortingacollection.

Inthecaseofthesortingproblem,weabstractedthesomethingwewanttosorttothemostpossibleextreme.TheJavabuildinsortcansortarraysorlists.Ifyouwanttosortsomethingthatisnotalistoranarray,youhavetocreateaclassthatimplementsthejava.util.Listinterfacewithmorethan24methodsitrequirestowrapyoursortableobjecttomakeitsortablebytheJDKsort.Tobehonest,thatisnottoomany,andinareal-worldproject,Iwouldconsiderthatasanoption.

However,wedonot,andcannotknow,whatmethodsoftheinterfacethebuilt-insortuses.Thosethatareusedshouldbefunctionallyimplementedandthosethatarenot,cancontainasimplereturnstatementbecausetheyarejustneverinvoked.AdevelopercanconsultthesourcecodeoftheJDKandseewhatmethodsareactuallyused,butthatisnotthecontractofthesearchimplementation.Itisnotguaranteedthatanewversionwillstilluseonlythosemethods.Ifanewversionstartstouseamethodthatweimplementedwithasinglereturnstatement,thesortwillmagicallyfail.

ItisalsoaninterestingperformancequestionhowtheswappingoftwoelementsisimplementedbythesearchusingonlytheListinterface.Thereisnoput(int,Object)methodintheListinterface.Thereisadd(intObject),butthatinsertsanewelementanditmaybeextremelycostly(burningCPU,disk,energy)topushallelementsofthelistupiftheobjectsarestored,forexample,ondisk.Furthermore,thenextstepmayberemovingtheelementaftertheonewejustinserted,doingthecostlyprocessofmovingthetailofthelistagain.Thatis,thetrivialimplementationofput(int,Object)thatthesortmayormaynotfollow.Again,thisissomethingthatshouldnotbeassumed.

Whendevelopersuselibraries,classes,andmethodsfromtheJDK,opensource,orcommerciallibraries,thedevelopersmayconsultthesourcecodebuttheyshouldnotrelyontheimplementation.YoushouldrelyonlyonthecontractandthedefinitionoftheAPIthatthelibrarycomeswith.Whenyouimplementaninterfacefromsomeexternallibrary,andyoudonotneedtoimplementsomepartofit,andcreatesomedummymethods,feelthedangerintheair.Itisanambush.Itislikelythateitherthelibraryispoorqualityoryoudidnotunderstandhowtouseit.

Inourcase,weseparatedtheswappingandthecomparisonfromthesort.Thecollectionshouldimplementtheseoperationsandprovidethemforthesort.Thecontractistheinterface,andtousethesort,

Page 224:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

youhavetoimplementallmethodsoftheinterfaceswedefined.

TheinterfaceofSortdefinessettersthatsetSwapperandComparator.HavingdependenciessetthatwaymayleadtoacodethatcreatesanewinstanceofaclassimplementingtheSortinterface,butdoesnotsetSwapperandComparatorbeforeinvokingSort.ThiswillleadtoNullPointerExceptionthefirsttimetheComparatorisinvoked(orwhentheSwapperisinvokedincasetheimplementationinvokesthatfirst,whichisnotlikely,butpossible).Thecallingmethodshouldinjectthedependenciesbeforeusingtheclass.Whenitisdonethroughsetters,itiscalledsetterinjection.ThisterminologyisheavilyusedwhenweuseframeworkssuchasSpring,Guice,orsomeothercontainer.Creatingtheseserviceclassesandinjectingtheinstanceintoourclassesisfairlysimilarallthetime.

Containerimplementationscontainthefunctionalityinageneralwayandprovideconfigurationoptionstoconfigurewhatinstancesaretobeinjectedintowhatotherobjects.Usually,thisleadstoshorter,moreflexible,andmorereadablecode.However,dependencyinjectionisnotexclusivetocontainers.Whenwewritethetestingcodeinthenextsection,andinvokethesetters,weactuallydodependencyinjection.

Thereisanotherwayofdependencyinjectionthatavoidstheproblemofdependenciesnotbeingset.Thisiscalledconstructorinjection.Thedependenciesarefinalprivatefieldswithnovalues.Rememberthatthesefieldsshouldgettheirfinalvaluesbythetimetheconstructorfinishes.Constructorinjectionpassestheinjectedvaluestotheconstructorasargumentsandtheconstructorsetsthefields.Thisway,thefieldsareguaranteedtobesetbythetimetheobjectwasconstructed.Thisinjection,however,cannotbedefinedinaninterface.

Now,wealreadyhavethecode,andweknowtheconsiderationsofhowtheinterfaceswerecreated.Thisisthetimetodosometesting.

Page 225:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 226:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CreatingunittestsWhenwewritecode,weshouldtestit.Nocodehasevergoneintoproductionbeforeatleastdoingsometestruns.Therearedifferentlevelsoftestshavingdifferentaims,technologies,industrypractices,andnames.

Unittests,asthenamesuggests,testaunitofcode.Integrationteststesthowtheunitsintegratetogether.Smoketeststestalimitedsetofthefeaturesjusttoseethatthecodeisnottotallybroken.Thereareothertests,untilthefinaltest,whichistheproofofthework:useracceptancetest.Proofofthepuddingiseatingit.Acodeisgoodiftheuseracceptsit.

Manytimes,Itelljuniorsthatthenameuseracceptancetestisabitmisleading,becauseitisnottheuserwhoacceptstheresultofaproject,butthecustomer.Bydefinition,thecustomeristhepersonwhopaysthebill.Professionaldevelopmentispaid;otherwise,itisnotprofessional.Theterminologyis,however,useracceptancetest.Itjusthappensthatcustomersaccepttheprojectonlyiftheuserscanusetheprogram.

WhenwedevelopinJava,unittestistestingstandaloneclasses.Inotherwords,inJavadevelopment,aunitisaclasswhenwetalkaboutunittests.Tofurnishunittests,weusuallyusetheJUnitlibrary.Thereareotherlibraries,suchasTestNG,butJUnitisthemostwidelyused,sowewilluseJUnit.Touseitasalibrary,first,wewillhavetoaddittotheMavenPOMasadependency.

Page 227:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 228:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AddingJUnitasdependencyRecallthatwehaveamulti-moduleproject,andthedependencyversionsaremaintainedintheparentPOMunderthedependencyManagementtag.

<dependencyManagement>

<dependencies>

...

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>

</dependencies>

</dependencyManagement>

Thescopeofthedependencyistest,whichmeansthatthislibraryisneededonlytocompilethetestcodeandduringtheexecutionofthetest.TheJUnitlibrarywillnotmakeitswaytothefinalreleasedproduct;thereisnoneedforit.IfyoufindtheJUnitlibraryinsomedeployedproductionWebArchive(WAR)file,suspectthatsomebodywasnotproperlymanagingthescopesofthelibraries.

MavensupportsthecompilationandtheexecutionofJUnittestsinthelifecycleoftheproject.Ifwewanttoexecutethetests,onlywecanissuethemvntestcommand.TheIDEsalsosupporttheexecutionoftheunittests.Usually,thesamemenuitemthatcanbeusedtoexecuteaclassthathasapublicstaticmainmethodcanbeused.IftheclassisaunittestutilizingJUnit,theIDEwillrecognizeitandexecutethetestsandusuallygiveagraphicalfeedbackonwhattestwasexecutingfineandwhichonesfailed,andhow.

Page 229:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 230:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WritingtheBubbleSortTestclassThetestclassesareseparatedfromtheproductionclasses.Theygointothesrc/test/javadirectory.Whenwehaveaclassnamed,forexample,BubbleSort,thenthetestwillbenamedBubbleSortTest.Thisconventionhelpstheexecutingenvironmenttoseparatethetestsfromthoseclassesthatdonotcontaintestsbutareneededtoexecutethetests.Totestthesortimplementationwehavejustcreated,wecanfurnishaclassthatcontains,fornow,asinglecanSortStringsmethod.

Unittestmethodnamesareusedtodocumentthefunctionalitybeingtested.AstheJUnitframeworkinvokeseachandeverymethodthathasthe@Testannotation,thenameofthetestisnotreferencedanywhereinourcode.Wecanbravelyusearbitrarylongmethodnames;itwillnothinderreadabilityattheplacewherethemethodisinvoked.

packagepackt.java9.by.example.ch03.bubble;

//importsdeletedfromprint

publicclassBubbleSortTest{

@Test

publicvoidcanSortStrings(){

ArrayListactualNames=newArrayList(Arrays.asList(

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

));

ThemethodcontainsArrayListwiththeactualnamesthatwehavealreadygottenfamiliarwith.AswehaveasortimplementationandinterfacethatneedsSortableCollection,wewillcreateonebackedupbyArrayList.

SortableCollectionnamesCollection=newSortableCollection(){

@Override

publicObjectget(inti){

returnactualNames.get(i);

}

@Override

publicintsize(){

returnactualNames.size();

}

};

WedeclaredanewobjectthathastheSortableCollectiontype,whichisaninterface.ToinstantiatesomethingthatimplementsSortableCollection,wewillneedaclass.Wecannotinstantiateaninterface.Inthiscase,definetheclassintheplaceoftheinstantiation.ThisiscalledananonymousclassinJava.Thenamecomesfromthefactthatthenameofthenewclassisnotdefinedinthesourcecode.TheJavacompilerwillautomaticallycreateanameforthenewclass,butthatisnotinterestingfortheprogrammers.WewillsimplywritenewSortableCollection()andprovidetheneededimplementationimmediatelyfollowingbetween{and}.Itisveryconvenienttodefinethisanonymousclassinsidethemethodas,thisway,itcanaccessArrayListwithoutpassingareferencetoArrayListintheclass.

Asamatteroffact,thereferenceisneeded,buttheJavacompilerautomaticallydoesthis.TheJavacompiler,inthiscase,alsotakescarethatautomaticreferencepassingthiswaycanonlybedoneusingvariablesthatwereinitializedandwillnotchangeduringtheexecutionofthecodeaftertheinstantiationoftheanonymousclass.ThevariableactualNameswassetanditshouldnotbechangedinthemethodlater.

Page 231:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Asamatteroffact,wecanevendefineactualNamestobefinalandthiswouldhavebeenarequirementifweusedJava1.7orearlier.Startingwith1.8,therequirementisthatthevariableiseffectivelyfinal,butyouneednotdeclareittobefinal.

ThenextthingthatweneedisaSwapperimplementationforArrayList.Inthiscase,wewilldefineawholeclassinsidethemethod.Itcanalsobeananonymousclass,butthistimeIdecidedtouseanamedclasstodemonstratethataclasscanbedefinedinsideamethod.Usually,wedonotdothatinproductionprojects.

classSwapActualNamesArrayElementsimplementsSwapper{

@Override

publicvoidswap(inti,intj){

finalObjecttmp=actualNames.get(i);

actualNames.set(i,actualNames.get(j));

actualNames.set(j,tmp);

}

}

Last,butnotleast,wewillneedacomparatorbeforewecaninvokethesort.AswehaveStringstocompare,thisiseasyandstraightforward.

ComparatorstringCompare=newComparator(){

@Override

publicintcompare(Objectfirst,Objectsecond){

finalStringf=(String)first;

finalStrings=(String)second;

returnf.compareTo(s);

}

};

Havingeverythingpreparedforthesorting,wewillfinallyneedaninstanceoftheSortimplementation,setthecomparatorandtheswapper,andinvokethesort.

Sortsort=newBubbleSort();

sort.setComparator(stringCompare);

sort.setSwapper(newSwapActualNamesArrayElements());

sort.sort(namesCollection);

Thelast,butmostimportantpartofthetestistoassertthattheresultistheonethatweexpect.JUnithelpsusdothatwiththeaidoftheAssertclass.

Assert.assertEquals(Arrays.asList("Abraham","Dagobert","Johnson","Wilkinson","Wilson"),actualNames);

}

}

ThecalltoassertEqualschecksthatthefirstargument,theexpectedresult,equalsthesecondargument,thesortedactualNames.Iftheydiffer,thenAssertionErroristhrown;otherwise,thetestjustfinishesfine.

Page 232:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 233:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GoodunittestsIsthisagoodunittest?Ifyoureaditinatutorialbooklikethis,ithastobe.Actually,itisnot.ItisagoodcodetodemonstratesomeofthetoolsthatJUnitprovidesandsomeJavalanguagefeatures,butasarealJUnittest,Iwillnotuseitinareallifeproject.

Whatmakesaunittestgood?Toanswerthisquestion,wewillhavetofindwhattheunittestisgoodforandwhatitisthatweuseitfor.

Wewillcreateunitteststovalidatetheoperationoftheunitsandtodocument.

Unittestsarenottofindbugs.Developerseventuallyuseunittestsduringdebuggingsessionsbut,manytimes,thetestingcodecreatedforthedebuggingisatemporaryone.Whenthebugisfixed,thecodeusedtofinditwillnotgetintothesourcecode.Foreverynewbug,thereshouldbeanewtestcreatedthatcoversthefunctionalitythatwasnotproperlyworking,butitishardlythetestcodethatisusedtofindthebug.Thisisbecauseunittestsaremainlyfordocumentation.YoucandocumentaclassusingJavaDoc,buttheexperienceshowsthatthedocumentationoftenbecomesoutdated.Thedevelopersmodifythecode,buttheydonotmodifythedocumentation,andthedocumentationbecomesobsoleteandmisleading.Unittests,however,areexecutedbythebuildsystemandifContinuousIntegration(CI)isinuse(anditshouldbe,inaprofessionalenvironment),thenthebuildwillbebrokenifatestfails,alldeveloperswillgetmailnotificationaboutit,anditwilldrivethedeveloperbreakingthebuildtofixthecodeorthetest.Thisway,thetestsverifythatcontinuousdevelopmentdidnotbreakanythinginthecodeor,atleast,notsomethingthatcanbediscoveredusingunittests.

Page 234:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 235:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AgoodunittestisreadableOurtestisfarfrombeingreadable.Atestcaseisreadableifyoulookatitandin15secondsyoucantellwhatitdoes.Itassumes,ofcourse,someexperienceinJavaonbehalfofthereader,butyougetthepoint.Ourtestisclutteredwithsupportclassesthatarenotcoretothetest.

Ourtestalsohardlyvalidatesthatthecodeisworkingproperly.Itactuallydoesnot.TherearesomebugsinitthatIputtheredeliberately,whichwewilllocateandzapinthefollowingsections.OnesingletestthatsortsasingleStringarrayisfarfromvalidatingasortimplementation.IfIweretoextendthistesttoareal-worldtest,wewouldneedmethodsthatwouldhavethenamecanSortEmptyCollection,canSortOneElementCollection,canSortTwoElements,canSortReverseOrder,orcanSortAlreadySorted.Ifyoulookatthenames,youwillseewhattestsweneed.Comingfromthenatureofthesortproblem,animplementationmaybereasonablysensitivetoerrorsinthesespecialcases.

Whatarethegoodpointsinourunittest,inadditiontoitbeinganacceptabledemonstrationtool?

Page 236:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 237:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Unittestsarefast

Ourunittestrunsfast.Asweexecuteunittestseachtime,theCIfiresupabuildandtheexecutionofthetestsshouldnotlastlong.Youshouldnotcreateaunittestsortingbillionsofelements.Thatisakindofstabilityorloadtestandtheyshouldruninseparatetestperiodsandnoteverytimethebuildisrunning.Ourunittestsortsfiveelementsthatarereasonable.

Page 238:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 239:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Unittestsaredeterministic

Ourunittestisdeterministic.Non-deterministicunittestsarethenightmareofthedevelopers.IfyouareinagroupwheresomebuildsbreakontheCIserver,andwhenabuildbreaks,yourfellowdevelopersaysthatyoujusthavetotryitagain;noway!Ifaunittestruns,itshouldrunalltimes.Ifitfails,itshouldfailnomatterhowmanytimesyoustartit.Anon-deterministicunittest,inourcase,willbetorenderrandomnumbersandhavethemsorted.Wewillendupwithdifferentarraysineachtestrunand,incasethereissomebuginthecodethatmanifestsforsomearray,wewillnotbeabletoreproduceit.Nottomentionthattheassertionthatthecodewasrunningfineisalsodifficult.

Ifwesortedarandomarrayinaunittest(somethingwedonot),wecould,hypothetically,assertthatthearrayissorted,comparingtheelementsoneaftertheothercheckingthattheyareinascendingorder.Itwouldalsobeatotallywrongpractice.

Page 240:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 241:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Assertionsshouldbeassimpleaspossible

Iftheassertioniscomplex,theriskofintroducingbugsintheassertionishigher.Themorecomplextheassertion,thehighertherisk.Wewillwritetheunitteststoeaseourlivesandnottohavemorecodetodebug.

Additionally,onetestshouldassertonlyonething.ThisoneassertionmaybecodedwithmultipleAssertclassmethods,oneaftertheother.Still,theaimoftheseistoassertthecorrectnessofonesinglefeatureoftheunit.RemembertheSRP:onetest,onefeature.Agoodtestislikeagoodsniper:oneshot,onekill.

Page 242:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 243:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

UnittestsareisolatedWhenwetestaunitA,anychangeinanotherunitB,orabuginadifferentunitshouldnotaffectourunittestthatisfortheunitA.Inourcase,itwaseasybecausewehaveonlyoneunit.Later,whenwedevelopthetestforthequicksort,wewillseethatthisseparationisnotthatsimple.

Iftheunittestsareproperlyseparated,afailingunittestclearlypointsoutthelocationoftheproblem.Itisintheunitwheretheunittestfailed.Iftestsdonotseparatetheunits,thenafailureinonetestmaybecausedbyabuginadifferentunitthanweexpect.Inthiscase,thesetestsarenotreallyunittests.

Inpractice,youshouldmakeabalance.Iftheisolationoftheunitswillbetoocostly,youcandecidetocreateintegrationtests;and,iftheystillrunfast,havethemexecutedbytheCIsystem.Atthesametime,youshouldalsotrytofindoutwhytheisolationishard.Ifyoucannoteasilyisolatetheunitsinthetests,itmeansthattheunitsaretoostronglycoupled,whichmaynotbeagooddesign.

Page 244:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 245:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

UnittestscoverthecodeUnittestsshouldtestallusualandalsoallspecialcasesofthefunctionality.Ifthereisaspecialcaseofcodethatisnotcoveredbytheunittest,thecodeisindanger.Incaseofasortimplementation,thegeneralcaseissorting,sayfiveelements.Thespecialcasesaremuchmorenumeroususually.Howdoesourcodebehaveifthereisonlyoneelementoriftherearenoelements?Whatiftherearetwo?Whatiftheelementsareinreverseorder?Whatiftheyarealreadysorted?

Usually,thespecialcasesarenotdefinedinthespecification.Theprogrammerhastothinkaboutitbeforecoding,andsomespecialcasesarediscoveredduringcoding.Thehardthingisthatyoujustcannottellifyoucoveredallspecialcasesandthefunctionalityofthecode.

Whatyoucantellisifallthelinesofcodewereexecutedduringthetestingornot.If90%ofthecodelinesareexecutedduringthetests,thenthecodecoverageis90%,whichisfairlygoodinreallife,butyoushouldneverbecontentwithanythinglessthan100%.

Codecoverageisnotthesameasfunctionalcoverage,butthereisacorrelation.Ifthecodecoverageislessthan100%,thenatleastoneofthefollowingtwostatementsistrue:

Thefunctionalcoverageisnot100%Thereisunusedcodeinthetestedunit,whichcanjustbedeleted

Thecodecoveragecanbemeasured,thefunctionalcoveragecannot.ThetoolsandIDEssupportcodecoveragemeasurement.Thesemeasurementsareintegratedintotheeditorsoyouwillnotonlygetthepercentageofthecoverage,buttheeditorwillshowyouexactlywhichlinesarenotcoveredbythecoveragecoloringthelines(inEclipse,forexample)orthegutterontheleftsideoftheeditorwindow(IntelliJ).ThepictureshowsthatinIntelliJ,thetestscoverthelinesindicatedbyagreencoloronthegutter.(Intheprintversionthisisjustagreyrectangle).

Page 246:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 247:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RefactorthetestNowthatwehavediscussedwhatagoodunittestis,let'simproveourtest.Thefirstthingistomovethesupportingclassestoseparatefiles.WewillcreateArrayListSortableCollection:

packagepackt.java9.by.example.ch03.bubble;

importpackt.java9.by.example.ch03.SortableCollection;

importjava.util.ArrayList;

publicclassArrayListSortableCollectionimplementsSortableCollection{

finalprivateArrayListactualNames;

ArrayListSortableCollection(ArrayListactualNames){

this.actualNames=actualNames;

}

@Override

publicObjectget(inti){

returnactualNames.get(i);

}

@Override

publicintsize(){

returnactualNames.size();

}

}

ThisclassencapsulatesArrayListandthenimplementsthegetandsizemethodstoArrayListaccess.ArrayListitselfisdeclaredasfinal.Recallthatafinalfieldhastobedefinedbythetimetheconstructorfinishes.Thisguaranteesthatthefieldistherewhenwestarttousetheobjectandthatitdoesnotchangeduringtheobjectlifetime.Note,however,thatthecontentoftheobject,inthiscase,theelementsofArrayList,maychange.Ifitwerenotthecase,wewouldnotbeabletosortit.

ThenextclassisStringComparator.ThisissosimplethatIwillnotlistithere;Iwillleaveittoyoutoimplementthejava.util.ComparatorinterfacethatcancomparetwoStrings.Itshouldnotbedifficult,especiallyasthisclasswasalreadyapartofthepreviousversionoftheBubbleSortTestclass(hint:itwasananonymousclassthatwestoredinthevariablenamedstringCompare).

WealsohavetoimplementArrayListSwapper,whichalsoshouldnotbeabigsurprise.

packagepackt.java9.by.example.ch03.bubble;

importpackt.java9.by.example.ch03.Swapper;

importjava.util.ArrayList;

publicclassArrayListSwapperimplementsSwapper{

finalprivateArrayListactualNames;

ArrayListSwapper(ArrayListactualNames){

this.actualNames=actualNames;

}

@Override

publicvoidswap(inti,intj){

Objecttmp=actualNames.get(i);

actualNames.set(i,actualNames.get(j));

actualNames.set(j,tmp);

}

}

Page 248:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Finally,ourtestwilllookthis:

packagepackt.java9.by.example.ch03.bubble;

//...importsdeletedfromprint...

publicclassBubbleSortTest{

@Test

publicvoidcanSortStrings(){

ArrayListactualNames=newArrayList(Arrays.asList(

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

));

ArrayListexpectedResult=newArrayList(Arrays.asList(

"Abraham","Dagobert",

"Johnson","Wilkinson","Wilson"

));

SortableCollectionnames=

newArrayListSortableCollection(actualNames);

Sortsort=newBubbleSort();

sort.setComparator(

newStringComparator());

sort.setSwapper(

newArrayListSwapper(actualNames));

sort.sort(names);

Assert.assertEquals(expectedResult,actualNames);

}

}

Nowthisisalreadyatestthatcanbeunderstoodin15seconds.Itdocumentswellhowtouseasortimplementationthatwedefined.Itstillworksanddoesnotrevealanybug,asIpromised.

Page 249:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 250:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CollectionswithwrongelementsThebugisnottrivial,andasusual,thisisnotintheimplementationofthealgorithm,butratherinthedefinition,orthelackofit.Whatshouldtheprogramdoiftherearenotonlystringsinthecollectionthatwesort?

IfIcreateanewtestthatstartswiththefollowinglines,itwillthrowClassCastException:

@Test

publicvoidcanNotSortMixedElements(){

ArrayListactualNames=newArrayList(Arrays.asList(

42,"Wilson",

"Wilkinson","Abraham","Dagobert"

));

...therestofthecodeisthesameastheprevioustest

TheproblemhereisthatJavacollectionscancontainanytypeofelements.Youcannoteverbesurethatacollection,suchasArrayList,containsonlythetypesthatyouexpect.Evenifyouusegenerics(wehavenotlearnedthat,butwewillinthischapter),thechancesofabugsomehowconjuringupsomeobjectofaninappropriatetypeintoacollection,aresmallerbutarestillthere.Don'taskmehow;Icannottellyou.Thisisthenatureofthebugs—youcannottellhowtheyworkuntilyouzapthem.Thethingisthatyouhavetobepreparedforsuchanexceptionalcase.

Page 251:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 252:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HandlingexceptionsExceptionalcasesshouldbehandledinJavausingexceptions.TheClassCastExceptionisthereandithappenswhenthesorttriestocompareStringtoIntegerusingStringComparator,andtodothat,ittriestocastanIntegertoString.

Whenanexceptionisthrownbytheprogramusingthethrowcommand,orbytheJavaruntime,theexecutionoftheprogramstopsatthatpoint,andinsteadofexecutingthenextcommand,itcontinueswheretheexceptioniscaught.Itcanbeinthesamemethod,orinsomecallingmethodupinthecallchain.Tocatchanexception,thecodethrowingtheexceptionshouldbeinsideatryblock,andthecatchstatementfollowingthetryblockshouldspecifyanexceptionthatiscompatiblewiththeexceptionthrown.

Iftheexceptionisnotcaught,thentheJavaruntimewillprintoutthemessageoftheexceptionalongwithastacktracethatwillcontainalltheclasses,methods,andlinenumbersonthecallstackatthetimeoftheexception.Inourcase,themvntestcommandwillproducethefollowingtraceintheoutput:

java.lang.ClassCastException:java.lang.Integercannotbecasttojava.lang.String

atpackt.java9.by.example.ch03.bubble.StringComparator.compare(StringComparator.java:9)

atpackt.java9.by.example.ch03.bubble.BubbleSort.sort(BubbleSort.java:13)

atpackt.java9.by.example.ch03.bubble.BubbleSortTest.canNotSortMixedElements(BubbleSortTest.java:49)

atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)

atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

atjava.lang.reflect.Method.invoke(Method.java:498)

...somelinesdeletedfromtheprint

atorg.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)

atorg.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)

atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)

atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

...somelinesdeletedfromtheprint

atorg.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)

atorg.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)

atorg.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Thisstacktraceisnotreallylong.Intheproductionenvironmentinanapplicationthatrunsonanapplicationserver,thestacktracemaycontainafewhundredelements.Inthistrace,youcanseethatMavenwasstartingthetestexecution,involvedMavensurefireplugin,andthentheJUnitexecutor,untilwegetthroughthetesttothecomparator,wheretheactualexceptionwasthrown.

ThisexceptionwasnotprintedbytheJavaruntimetotheconsole.ThisexceptioniscaughtbytheJUnitlibrarycodeandthestacktraceisloggedouttotheconsoleusingMavenloggingfacility.

Theproblemwiththisapproachisthattherealissueisnottheclasscastingfailure.Therealissueisthatthecollectioncontainsmixedelements.ItisonlyrealizedbytheJavaruntimewhenittriestocasttwoincompatibleclasses.Ourcodecanbesmarter.Wecanamendthecomparator.

packagepackt.java9.by.example.ch03.bubble;

importjava.util.Comparator;

publicclassStringComparatorimplementsComparator{

@Override

publicintcompare(Objectfirst,Objectsecond){

try{

finalStringf=(String)first;

finalStrings=(String)second;

returnf.compareTo(s);

}catch(ClassCastExceptioncce){

thrownewNonStringElementInCollectionException(

Page 253:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

"Therearemixedelementsinthecollection.",cce);

}

}

}

ThiscodecatchestheClassCastExceptionandthrowsanewone.Theadvantageofthrowinganewexceptionisthatyoucanbesurethatthisexceptionisthrownfromthecomparatorandthattheproblemreallyisthattherearemixedelementsinthecollection.Classcastingproblemsmayhappenatotherplacesofthecodeaswell,insidesomeofthesortimplementations.Someapplicationcodemaywanttocatchtheexceptionandwanttohandlethecase;forexample,sendinganapplication-specificerrormessageandnotdumpingonlyastacktracetotheuser.ThiscodecancatchClassCastExceptionaswell,butitcannotbesurewhattherealcauseoftheexceptionis.Ontheotherhand,NonStringElementInCollectionExceptionisdefinite.

TheNonStringElementInCollectionExceptionisanexceptionthatdoesnotexistintheJDK.Wewillhavetocreateit.ExceptionsareJavaclassesandourexceptionlooksasfollows:

packagepackt.java9.by.example.ch03.bubble;

publicclassNonStringElementInCollectionExceptionextendsRuntimeException{

publicNonStringElementInCollectionException(Stringmessage,Throwablecause){

super(message,cause);

}

}

Javahasthenotionofcheckedexceptions.ItmeansthatanyexceptionthatisnotextendingRuntimeExceptionshouldbedeclaredinthemethoddefinition.Supposeourexceptionwasdeclaredasfollows:

publicclassNonStringElementInCollectionExceptionextendsException

Then,wewillhavetodeclarethecomparemethodasfollows:

publicintcompare(Objectfirst,Objectsecond)throwsNonStringElementInCollectionException

Theproblemisthattheexceptionamethodthrowsispartofthemethodsignature,andthiswaycomparewillnotoverridethecomparemethodoftheinterface,and,thatway,theclasswillnotimplementtheComparatorinterface.Thus,ourexceptionhastobearuntimeexception.

Therecanbeahierarchyofexceptionsinanapplication,andoften,noviceprogrammerscreatehugehierarchiesofthem.Ifthereissomethingyoucando,itdoesnotmeanthatyoushoulddoit.Hierarchiesshouldbekeptasflataspossible,andthisisespeciallytrueforexceptions.IfthereisanexceptionintheJDKthatdescribestheexceptionalcase,thenusethereadymadeexception.Justaswellasforanyotherclass:ifitisready,donotimplementitagain.

Itisalsoimportanttonotethatthrowinganexceptionshouldonlybedoneinexceptionalcases.Itisnottosignalsomenormaloperationalcondition.DoingthathindersreadabilityofthecodeandalsoeatsCPU.ThrowinganexceptionisnotaneasytaskfortheJVM.

Itisnotonlytheexceptionthatcanbethrown.Thethrowcommandcanthrow,andthecatchcommandcancatchanythingthatextendstheThrowableclass.TherearetwosubclassesofThrowable:Error,andException.TheErrorexceptionisthrownifsomeerrorhappenedduringtheexecutionoftheJavacode.ThetwomostinfamouserrorsareOutOfMemoryErrorandStackOverflowError.Ifanyofthesehappens,youcannotdoanythingreliablytocatchtheerror.

Page 254:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThereisalsoInternalErrorandUnknownErrorintheJVM,butsinceJVMisfairlystable,youwillhardlyevermeettheseerrors.

Whenanyofthoseerrorshappen,trytodebugthecodeandtrytofindoutwhyyouusethatmuchmemoryorsuchdeepmethodcallsandtrytooptimizeyoursolution.WhatIhavejustsaidaboutcreatingexceptionhierarchiesistrueagaintocatcherrors.Thefactthatyoucancatcherrorsdoesnotmeanthatyoushould.Onthecontrary,youshouldnevercatchanerrorand,especially,neverevercatchaThrowable.

Thisway,wehandledthisspecialcasewhensomeprogrammeraccidentallywrites42amongthenames,butwillitbeniceriftheerrorwasidentifiedduringcompiletime?Todothat,wewillintroducegenerics.

Justalastthoughtbeforewegothere.WhatclassbehaviordowetestwiththecanNotSortMixedElementsunittest?ThetestisinsidetheBubbleSortTesttestclass,butthefunctionalityisinthecomparatorimplementation,StringComparator.Thistestcheckssomethingthatisoutofthescopeoftheunittestclass.Icanuseitfordemonstrationpurposes,butthisisnotaunittest.Therealfunctionalityofthesortimplementationcanbeformulizedthisway:whateverexceptionthecomparatorthrowsisthrownbythesortimplementation.Youcantrytowritethisunittest,orreadon;wewillhaveitinthenextsection.

TheStringComparatorclassdoesnothaveatestclassbecauseStringComparatorispartofthetestandwewillneverwriteatestforatest.Otherwise,wewillsinkintoanendlessrabbithole.

Page 255:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 256:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GenericsThegenericsfeaturewasintroducedintoJavainversion5.Tostartwithanexample,ourSortableinterfaceuntilnowwasthis:

packagepackt.java9.by.example.ch03;

publicinterfaceSortableCollection{

Objectget(inti);

intsize();

}

Afterintroducinggenerics,itwillbeasfollows:

packagepackt.java9.by.example.ch03;

publicinterfaceSortableCollection<E>{

Eget(inti);

intsize();

}

TheEidentifierdenotesatype.Itcanbeanytype.Itsaysthataclassisasortablecollectionifitimplementstheinterface,namelythetwomethods—sizeandget.ThegetmethodshouldreturnsomethingthatisoftypeE,whateverEis.Thismaynotmaketoomuchsenseupuntilnow,butyouwillsoongetthepoint.Afterall,genericsisadifficulttopic.

TheSortinterfacewillbecomethefollowing:

packagepackt.java9.by.example.ch03;

importjava.util.Comparator;

publicinterfaceSort<E>{

voidsort(SortableCollection<E>collection);

voidsetSwapper(Swapperswap);

voidsetComparator(Comparator<E>compare);

}

Thisstilldoesnotprovidemuchmorevaluethanthepreviousversionwithoutgenerics,but,atleast,itdoessomething.IntheactualclassimplementingtheSortinterface,ComparatorshouldacceptthesametypethatSortableCollectionuses.ItisnotpossiblethatSortableCollectionworksonstringsandweinjectacomparatorforintegers.

TheimplementationofBubbleSortisasfollows:

packagepackt.java9.by.example.ch03.bubble;

importpackt.java9.by.example.ch03.*;

importjava.util.Comparator;

publicclassBubbleSort<E>implementsSort<E>{

@Override

publicvoidsort(SortableCollection<E>collection){

...sortcodesameasbefore

}

privateComparator<E>comparator=null;

@Override

publicvoidsetComparator(Comparator<E>comparator){

this.comparator=comparator;

}

...methodswappersameasbefore

}

Therealpowerofgenericswillcomewhenwewillwritethetests.Thefirsttestdoesnotchangemuch,

Page 257:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

althoughwiththegenerics,itismoredefinite.

@Test

publicvoidcanSortStrings(){

ArrayList<String>actualNames=newArrayList<>(Arrays.asList(

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

));

ArrayList<String>expectedResult=newArrayList<>(Arrays.asList(

"Abraham","Dagobert",

"Johnson","Wilkinson","Wilson"

));

SortableCollection<String>names=

newArrayListSortableCollection<>(actualNames);

Sort<String>sort=newBubbleSort<>();

sort.setComparator(String::compareTo);

sort.setSwapper(newArrayListSwapper<>(actualNames));

sort.sort(names);

Assert.assertEquals(expectedResult,actualNames);

}

WhenwedefineArrayList,wewillalsodeclarethattheelementsofthelistwillbestrings.WhenweallocatethenewArrayList,thereisnoneedtospecifyagainthattheelementsarestringsbecauseitcomesfromtheactualelementsthere.Eachofthemisastring;therefore,thecompilerknowsthattheonlythingthatcancomebetweenthe<and>characterisString.

Thetwocharacters<and>,withoutthetypedefinitioninbetween,iscalleddiamondoperator.Thetypeisinferred.Ifyougetusedtogenerics,thiscodebringsyoumoreinformationonthetypesthatthecollectionsworkonandthecodebecomesmorereadable.Thereadabilityandtheextrainformationisnottheonlypoint.

AsweknowthattheComparatorargumentisComparator<String>now,wecanuseadvancedfeaturesofJavaavailablesinceJava8andcanpasstheString::compareTomethodreferencetothecomparatorsetter.

Thesecondtestistheimportantoneforusnow.ThisisthetestwhichensuresthatSortdoesnotinterferewiththeexceptionthatthecomparatorthrows.

@Test(expected=RuntimeException.class)

publicvoidthrowsWhateverComparatorDoes(){

ArrayList<String>actualNames=newArrayList<>(Arrays.asList(

42,"Wilson",

"Wilkinson","Abraham","Dagobert"

));

SortableCollection<String>names=

newArrayListSortableCollection<>(actualNames);

Sort<String>sort=newBubbleSort<>();

sort.setComparator((Stringa,Stringb)->{

thrownewRuntimeException();

});

finalSwapperneverInvoked=null;

sort.setSwapper(neverInvoked);

sort.sort(names);

}

Thethingis,thatitdoesnotevencompile.ThecompilersaysthatitcannotinferthetypeofArrayList<>onthethirdline.WhenalltheargumentsoftheasListmethodwerestrings,themethodreturnedalistofStringelementsandthereforethenewoperatorwasknowntogenerateArrayList<String>.Thistime,thereisaninteger,andthus,thecompilercannotinferthatArrayList<>isforStringelements.

TochangethetypedefinitionfromArrayList<>toArrayList<String>isnotacure.Inthatcase,thecompiler

Page 258:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

willcomplainaboutthevalue42.Thisisthepowerofgenerics.Whenyouuseclassesthathavetypeparameters,thecompilercandetectwhenyouprovideavalueofthewrongtype.TogetthevalueintoArrayListtocheckthattheimplementationreallythrowsanexception,wewillhavetoconjurethevalueintoit.Wecantrytoreplacethevalue42withanemptyStringandthenaddthefollowinglinewhichwillstillnotcompile:

actualNames.set(0,42);

ThecompilerwillstillknowthatthevalueyouwanttosetinArrayListissupposedtobeString.TogetthearraywiththeIntegerelement,youwillhavetoexplicitlyunlockthesafetyhandleandpullthetrigger,shootingyourself:

((ArrayList)actualNames).set(0,42);

Now,thetestlookslikethis:

@Test(expected=RuntimeException.class)

publicvoidthrowsWhateverComparatorDoes(){

ArrayList<String>actualNames=newArrayList<>(Arrays.asList(

"","Wilson",

"Wilkinson","Abraham","Dagobert"

));

((ArrayList)actualNames).set(0,42);

SortableCollection<String>names=

newArrayListSortableCollection<>(actualNames);

Sort<String>sort=newBubbleSort<>();

sort.setComparator((a,b)->{

thrownewRuntimeException();

});

finalSwapperneverInvoked=null;

sort.setSwapper(neverInvoked);

sort.sort(names);

}

WewillsettheSwappertobenullbecauseitisneverinvoked.WhenIfirstwrotethiscode,itwasevidenttome.Afewdayslater,IreadthecodeandIstopped.Whyisswappernull?ThenIrememberedinasecondortwo.Butanytime,whenreadingandunderstandingthecodehicksup,Itendtothinkaboutrefactoring.Icanaddacommenttothelinesaying//neverinvoked,butcommentstendtoremainthereevenwhenfunctionalitychanges.Ilearneditthehardwayin2006,whenawrongcommentpreventedmefromseeinghowthecodewasexecuting.Iwasreadingthecommentwhiledebugging,insteadofthecode,andbugfixingtooktwodayswhilethesystemwasdown.Insteadofacomment,Itendtouseconstructsthatmakethecodeexpresswhathappens.Theextravariablemaymaketheclassfileafewbytesbigger,butitisoptimizedoutbytheJITcompilersothefinalcodedoesnotrunslower.

Thecomparatorthatthrowsanexceptionwasprovidedasalambdaexpression.Lambdaexpressionscanbeusedincaseswhereananonymousclassornamedclasswillbeusedhavingonlyonesimplemethod.Lambdaexpressionsareanonymousmethodsstoredinvariablesorpassedinargumentforlaterinvocation.WewilldiscussthedetailsoflambdaexpressionsinChapter8,ExtendingourE-CommerceApplication.

Fornow,wewillgoonimplementingQuickSort,andtodothat,wewillusetheTDDmethodology.

Page 259:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 260:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TestDrivenDevelopmentTestDrivenDevelopment(TDD)isacodewritingapproachwhenthedevelopersfirstwriteatestbasedonthespecificationandthenwritethecode.Thisisjusttheoppositethatthedevelopercommunitygotusedto.Theconventionalapproachthatwefollowedwastowritethecodeandthenwritetestsforit.Tobehonest,therealpracticemanytimeswastowritethecodeandtestitwithad-hoctestsandnounittestsatall.Beingaprofessional,youwillneverdothat,bytheway.Youalwayswritetests.(Andnow,writeitdownahundredtimes:Iwillalwayswritetests.)

OneoftheadvantagesofTDDisthatthetestsdonotdependonthecode.Asthecodedoesnotexistatthecreationofthetest,developerscannotrelyontheimplementationoftheunitand,thus,itcannotinfluencethetestcreationprocess.Thisisgenerallygood.Unittestsshouldbeblackboxtestsasmuchaspossible.

Blackboxtestisatestthatdoesnottakeintoaccounttheimplementationofthetestedsystem.Ifasystemisrefactored,implementedinadifferentway,buttheinterfaceitprovidestowardtheexternalworldisthesame,thentheblackboxtestsshouldrunjustfine.Awhiteboxtestdependsontheinternalworkingofthesystemtested.Whenthecodechangesthewhiteboxtest,thecodemayalsoneedtuningtofollowthechange.Theadvantageofawhiteboxtestcanbethesimplertestcode.Notalways.Grayboxtestisamixtureofthetwo.

Unittestsshouldbeblackboxtests,but,manytimes,itisnotsimpletowriteablackboxtest.Developerswillwriteatestthattheythinkisblackbox,butmanytimes,thisbeliefprovestobefalse.Whentheimplementationchanges,somethingisrefactoredandthetestdoesnotworkanymoreanditneedstobecorrected.Itjusthappensthatknowingtheimplementation,thedevelopers,especiallythosewhowrotetheunit,willwriteatestthatdependsontheinternalworkingofthecode.Writingthetestbeforethecodeisatooltopreventthis.Ifthereisnocode,youcannotdependonit.

TDDalsosaysthatthedevelopmentshouldbeaniterativeapproach.Youwriteonlyonetestatthestart.Ifyourun,itfails.Ofcourseitfails!Asthereisnocodeyet,ithastofail.Then,youwillwritethecodethatfulfillsthistest.Nothingmore,onlythecodethatmakesthistestpass.Then,youwillgoonwritinganewtestforanotherpartofthespecification.Youwillrunitanditfails.Thisprovesthatthenewtestdoestestsomethingthatwasnotdevelopedyet.Then,youwilldevelopthecodetosatisfythenewtestand,possibly,youwillalsomodifyablockofcodethatyouhavealreadywritteninthepreviousiterations.Whenthecodeisready,thetestswillpass.

Manytimes,developersarereluctanttomodifythecode.Thisisbecausetheyareafraidofbreakingsomethingthatwasalreadyworking.WhenyoufollowTDD,youshouldnot,andatthesametime,youneednotbeafraidofthis.Therearetestsforallfeaturesthatwerealreadydeveloped.Ifsomeofthecodemodificationbreakssomefunctionality,thetestswillimmediatelysignaltheerror.Thekeyisthatyourunthetestsasoftenaspossiblewhenthecodeismodified.

Page 261:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 262:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ImplementingQuickSort

Quicksort,aswehavealreadydiscussed,ismadeoftwomajorparts.Oneispartitioningandtheotheroneisdoingthepartitioningrecursivelyuntilthewholearrayissorted.TomakeourcodemodularandreadytodemonstratetheJava9module-handlingfeature,wewilldevelopthepartitioningandtherecursivesortingintoseparateclassesandinaseparatepackage.Thecomplexityofthecodewillnotjustifythisseparation.

Page 263:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 264:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThepartitioningclassThepartitioningclassshouldprovideamethodthatmovestheelementsofthecollectionbasedonapivotelement,andwewillneedtoknowthepositionofthepivotelementafterthemethodfinishes.Thesignatureofthemethodshouldlooksomethinglikethis:

publicintpartition(SortableCollection<E>sortable,intstart,intend,Epivot);

TheclassshouldalsohaveaccesstoSwapperandComparator.Inthiscase,wedefinedaclassandnotaninterface;therefore,wewilluseconstructorinjection.

Theseconstructs,likesettersandconstructorinjectors,aresocommonandhappensofrequentlythatIDEssupportthegenerationofthese.Youwillneedtocreatethefinalfieldsinthecodeandusethecodegenerationmenutocreatetheconstructor.

Thepartitioningclasswilllooklikethefollowing:

packagepackt.java9.by.example.ch03.qsort;

importpackt.java9.by.example.ch03.SortableCollection;

importpackt.java9.by.example.ch03.Swapper;

importjava.util.Comparator;

publicclassPartitioner<E>{

privatefinalComparator<E>comparator;

privatefinalSwapperswapper;

publicPartitioner(Comparator<E>comparator,Swapperswapper){

this.comparator=comparator;

this.swapper=swapper;

}

publicintpartition(SortableCollection<E>sortable,intstart,intend,Epivot){

return0;

}

}

Thiscodedoesnothing,butthatishowTDDstarts.Wewillcreatethedefinitionofarequirementprovidingtheskeletonofthecodeandthetestthatwillcallit.Todothat,wewillneedsomethingthatwecanpartition.ThesimplestchoiceisanIntegerarray.ThepartitionmethodneedsaobjectoftypeSortableCollection<E>,andwewillneedsomethingthatwrapsthearrayandimplementsthisinterface.WenamethatclassArrayWrapper.Thisclassservesageneralpurposeanditisnotonlyforthetest.Becauseofthat,wecreateitasproductioncodeandassuchweputitinthedirectorymainandnotinthedirectorytest.AsthiswrapperisindependentfromtheimplementationofSort,theproperpositionofthisclassisinanewSortSupportClassesmodule.Wewillcreatethenewmoduleasitisnotpartoftheinterface.Implementationsdependontheinterface,butnotonthesupportclasses.Therecanalsobesomeapplicationthatusesourlibrariesandmayneedtheinterfacemoduleandsomeoftheimplementationbutstilldoesnotneedthesupportclasseswhentheydeliverthewrappingfunctionalitythemselves.Afterall,wecannotimplementallpossiblewrappingfunctionality.TheSRPalsoholdsforthemodules.

Javalibrariestendtocontainunrelatedfunctionalities.Fortheshortrun,itmakestheuseofthelibrarysimpler.YouwillonlyneedtospecifyonedependencyinyourPOMfileandyouwillhavealltheclassesandAPIsthatyouneed.Inthelongrun,theapplicationgetsbigger,carryingalotofclassesthatarepart

Page 265:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ofsomeofthelibrariesbuttheapplicationneverusesthem.

Toaddthenewmodule,themoduledirectoryhastobecreatedalongwiththesourcedirectoriesandthePOMfile.ThemodulehastobeaddedtotheparentPOManditalsohastobeaddedtothedependencyManagementsectionsothatthetestcodeoftheQuickSortmodulecanuseitwithoutspecifyingtheversion.Thenewmoduledependsontheinterfacemodule,sothisdependencyhastobeaddedtothePOMofthesupportclasses.

TheArrayWrapperclassissimpleandgeneral.

packagepackt.java9.by.example.ch03.support;

importpackt.java9.by.example.ch03.SortableCollection;

publicclassArrayWrapper<E>implementsSortableCollection<E>{

privatefinalE[]array;

publicArrayWrapper(E[]array){

this.array=array;

}

publicE[]getArray(){

returnarray;

}

@Override

publicEget(inti){

returnarray[i];

}

@Override

publicintsize(){

returnarray.length;

}

}

TheArraySwapperclass,whichwealsoneed,comesintothesamemodule.Itisjustassimpleasthewrapper.

packagepackt.java9.by.example.ch03.support;

importpackt.java9.by.example.ch03.Swapper;

publicclassArraySwapper<E>implementsSwapper{

privatefinalE[]array;

publicArraySwapper(E[]array){

this.array=array;

}

@Override

publicvoidswap(intk,intr){

finalEtmp=array[k];

array[k]=array[r];

array[r]=tmp;

}

}

Havingtheseclasses,wecancreateourfirsttest.

packagepackt.java9.by.example.ch03.qsort;

//importsdeletedfromprint

publicclassPartitionerTest{

Beforecreatingthe@Testmethod,wewillneedtwohelpermethodsthatmakeassertions.Assertionsarenotalwayssimple,andinsomecases,theymayinvolvesomecoding.Thegeneralruleisthatthetestandtheassertionsinitshouldbeassimpleaspossible;otherwise,theyarejustpossiblesourceofprogrammingerrors.Additionally,wecreatedthemtoavoidprogrammingerrors,nottocreatenewones.

TheassertSmallElementsmethodassertsthatallelementsbeforecutIndexaresmallerthanpivot.

Page 266:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privatevoidassertSmallElements(Integer[]array,intcutIndex,Integerpivot){

for(inti=0;i<cutIndex;i++){

Assert.assertTrue(array[i]<pivot);

}

}

TheassertLargeElementsmethodmakessurethatallelementsfollowingcutIndexareatleastaslargeaspivot.

privatevoidassertLargeElemenents(Integer[]array,intcutIndex,Integerpivot){

for(inti=cutIndex;i<array.length;i++){

Assert.assertTrue(pivot<=array[i]);

}

}

ThetestusesaconstantarrayofIntegersandwrapsitintoanArrayWrapperclass.

@Test

publicvoidpartitionsIntArray(){

Integer[]partitionThis=newInteger[]{0,7,6};

Swapperswapper=newArraySwapper<>(partitionThis);

Partitioner<Integer>partitioner=

newPartitioner<>((a,b)->a<b?-1:a>b?+1:0,swapper);

finalIntegerpivot=6;

finalintcutIndex=partitioner.partition(newArrayWrapper<>(partitionThis),0,2,pivot);

Assert.assertEquals(1,cutIndex);

assertSmallElements(partitionThis,cutIndex,pivot);

assertLargeElemenents(partitionThis,cutIndex,pivot);

}

}

ThereisnoComparatorforIntegertypeintheJDK,butitiseasytodefineoneasalambdafunction.Nowwecanwritethepartitionmethod,asfollows:

publicintpartition(SortableCollection<E>sortable,intstart,intend,Epivot){

intsmall=start;

intlarge=end;

while(large>small){

while(comparator.compare(sortable.get(small),pivot)<0&&small<large){

small++;

}

while(comparator.compare(sortable.get(large),pivot)>=0&&small<large){

large--;

}

if(small<large){

swapper.swap(small,large);

}

}

returnlarge;

}

Ifwerunthetest,itrunsfine.However,ifwerunthetestwithcoverage,thentheIDEtellsusthatthecoverageisonly92%.Thetestcoveredonly13ofthe14linesofthepartitionmethod.

Thereisaredrectangleonthegutteratline28.Thisisbecausethetestarrayisalreadypartitioned.Thereisnoneedtoswapanyelementinitwhenthepivotvalueis6.Itmeansthatourtestisgood,butnotgood

Page 267:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

enough.Whatifthereisanerroronthatline?

Toamendthisproblem,wewillextendthetest,changingthetestarrayfrom{0,7,6}to{0,7,6,2}.Runthetestanditfails.Why?Aftersomedebugging,wewillrealizethatweinvokethemethodpartitionwiththefixedparameter2asthelastindexofthearray.But,wemadethearraylonger.Whydidwewriteaconstantthereinthefirstplace?Itisabadpractice.Let'sreplaceitwithpartitionThis.length-1.Now,itsaysthatcutIndexis2,butweexpected1.Weforgottoadjusttheassertiontothenewarray.Let'sfixit.Nowitworks.

Thelastthingistorethinktheassertions.Thelesscodethebetter.Theassertionmethodsarequitegeneral,andwewilluseitforonesingletestarray.Theassertionmethodsaresocomplexthattheydeservetheirowntest.But,wedonotwritecodetotest.Insteadofthat,wecansimplydeletethemethodsandhavethefinalversionofthetest.

@Test

publicvoidpartitionsIntArray(){

Integer[]partitionThis=newInteger[]{0,7,6,2};

Swapperswapper=newArraySwapper<>(partitionThis);

Partitioner<Integer>partitioner=

newPartitioner<>((a,b)->a<b?-1:a>b?+1:0,swapper);

finalIntegerpivot=6;

finalintcutIndex=partitioner.partition(newArrayWrapper<>(partitionThis),0,partitionThis.length-1,pivot);

Assert.assertEquals(2,cutIndex);

finalInteger[]expected=newInteger[]{0,2,6,7};

Assert.assertArrayEquals(expected,partitionThis);

}

Andthenagain,isthisablack-boxtest?Whatifthepartitioningreturns{2,1,7,6}?Itfitsthedefinition.Wecancreatemorecomplexteststocoversuchcases.Butamorecomplextestmayalsohaveabuginthetestitself.Asadifferentapproach,wecancreateteststhatmaybesimplerbutrelyontheinternalstructureoftheimplementation.Thesearenotblack-boxtestsandthusnotidealunittests.Iwillgoforthesecondone,butIwillnotargueifsomeonechoosestheother.

Page 268:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 269:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RecursivesortingWewillimplementthequicksortwithanextraclassthatisintheqsortpackagealongwiththepartitioningclass,whichisasfollows:

packagepackt.java9.by.example.ch03.qsort;

//importsdeletedfromtheprint

publicclassQsort<E>{

//constructorinjectedfinalfieldsdeletedfromtheprint

publicvoidqsort(SortableCollection<E>sortable,intstart,intend){

if(start<end){

finalEpivot=sortable.get(start);

finalPartitioner<E>partitioner=newPartitioner<>(comparator,swapper);

intcutIndex=partitioner.partition(sortable,start,end,pivot);

if(cutIndex==start){

cutIndex++;

}

qsort(sortable,start,cutIndex-1);

qsort(sortable,cutIndex,end);

}

}

}

ThemethodgetsSortableCollection<E>andtwoindexparameters.Itdoesnotsortthewholecollection;itsortsonlytheelementsbetweenthestartandtheendindex.

Itisalwaysimportanttobeextremelyprecisewiththeindexing.Usually,thereisnoproblemwiththestartindexinJava,butalotofbugssourcefromhowtheendindexisinterpreted.Inthismethod,thevalueofendcanmeanthattheindexisalreadynotpartoftheto-be-sortedinterval.Inthatcase,thepartitionmethodshouldbeinvokedwithend-1andthefirstrecursivecallwithcutIndexaslastparameter.Itisamatteroftaste.Theimportantthingistobepreciseanddefinetheinterpretationofindexparameters.

Ifthereisonlyoneelement(start==end),thenthereisnothingtobesortedandthemethodreturns.Thisistheendcriterionoftherecursion.Themethodalsoassumesthattheendindexisneversmallerthanthestartindex.Asthismethodisusedonlyinsidethelibrarythatwearedevelopingatthemoment,suchanassumptionisnottooriskytomake.

Ifthereissomethingtobesorted,thenthemethodtakesthefirstelementoftheto-be-sortedintervalandusesitaspivotandcallsthepartitionmethod.Whenthepartitionisdone,themethodrecursivelycallsitselfforthetwohalves.

Thisalgorithmisrecursive.Thismeansthatthemethodcallsitself.Whenamethodcallisexecuted,theprocessorallocatessomememoryinanareacalledstackanditstoresthelocalvariablesthere.Thisareathatbelongstothemethodinthestackiscalledstackframe.Whenthemethodreturns,thisareaisreleasedandthestackisrestored,simplymovingthestackpointerwhereitwastothepreviousstate.Thiswayamethodcancontinueitsexecutionaftercallinganothermethod;thelocalvariablesarethere.

Whenamethodcallsitself,itisnotdifferent.Thelocalvariablesarelocaltotheactualcallofthemethod.Whenthemethodcallsitself,itallocatesspaceforthelocalvariablesagainonthestack.Inother

Page 270:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

words,thesearenewinstancesofthelocalvariables.

WewilluserecursivemethodsinJava,andinotherprogramminglanguages,whenthedefinitionofthealgorithmisrecursive.Itisextremelyimportanttounderstandthatwhentheprocessorcoderuns,itisnotrecursiveanymore.Onthatlevel,thereareinstructions,registerstores,andmemoryloadsandjumps.Thereisnothinglikefunctionormethodandtherefore,onthatlevel,thereisnothinglikerecursion.

Ifyougetthat,itiseasytounderstandthatanyrecursioncanbecodedasaloop.

Asamatteroffact,itisalsotruetheotherwayaround—everyloopcanbecodedasrecursionbutthatisnotreallyinterestinguntilyoustartfunctionalprogramming.

TheproblemwiththerecursioninJava,andinmanyotherprogramminglanguages,isthatitmayrunoutofstackspace.Inthecaseofquicksort,thisisnotthecase.YoucansafelyassumethatthestackformethodcallinginJavaisafewhundredsoflevels.Quicksortneedsastackthatisapproximatelylog2ndeep,wherenisthenumberofelementstobesorted.Inthecaseofonebillionelements,thisis30thatshouldjustfit.

Whyisthestacknotmovedorresized?Thatisbecausethecodethatrunsoutofthestackspaceisusuallybadstyle.Theycanbeexpressedmorereadableinformofsomeloop.Amorerobuststackimplementationwouldonlylurethenoviceprogrammertodosomelessreadablerecursivecoding.

Thereisaspecialcaseofrecursionnamedtailrecursion.Atailrecursivemethodcallsitselfasthelastinstructionofthemethod.Whentherecursivecallreturnsthecode,executingthemethoddoesnothingelsebutreleasethestackframethatwasusedforthismethodinvocation.Inotherwords,wewillkeepthestackframeduringtherecursivecalljusttothrowitawayafterwards.Whynotthrowitawaybeforethecall?Inthatcase,theactualframe,whichhasthesamesizeandcall,willallocatebecausethisisjustthesamemethodthatiskeptandtherecursivecallistransformedintoajumpinstruction.ThisisanoptimizationthatJavadoesnotdo.Functionallanguagesaredoingit,butJavaisnotreallyafunctionallanguageandthereforetail-recursivefunctionsshouldratherbeavoidedandtransformedtoaloopintheJavasourcelevel.

Page 271:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 272:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Non-recursivesortingTodemonstratethatevennon-tailrecursivemethodscanbeexpressedinanon-recursiveway,hereisthequicksortthatway:

publicclassNonRecursiveQuickSort<E>{

//injectedfinalfieldsandconstructordeletedfromprint

privatestaticclassStack{

finalintbegin;

finalintfin;

publicStack(intbegin,intfin){

this.begin=begin;

this.fin=fin;

}

}

publicvoidqsort(SortableCollection<E>sortable,intstart,intend){

finalList<Stack>stack=newLinkedList<>();

finalPartitioner<E>partitioner=newPartitioner<>(comparator,swapper);

stack.add(newStack(start,end));

inti=1;

while(!stack.isEmpty()){

Stackiter=stack.remove(0);

if(iter.begin<iter.fin){

finalEpivot=sortable.get(iter.begin);

intcutIndex=partitioner.partition(sortable,iter.begin,iter.fin,pivot);

if(cutIndex==iter.begin){

cutIndex++;

}

stack.add(newStack(iter.begin,cutIndex-1));

stack.add(newStack(cutIndex,iter.fin));

}

}

}

}

ThiscodeimplementsastackontheJavalevel.Whileitseesthatthereisstillsomethingscheduledtobesortedinstack,itfetcheditfromthestackanddoesthesortpartitioning,andschedulesthetwopartsforbeingsorted.

ThiscodeismorecomplexthanthepreviousoneandyouhavetounderstandtheroleoftheStackclassandhowitworks.Ontheotherhand,theprogramusesonlyoneinstanceofthePartitionerclassanditisalsopossibletouseathreadpooltoschedulethesubsequentsortsinsteadofhandlingthetasksinasingleprocess.Thismayspeedupthesortwhenitisexecutedonamulti-CPUmachine.However,thisisabitmorecomplextaskandthischaptercontainsalotofnewthingswithoutmultitasking;therefore,wewilllookatmultithreadcodeintwochapterslateronly.

Intheveryfirstversionofthesort,IwascodingitwithoutthethreelinesthatcomparecutIndexagainsttheintervalstartandincrementsitintheifbranch.Itisneededverymuch.But,theunittestswecreatedinthisbookdonotdiscoverthebugifwemissthoselines.Irecommendthatyoujustdeletethoselinesandtrytowritesomeunitteststhatfail.Thentrytounderstandwhatthespecialcaseiswhenthoselinesarevitalandtrytomodifyyourunittestsothatitisthesimplestpossiblethatstilldiscoversthatbug.(Finally,putthefourlinesbackandseeifthecodeworks.)Additionally,findsomearchitecturalreasonwhynottoputthismodificationintothemethodpartition.Thatmethodcouldjustreturnlarge+1incaselarge==start.

Page 273:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 274:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ImplementingtheAPIclassHavingdoneallthis,thelastthingwewillneedistohaveQuickSortasasimpleclass(alltherealworkwasalreadydoneindifferentclasses).

publicclassQuickSort<E>implementsSort<E>{

publicvoidsort(SortableCollection<E>sortable){

intn=sortable.size();

Qsort<E>qsort=newQsort<>(comparator,swapper);

qsort.qsort(sortable,0,n-1);

}

//...setterinjectorsweredeletedfromtheprint

}

Donotforgetthatwealsoneedatest!But,inthiscase,thatisnotmuchdifferentthanthatofBubbleSort.

@Test

publicvoidcanSortStrings(){

finalString[]actualNames=newString[]{

"Johnson","Wilson",

"Wilkinson","Abraham","Dagobert"

};

finalString[]expected=newString[]{"Abraham","Dagobert","Johnson","Wilkinson","Wilson"};

Sort<String>sort=newQuickSort<>();

sort.setComparator(String::compareTo);

sort.setSwapper(newArraySwapper<String>(actualNames));

sort.sort(newArrayWrapper<>(actualNames));

Assert.assertArrayEquals(expected,actualNames);

}

Thistime,weusedStringarrayinsteadofArrayList.Thismakesthistestsimplerand,thistime,wealreadyhavethesupportclasses.

Youmayrecognizethatthisisnotaunittest.InthecaseofBubbleSort,thealgorithmwasimplementedinasingleclass.Testingthatsingleclassisaunittest.InthecaseofQuickSort,weseparatedthefunctionalityintoseparateclasses,andevenintoseparatepackages.ArealunittestoftheQuickSortclasswilldisclosethedependencyofthatclassonotherclasses.Whenthistestruns,itinvolvestheexecutionofPartitionerandalsoQsort;therefore,itisnotreallyaunittest.

Shouldwebotheraboutthat?Notreally.Wewanttocreateunitteststhatinvolveasingleunittoknowwheretheproblemiswhenaunittestfails.Iftherewereonlyintegrationtests,afailingtestcasewouldnothelpalotinpointingoutwheretheproblemis.Allitsaysisthatthereissomeproblemintheclassesthatareinvolvedinthetest.Inthiscase,thereareonlyalimitednumberofclasses(three)thatareinvolvedinthistestandtheyaretiedtogether.Theyareactuallytiedtogetherandrelatedtoeachothersocloselythatintherealproductioncode,Iwouldhaveimplementedtheminasingleclass.IseparatedthemheretodemonstratehowtotestasingleunitandalsotodemonstrateJava9modulesupportthatneedsabitmorethanasingleclassinaJARfile.

Page 275:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 276:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Creatingmodules

Modulehandling,alsoknownasprojectJigsaw,isafeaturethatwasmadeavailableonlyinJava9.Itwasalongplannedfeaturethatthedeveloperswerewaitingfor.FirstitwasplannedforJava7,butitwassocomplexthatitgotpostponedtoJava8andthentoJava9.Ayearago,itseemedthatitwouldgetpostponedagain,butfinally,theprojectcodegotintotheearlyreleasesandnownothingcanstopfrombeingpartoftherelease.

Page 277:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 278:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhymodulesareneededWehavealreadyseenthattherearefourlevelsofaccessinJava.Amethodorfieldcanbeprivate,protected,public,ordefault(alsoknownaspackageprivate)whennomodifierissupplied.Whenyoudevelopacomplexlibrarytobeusedinseveralprojects,thelibraryitselfwillcontainmanyclassesinmanypackages.Therewillcertainlybeclassesandmethods,fieldsinthosethatareusedinsidethelibrarybyotherclassesfromdifferentpackages,butclassesthatarenottobeusedbythecodeoutsidethelibrary.Makingthemanythinglessvisiblethanpublicwillrenderthemunusableinsidethelibrary.Makingthempublicwillmakethemvisiblefromoutside.

Inourcode,theMavenmodulequickcompiledtoaJARcanonlybeusedifthemethodsortcaninvokeqsort.But,wedonotwantqsorttobeuseddirectlyfromoutside.Inthenextversion,wemaywanttodevelopaversionofthesortthatusesqsortfromtheNonRecursiveQuickSortclassandwedonotwantcomplainingcustomerswhosecodedoesnotcompileorworkbecauseofaminorlibraryupgrade.Wecandocumentthattheinternalmethodsandclassesarestillpublicbutnotforuse,butinvain.Developersusingourlibrarydonotreaddocumentation.Thisisalsowhywedonotwriteexcessivecomments.Nobodywillreadit,noteventheprocessorexecutingthecode.

Themostwell-knownandinfamousexampleofthisproblemisthesun.misc.UnsafeclassintheJDK.Thereissomereallyunsafecodeinit,asthenameimplies.Youcanaccessmemoryoutofheap,createobjectswithoutinitialization,andsoon.Youshouldnot.Whybother?Youareawell-behavingdeveloperandyoujuststicktotherulesandyoudonotusethatpackage.WheneveritchangesinanewversionoftheJDK,yourprogramissafeusingonlypublicandwell-documentedJDKAPI.Right?

Wrong!Withoutbeingawareofthis,youmayusesomelibrariesthatdependonotherlibrariesthatusethepackage.MockitoandSpringFrameworkareonlytwoofthenumerousindanger.Inaddition,Java9willdefinitelycomewithanewversionofthispackage.However,itwillalsocomewithmodulehandling.WhileJava9willprovidesomeusefulAPIforthelibrariesthatwereusingtheUnsafepackagebecausetherewasnoprovidedAPIforthefunctionalitytheyneeded,itwilldelivermodulesnottorecreatethesameproblemagain.

Page 279:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 280:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhatisaJavamoduleAJavamoduleisacollectionofclassesinaJARorinadirectorythatalsocontainaspecialclassnamedmodule-info.IfthereisthisfileinaJARordirectorythenitisamodule,otherwiseitisjustacollectionofclassesthatareontheclasspath(ornot).Java8,andtheearlierversions,willjustignorethatclassasitisneverusedascode.Thisway,usingolderJava,causesnoharmandbackwardcompatibilityismaintained.

Themoduleinformationdefineswhatthemoduleexportsandwhatitrequires.Ithasaspecialformat.Forexample,wecanplacemodule-info.javainourSortInterfaceMavenmodule.

modulepackt.java9.by.example.ch03{

exportspackt.java9.by.example.ch03;

}

Thismeansthatanyclass,whichispublicandinsidethepackt.java9.by.example.ch03package,canbeusedfromoutside.Thispackageisexportedfromthemodule,butotherclassesfromotherpackagesarenotvisiblefromoutsideofthemoduleeveniftheyarepublic.Thenameofthemoduleissameasthepackage,butthisismereconventionincasethereisonlyonepackageexported.Therequirementisthesameasinthecaseofpackages:thereshouldbeanamethatisnotlikelytocollidewithothermodulenames.Thereverseddomainnameisagoodchoicebutitisnotamustasyoucanseeinthisbook.Thereisnotop-leveldomainpackt,yet.

WeshouldalsoconfiguretheparentPOMtoensurethatthecompilerweuseisJava9,

<build>...

<plugins>...

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.5.1</version>

<configuration>

<source>1.9</source>

<target>1.9</target>

</configuration>

</plugin>

...

Olderversionswouldbeconfusedwiththemodule-info.javafile.(Bytheway,eventheearlyaccessversionofJava9Iuseforthisbooksometimesgivesahardtime.)

Wealsocreateamodule-info.javafileintheMavenmodule,quick,whichisasfollows:

modulepackt.java9.by.example.ch03.quick{

exportspackt.java9.by.example.ch03.quick;

requirespackt.java9.by.example.ch03;

}

Thismoduleexportsanotherpackageandrequiresthepackt.java9.by.example.ch03modulethatwehavejustcreated.Now,wecancompilethemodulesandthecreatedJARsinthe./quick/targetand./SortInterface/targetdirectoriesarenowJava9modules.

AsMavendoesnotfullysupportthemodulesyet,whenIissuethemvninstallcommand,I

Page 281:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

getthefollowingerrormessage:[ERROR].../genericsort/quick/src/main/java/module-info.java:[3,40]modulenotfound:

packt.java9.by.example.ch03

Mavenputsthecompiledmodulesonclasspath,butJava9seeksmodulepathformodules.Mavendoesnothandlemodulepathyet.Tohackmodulepathtothecompiler,wewillhavetoaddthefollowingconfigurationlinestotheparentPOMtotheconfigurationofthecompilerplugin:<compilerArgs><arg>-modulepath</arg>

<arg>${project.parent.basedir}/SortInterface/target/SortInterface-1.0.0-SNAPSHOT.jar:...</arg>

</compilerArgs>

TheactualfileshouldlistallthecolonseparatedJARfilesthatMavengenerates,andonwhichsomeofthemodulesdepend.ThesearetheSortInterface,quick,andSortSupportClasses.

Totestthefunctionalityofmodulesupport,wewillcreateanotherMavenmodulecalledMain.Ithasonlyoneclass,calledMain,withapublicstaticvoidmainmethod:

packagepackt.java9.by.example.ch03.main;

//...importsdeletedfromtheprint

publicclassMain{

publicstaticvoidmain(String[]args)throwsIOException{

StringfileName=args[0];

BufferedReaderbr=newBufferedReader(newInputStreamReader(newFileInputStream(newFile(fileName))));

List<String>lines=newLinkedList<>();

Stringline;

while((line=br.readLine())!=null){

lines.add(line);

}

br.close();

String[]lineArray=lines.toArray(newString[0]);

Sort<String>sort=newQuickSort<>();

Qsort<String>qsort=newQsort<>(String::compareTo,newArraySwapper<>(lineArray));

sort.setComparator(String::compareTo);

sort.setSwapper(newArraySwapper<>(lineArray));

sort.sort(newArrayWrapper<>(lineArray));

for(finalStringoutLine:lineArray){

System.out.println(outLine);

}

}

}

Ittakesthefirstargument(withoutcheckingthatthereisone,whichweshouldnotuseinaproductioncode)andusesthatasafilename.Then,itreadsthelinesofthefileintoaStringarray,sortsit,andprintsittothestandardoutput.

Asthemodulesupportonlyworksformodules,thisMavenmodulealsohastobeaJavamoduleandhaveamodule-info.javafile.

modulepackt.java9.by.example.ch03.main{

requirespackt.java9.by.example.ch03.quick;

requirespackt.java9.by.example.ch03;

requirespackt.java9.by.example.ch03.support;

}

Additionally,wewillhavetocreateamodule-info.javafileforthesupportmodule;otherwise,wewillnotbeabletouseitfromourmodule.

Aftercompilingthemodulesusingmvninstall,wecanrunittoprintouttheparentPOM.

java-cpMain/target/Main-1.0.0-SNAPSHOT.jar:SortInterface/target/SortInterface-1.0.0-SNAPSHOT.jar:quick/target/quick-1.0.0-SNAPSHOT.jar:SortSupportClasses/target/SortSupportClasses-1.0.0-SNAPSHOT.jarpackt.java9.by.example.ch03.main.Mainpom.xml

Page 282:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Notethatthisisonelineofcommandthatprintbreaksintoseverallines.

Now,ifwetrytoaccessQsortdirectlyinsertingthefollowinglineQsort<String>qsort=newQsort<>(String::compareTo,newArraySwapper<>(lineArray));intothemainmethod,MavenwillcomplainbecausethemodulesystemhidesitfromourMainclass:

[ERROR]Failedtoexecutegoalorg.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile(default-compile)onprojectMain:Compilationfailure:Compilationfailure:

[ERROR].../Main/src/main/java/packt/java9/by/example/ch03/main/Main.java:[4,41]packagepackt.java9.by.example.ch03.qsortdoesnotexist

[ERROR].../Main/src/main/java/packt/java9/by/example/ch03/main/Main.java:[25,9]cannotfindsymbol

Themodulesystemalsosupportsthejava.util.ServiceLoaderbasedclass-loadingmechanism,whichwewillnotdiscussinthisbook.ThisisanoldtechnologythatisrarelyusedinanenterpriseenvironmentwhenSpring,Guice,orsomeotherdependencyinjectionframeworkisused.Ifyouseeamodule-info.javafilethatcontainstheusesandprovideskeywords,thenfirstconsultwiththeJavadocumentationabouttheServiceLoaderclassathttp://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html,andthentheJava9languagedocumentationonmodulesupport(http://openjdk.java.net/projects/jigsaw/quick-start).

Page 283:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 284:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

Inthischapter,wedevelopedageneralsortingalgorithmimplementingquicksort.Wemodifiedourprojecttobeamulti-moduleMavenprojectandalsotouseJavamoduledefinitions.WewereusingJUnittodevelopunittests,andwedevelopedthecodeusingTDD.WeconvertedthecodefromoldstyleJavatonewusinggenerics,andweusedexceptionhandling.Thesearethebasictoolsthatareneededforthecomingchapters,wherewewilldevelopaguessinggame.Firstwewilldevelopasimplerversionandinthesubsequentchapterwewilldevelopaversionthatusesparallelcomputing,andmultipleproccessors.

Page 285:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 286:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Mastermind-CreatingaGameInthischapter,wewillstarttodevelopasimplegame.ThegameistheMastermindgamefortwoplayers.Playeroneselectsfourdifferentlycoloredpinsoutofsixpossiblecolorsandarrangesthemonaboardinarowhiddenfromtheotherplayer.Theotherplayertriestoguessthecolorsofthepinsanditspositions.Aftereachtry,playeronetellsthenumberofmatchingcolorsandthepinsmatchingbothcolorandposition.Theprogramwillactasbothplayeroneandplayertwo.Ourcodewillplayalone.However,whatremainsforustoplaywithisthemostimportant:thecode.

ThisexampleiscomplexenoughtodeepentheOOprinciplesandhowwedesignclassesandmodeltherealworld.WehavealreadyusedclassesprovidedintheJavaruntime.Thistime,wewillusecollectionsanddiscussthisimportantarea.TheseclassesandinterfacesarewidelyusedandavailableintheJDKandasimportantforaprofessionalJavadeveloperasthelanguageitself.

ThebuildtoolthistimeisGradle.

Inthischapterwewillcover:

JavacollectionsDependencyinjectionHowtocommentourcodeandtocreateJavaDocdocumentationHowtocreateintegrationtests

Page 287:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 288:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheGameMastermind(https://en.wikipedia.org/wiki/Mastermind_(board_game))isanoldgame.Theplasticversionthatwasubiquitousineveryhousewithchildrenwasinventedin1970.Igotaboardaround1980asaChristmasgiftandsolvingthegamepuzzleinBASIClanguagewasoneofthefirstprogramsthatIcreatedaround1984.

Thegameboardcontainsholesinseveralrowsinfourcolumns.Thereareplasticpinsofsixdifferentcolorsthatcanbeinsertedintotheholes.Eachpinhasonecolor.Theyareusuallyred,green,blue,yellow,black,andwhite.Thereisaspecialrowthatishiddenfromoneoftheplayers(theguesser).

Toplaythegame,oneoftheplayers(hider)hastoselectfourpinsfromasetofpins.Theselectedpinsshouldhavedifferentcolors.Thepinsareplacedinthehiddenrowonebyone,eachintoaposition.

Theguessertriestofindoutwhatcolorsareinwhichpositionguessing.Eachguesstakesplaceselectingfourpinsandplacingtheminarow.Thehidertellstheguesserhowmanypinsareincorrectpositionandhowmanyhaveacolorthatisonthetable,butarenotinthepositionwherethatcolorishidden.

Asampleplaymaygolikethis:

Thehiderhidesfourpinswithcolorblue,yellow,white,andblack.Guesserguessesyellow,blue,green,andred.Thehidertellstheguesserthattherearetwocolorsmatching,butnoneofthemisinthepositioninthehiddenrow.Thehidersaysthisbecauseyellowandblueareinthehiddenrowbutnotinthepositionsastheguesserguessed.Theyareactuallyswapped,butthisinformationthehiderkeepsasecret.Allshesaysisthattherearetwocolorsmatching,noneinthecorrectposition.Thenextguessis...

Thegamefinisheswhentheguesserfindsthecorrectcolorsinthecorrectorder.Thesamegame,asonthefigure,canalsobedescribedwithtextualnotation,Bforblue,Yforyellow,Gforgreen,Wforwhite,Rforred,andbforblack(luckywehaveupperandlowercaselettersonthecomputer).

RGBY0/0

GRWb0/2

Page 289:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

YBbW0/2

BYGR0/4

RGYB2/2

RGBY4/0

Guesswhat!Thisistheactualoutputoftheprogramthatwedevelopinthischapter.

Page 290:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 291:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThemodelofthegameWhenwedevelopapieceofcodewithanobject-orientedmindset,wetrytomodeltherealworldandmapreal-worldobjectstoobjectsintheprogram.Youcertainlyhaveheardofobjectorientationexplainedwiththeverytypicalexamplesofgeometricobjects,orthecarandthemotorthingtoexplaincomposition.Personally,Ibelievethattheseexamplesaretoosimpletogetagoodunderstanding.Theymaybegoodforstarters,butwearealreadyinthefourthchapterofthebook.TheMastermindgameismuchbetter.Itisabitmorecomplexthanjustrectanglesandtriangles,butnotascomplexasatelecombillingapplicationoranatomicpowerplantcontrol.

Whatarethereal-worldobjectsthatwehaveinthatgame?Wehaveatableandwehavepinsofdifferentcolors.TherearetwoJavaclassesthatwecertainlywillneed.Whatisinatable?Therearerowseachhavingfourpositions.Perhapswewillneedaclassforarow.Atablewillhaverows.Wewillalsoneedsomethingthathidesthesecret.Thisalsomaybearowandeachrowmayalsoholdtheinformationabouthowmanypositionsandhowmanycolorsarematching.Incaseofthesecretrow,thisinformationisobvious:4and0.

Whatisapin?Eachpinhasacolorandgenerally,thatisit.Therearenootherfeaturesofapin,exceptthatitcanbeinsertedintoaholeonthetable,butthisisareallifefeaturewewillnotmodel.Essentially,apinisacolorandnothingelse.Thisway,wecaneliminatethepinclassfromourmodelearlyon,evenbeforewecreateditinJava.Instead,wehavecolors.

Whatisacolor?Thisissomethingthatmaybehardtoimmerseintothefirsttime.Weallknowwellwhatacoloris.Itisamixtureofdifferentfrequencyoflights,asoureyesperceiveit.Wecanhavepaintsandprintsindifferentcolors,andsoon.Thereareverymanythingsthatwedonotmodelinthisprogram.Itisreallyhardtotellwhatwemodelaboutcolorinourcodebecausethesefeaturesaresoobviousthatwetakeitforgrantedinreallife;wecantellabouttwocolorsthattheyaredifferent.Thisistheonlyfeatureweneed.Todothis,thesimplestclassofJavacanbeused:

packagepackt.java9.by.example.mastermind;

publicclassColor{}

IfyouhavetwovariablesofthetypeColor,youcantelliftheyarethesameornot.Youcanuseobjectidentitycomparingaandbusingtheexpressiona==boryoucanusetheequalsmethodinheritedfromtheObjectclass,a.equals(b).Itistemptingtoencodethecolorswithletters,oruseStringconstantstodenotethem.Itmaybeeasierfirst,butthereareseriousdrawbackslater.Whenthecodebecomescomplex,itleadstobugs;itwillbeeasytopasssomethingalsoencodedasStringinsteadofacolorandonlyunittestsmaysavetheday.Better,thecompileralreadycomplainsintheIDEwhenyoutypethewrongargument.

Whenweplaythegame,thepinsareinsmallboxes.Wepullpinsoutoftheboxes.Howdowegetthecolorsintheprogram?Weneedsomethingfromwherewecanfetchcolorsorlookingattheotherwaysomethingthatcangiveuscolors.WewillcallitColorManager.ColorManagerknowshowmanydifferentcolorswehaveandanytimeweneedacolor,wecanaskforit.

Again,thereisatemptationtodesigntheColorManagerthatitcanserveacolorbyitsserialnumber.Ifwe

Page 292:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

havefourcolors,wecouldaskforcolornumber0,1,2,or3.Butthenagain,itwouldjustimplicitlyencodethecolorsasintegernumbers,whichweagreedwewillnot.Weshouldfindtheminimumfeaturethatwewillneedtomodelthegame.

Todescribethestructureoftheclasses,professionaldevelopersusuallyuseUMLclassdiagrams.UMLisadiagramnotationthatisstandardizedandisalmostexclusivelyusedtovisualizesoftwarearchitecture.TherearemanydiagramtypesinUMLtodescribethestaticstructureandthedynamicbehaviorofaprogram.Thistime,wewilllookataverysimplifiedclassdiagram.

WehavenoroomtogetintothedetailsofUMLclassdiagrams.Rectanglesdenotetheclasses,normalarrowsdenotetherelationswhenaclasshasfieldoftheotherclasstype,andtriangleheadedarrowmeansthataclassextendsanother.Thearrowpointstothedirectionoftheclassbeingextended.

AGamecontainsasecretRowandaTable.TheTablehasaColorManagerandaList<>ofRow.TheColorManagerhasafirstcolorandhasaMap<>ofColor.Wehavenotdiscussedwhythatisthedesign,wewillgetthereandthediagramhelpsuswalkingthatroad.ARowisessentiallyanarrayofColor.

Theonewhoplaysthegamehasonefunction:ithastoguessmanytimesuntilitfindsthehiddensecret.TogettothemodeloftheColorManager,wewillhavetodesignthealgorithmoftheGuesser.

Whentheplayermakesthefirstguess,anycombinationofcolorsisjustasgoodasanyother.Later,theguessesshouldconsidertheresponsesthatweregivenforpreviousguesses.Itisareasonableapproachtotryonlycolorvariationsthatcanbetheactualsecret.Theplayerselectsavariationandlooksatallpreviousguessesassumingthattheselectedvariationisthesecret.Iftheresponsestotherowshehasalreadymadearethesameforthisvariationasfortheunknownsecretinthegame,thenitisreasonabletotrythisvariation.Ifthereisanydifferenceintheresponses,thenthisvariationiscertainlynotthe

Page 293:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

variationthatwashidden.

Tofollowthisapproach,theguesserhastogenerateallpossiblecolorvariationsoneaftertheotherandcompareitagainstthetable.Theguessercodewillnotcreateandstoreallthepossiblevariationsahead,butithastoknowwhereitwasandhastobeabletocalculatethenextvariationthatcomes.Thisassumesanorderofthevariations.Forashortwhile,let'sforgetthatnocolormayappeartwiceinavariation.Asimpleorderingcanbemadethesamewayaswesortdecimalnumbers.Ifwehaveathree-digitnumber,thenthefirstoneis000,thenextoneis001,andsoonuntil009,alwaysfetchingthenextdigitforthelastposition.Afterthat,010comes.Weincreasedadigitnexttothelastoneandwesetthelastoneto0again.Now,wehave011,012,andsoon.Youknow,howwecountnumbers.Now,replacethedigitswithcolorsandwehaveonlysixandnotten.Or,wehaveasmanyaswewantwhenweinstantiateaColorManagerobject.

ThisleadstothefunctionalityoftheColorManager.Ithastodothefollowingtwothings:

GivethefirstcolortothecallerGivethenextcolorthatfollowsagivencolor(wewillnamethemethodnextColor)

Thelatterfunctionalityshouldalsosignalsomewaywhenthereisnonextcolor.Thiswillbeimplementedusinganothermethod,namedthereIsNextColor.

ItisaconventiontostartthemethodnamesthatreturnaBooleanvaluewithis.ThatwouldleadtothenamefollowingthisconventionisThereNextColor,orisNextColor.Eitherofthesenamesexplainsthefunctionalityofthemethod.IfIaskthequestionisThereNextColor,themethodwillanswermetrueorfalse.But,thisisnothowwewillusethemethod.Wewilltalkinsimplesentences.Wewilluseshortsentences.Wewillavoidunnecessary,gibberishexpressions.Wewillalsoprogramthatway.Mostprobably,thecallerwillusethismethodinanifstatement.Theywillwritethefollowing:If(thereIsNextColor(currentColor)){...}

andnotif(isThereNextColor(currentColor)){...}

Ithinkthefirstversionismorereadableandreadabilitycomesfirst.Last,butnotleast,nobodywillblameyouifyoufollowtheoldconvention,andincasethatisthecompanystandard,youhavetoanyway.

Todothese,theColorManageralsohastocreatethecolorobjectsandshouldstoretheminastructurethathelpstheoperationsbeingperformed.

packagepackt.java9.by.example.mastermind;

importjava.util.HashMap;

importjava.util.Map;

publicclassColorManager{

finalprotectedintnrColors;

finalprotectedMap<Color,Color>successor=newHashMap<>();

finalprivateColorfirst;

publicColorManager(intnrColors){

this.nrColors=nrColors;

first=newColor();

ColorpreviousColor=first;

for(inti=1;i<nrColors;i++){

Page 294:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

finalColorthisColor=newColor();

successor.put(previousColor,thisColor);

previousColor=thisColor;

}

successor.put(previousColor,Color.none);

}

publicColorfirstColor(){

returnfirst;

}

booleanthereIsNextColor(Colorcolor){

returnsuccessor.get(color)!=Color.none;

}

publicColornextColor(Colorcolor){

returnsuccessor.get(color);

}

}

ThestructureweuseisaMap.MapisaninterfacedefinedintheJavaruntimeandisavailablesincetheveryearlyreleasesofJava.AMaphaskeysandvalue,andforanykey,youcaneasilyretrievethevalueassignedtothekey.

Youcanseeontheline,wherethevariablesuccessorisdefinedthatwedefinethetypeofthevariableasaninterface,butthevalueisaninstanceofaclass.Obviously,thevaluecannotbeaninstanceofaninterfacebecausesuchbeastsdonotexist.But,whydowedefinethevariabletobeaninterface?Thereasonisabstractionandcodingpractice.Ifweneedtochangetheimplementationweuseforsomereason,thevariabletypestillmayremainthesameandthereisnoneedtochangethecodeelsewhere.ItisalsoagoodpracticetodeclarethevariabletobeaninterfacesothatwewillnothavethetemptationtousesomespecialAPIoftheimplementationthatisnotavailableintheinterfacejustbyconvenience.Whenitisreallyneeded,wecanchangethetypeofthevariableandusethespecialAPI.Afterall,thereisareasonthatAPIisthere,butthemeretemptationtousesomespecialthingjustbecauseitisthereishindered.Thishelpstowritesimplerandcleanerprogram.

MapisonlyoneoftheinterfacesdefinedintheJavaruntimebelongingtotheJavacollections.Therearemanyotherinterfacesandclasses.Although,theJDKandalltheclassesareavastamountandalmostnobodyknowsalltheclassesthatarethere,collectionsisaspecialareathataprofessionaldevelopershouldbeknowledgeableabout.BeforegettingintodetailsonwhyHashMapisusedinthiscode,wewillhaveanoverviewofthecollectionclassesandinterfaces.Thiswillhelpusalsounderstandtheothercollectionsusedinthisprogram.

Page 295:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 296:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JavacollectionsCollectionsareinterfacesandclassesthathelpusstoremorethanoneobject.Wehavealreadyseenarraysthatcandothat,andalsoArrayListinthepreviouschapters,butwedidnotdiscussindetailwhatotherpossibilitiesthereareintheJDK.Here,wewillgointomoredetail,butleavethestreamsandthefunctionalmethodsforlaterchapters,andwewillalsorefraintogointodetailsthatisratherthetaskofareferencebook.

Usingimplementationofthecollectionclassesandinterfacesreducestheprogrammingeffort.Firstofall,youdonotneedtoprogramsomethingthatisalreadythere.Secondly,theseclassesarehighlyoptimized,bothinimplementationandintheirfeatures.TheyhaveverywelldesignedAPIaswellasthecodeisfastandusessmallmemoryfootprint.Sorrytosaythattheircodewaswrittenlongtimeagoandmanytimesitisnotagoodstyle,hardtoread,andunderstand.

WhenyouuseacollectionfromtheJDK,itismorelikelythatyoucaninteroperatewithsomelibrary.Ifyoucookyourownversionoflinkedlists,itisnotlikelythatyouwillfindareadymadesolutionthatwillsortyourlist.IfyouusetheLinkedListclassintheJDK'sstandardclasslibrary,youwillgetareadymadesolutionfromtheCollectionsclass,rightfromtheJDK.ItisalsoworthmentioningthattheJavalanguageitselfsupportstheseclasses,forexample,youcaneasilyiteratethroughtheelementsofaCollectionwithashortenedspecialsyntax.

ThecollectionsinJDKcontaininterfacesthatdefinethebehaviorofthedifferentcollectiontypes,implementationclasses,andalgorithmsthatperformcertainactionssuchassorting.Manytimes,thesealgorithmsworkondifferentimplementationversions,gettingthesameresult,butoptimizedfortheimplementationspecificclass.

YoucanusetheAPIgivenbytheinterface,andifyouchangetheimplementationinyourcode,youwillgetanoptimizedversionfittingtheimplementation.

Thecollectioninterfacescanbecategorizedintwobags.OnebagcontainstheinterfacesthatextendtheCollectioninterface,andtheotheronecontainsMap,andaSortedMapextendingMap.Thisway,Mapisnotreallyacollection,asitdoesnotsimplycontainotherobjectsbutalsopairvaluestokeys.

Page 297:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 298:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InterfacecollectionCollectionisthetopoftheinterfacehierarchy.Thisinterfacedefinesthemethodsthatallimplementationsshouldprovide,nomatteriftheyimplementtheSet,SortedSet,List,Queue,orDequeinterfacedirectly.AsCollectionsimplysaysthatanobjectthatimplementstheCollectioninterfaceisonlyanobjectthatcollectsotherobjectstogether,themethodsitdefinesarelikeaddinganewobjecttothecollection,clearingallelementsfromthere,checkingthatanobjectisalreadyamemberofthecollection,anditeratingthroughtheelements.

Foranup-to-datedefinitionoftheinterface,consulttheJavapidocumentation(http://download.java.net/java/jdk9/docs/api/overview-summary.html).YoucanconsulttheonlineAPIanytime,anditisrecommendedtodoso.

TheJavalanguageitselfdirectlysupportstheinterface.YoucaniteratethroughtheelementsoftheCollectionwiththeenhancedforloopsyntax,thesamewayasyoucaniterateovertheelementsofanarraywherethecollectionshouldbeanexpressionthatresultsanobjectthatimplementstheCollectioninterface:for(Eelement:collection){...}

Intheprecedingcode,EiseitherObjectorthegenerictypeoftheelementsoftheCollection.

TheinterfaceCollectionisnotdirectlyimplementedintheJDK.ClassesimplementoneofthesubinterfacesofCollection.

Page 299:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 300:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SetTheSetisaspecialcollectionthatcannotcontainduplicateelements.Whenyouwanttoaddanobjectintoasetthatalreadyhasanobjectthatisthesameorequaltotheactualone,thentheaddmethodwillnotaddtheactualobject.Theaddmethodwillreturnfalseindicatingthefailure.

YoucanuseSetinyourprogramwhenyouneedacollectionofuniqueelementswhereyousimplywanttocheckthatanelementisamemberofasetornot,whetheranobjectbelongstoacertaingroupornot.

Aswewillreturntoourprogramcode,wewillseethattheUniqueGuesserclasshastoimplementanalgorithmthatchecksthatacolorinaguessispresentonlyonce.ThisalgorithmistheidealcandidateforaSettobeused:

privatebooleanisNotUniqueWithSet(Color[]guess){

finalSet<Color>alreadyPresent=newHashSet<>();

for(Colorcolor:guess){

if(alreadyPresent.contains(color)){

returntrue;

}

alreadyPresent.add(color);

}

returnfalse;

}

Thecodecreatesaset,whichisemptywhenthemethodstarts.Afterthat,itchecksforeachcolor(noticetheenhancedforloopoverthearrayelements)ifitwasalreadypresentbefore.Todothat,thecodechecksifthecolorisalreadyintheset.Ifitisthere,theguessisnotuniqueaswehavefoundacolorthatispresentatleasttwice.Ifthecolorwasnotintheset,thentheguesscanstillbeuniqueincolors.Tobeabletodetectthatlater,thecodeputsthecolorintotheset.

TheactualimplementationofSetthatwewilluseisHashSet.IntheJDK,therearemanyclassesimplementingtheSetinterface.ThemostwidelyusedisHashSet,anditisalsoworthmentioningEnumSet,LinkedHashSet,andTreeSet.ThelastonealsoimplementstheSortedSetinterface,sowewilldetailitthere.

TounderstandwhatHashSet(andlaterHashMap)areandhowtheywork,wewillhavetodiscusswhathashesare.Theyplayveryimportantandcentralroleinmanyapplications.TheydotheirjobunderthehoodintheJDKbuttherearesomeveryimportantconstraintsthatprogrammershavetofolloworelsereallyweirdandextremelyhardtofindbugswillmaketheirlifemiserable.IdaretosaythatviolationofthehashcontractinHashSetandHashMaparethecauseofthesecondmostdifficulttofindbugsnexttomultithreadissues.

Thus,beforegoingonwiththedifferentcollectionimplementations,wewillvisitthistopic.Wearealreadyoneleveldeepfromourexampleinthisdetourdiscussingcollectionsandnowwewillgooneleveldeeper.Ipromisethisisthelastin-depthlevelofdetours.

Page 301:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 302:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HashfunctionsAhashisamathematicalfunctionthatassignsanumbertoanelement.SayyouworkatauniversityadministrationandyouhavetotellifWilkinsonisastudentatyourclass.Youcanstorethenamesonsmallpapersinenvelopesoneforeachstartingletter.Insteadofsearchingthroughthe10thousandstudents,youcanlookatthepapersintheenvelopetitledW.Thisverysimplehashfunctionassignsthefirstletterofthenametothename(ortheordinalnumberoftheletter,aswesaidthatahashfunctionresultsanumber).Thisisnotreallyagoodhashfunctionbecauseitputsonlyafewelements,ifany,intotheenvelopedenotedXandmanytoAforexample.

Agoodhashfunctionresultseachpossibleordinalnumberwithsimilarprobability.Inhashtables,weusuallyhavemorebuckets(envelopesinthepreviousexample)thanthenumberofelementstobestored.Therefore,whenanelementissearchedfor,itislikelythatthereisonlyoneelementthere.Atleastthatiswhatwewouldliketohave.Iftherearemultipleelementsinasinglebucket,itiscalledcollision.Agoodhashfunctionhasaslittlecollisionsaspossible.

Forbackwardcompatibility,thereisaHashtableclassintheJDK.ThiswasoneofthefirsthashtableimplementationsinJavarightintheveryfirstversion,andasJavaisbackwardcompatible,itwasnotthrownaway.TheMapinterfacewasintroducedinversion1.2only.Hashtablehasmanydrawbacksanditsuseisnotrecommended.(EventhenameisviolatingtheJavanamingconventions.)Wedonotdiscussthisclassinthisbook.Wheneverwetalkabouthashtables,itisreferringtotheactualarraythatisinsidetheimplementationofHashSet,HashMap,oranyothercollectionthatusessomehashindexedtable.

Hashtablesarearraysthatusetheresultofthehashfunctiontoindexthearray.Usually,linkedlistsmanagecollisions.Hashtableimplementationsalsoimplementastrategytoresizethearraywhenthenumberofelementstobestoredbecomestoohighandthelikelihoodofcollisionsincrease.Thisoperationmaytakeconsiderabletimeand,duringthis,theindividualelementsaremovedbetweenthebuckets.

Duringthisoperation,thehashtablecannotreliablybeusedandthismaybesomesourceofissuesinamultithreadenvironment.Insinglethreadcode,youdonotmeetthisproblem.Whenyoucalltheaddmethod,thehashtable(setormap)decidesthatthetablehastoberesized.Theaddmethodcallstheresizingmethodanddoesnotreturnuntilitisfinished.Singlethreadcodehasnopossibilitytousethehashtableduringthisperiod:theoneandsinglethreadisexecutingtheresizingitself.Inamultithreadenvironment,however...

HashSetandHashMapusethehashfunctionprovidedbytheObjectthatisstoredinthecollection.TheObjectclassimplementsthehashCodeandequalsmethods.Youcanoverridethemandifyoudo,youshouldoverridebothinaconsistentmanner.First,wewillseewhattheyareandthenhowtooverridethemconsistently.

Page 303:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 304:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Methodequals

Thedocumentationofsetsays"setscontainnopairofelementse1ande2suchthate1.equals(e2)".Theequalsmethodreturnstrueifthee1ande2areinsomewayequal.Itmaybedifferentfromtwoobjectsbeingidentical.Therecanbetwodistinctobjectsthatareequal.Forexample,wecouldhaveacolorimplementationthathasthenameofthecolorsasanattributeandtwocolorobjectsmayreturntruecallingtheequalsmethodononeofthemandpassingtheargumentastheotherwhenthetwostringsareequal.ThedefaultimplementationoftheequalsmethodisinthecodeoftheObjectclassandthisreturnstrueifandonlyife1ande2areexactlythesameandsingleobject.

Itseemstobeobvious,butmyexperienceshowsthatitcannotbestressedenoughthattheimplementationofequalsinanobjecthastobeasfollows:

Reflexive:ThismeansthatanobjectthatalwaysequalsitselfSymmetric(commutative):Thismeansife1.equals(e2)istrue,thene2.equals(e1)shouldalsobetrueTransitive:Thismeansife1.equals(e2)ande2.equals(e3),thene1.equals(e3)Consistent:Thismeansthatthereturnvalueshouldnotchangeiftheobjectswerenotchangedbetweentheinvocations

Page 305:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 306:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MethodhashCodeThehashCodemethodreturnsanint.Thedocumentationsaysthatanyclassredefiningthismethodshouldprovidethefollowingimplementation:

ConsistentlyreturnthesamevalueiftheobjectwasnotmodifiedResultthesameintvaluefortwoobjectsthatareequal(theequalsmethodreturnstrue)

Thedocumentationalsomentionsthatthisisnotarequirementtoresultdifferentintvaluesforobjectsthatarenotequal,butitisdesirabletosupporttheperformanceofthehashimplementingcollections.

IfyouviolateanyoftheserulesintheimplementationofequalsandhashCode,thentheJDKclassesusingthemwillfail.AsyoucanbesurethatHashSet,HashMap,andsimilarclasseswerefullydebugged,seeingthatyouaddedanobjecttoasetandthenthesetreportingthatitisnottherewillbeabewilderingexperience.However,onlyuntilyoufindoutthatthetwoobjectsbeingequalandstoredinthesethavedifferenthashCodevalues,HashSetandHashMapwilllookfortheobjectonlyinthebucketthatisindexedbythehashCodevalue.

ItisalsoacommonmistaketostoreanobjectinaHashSetorHashMapandthenmodifyit.TheobjectisinthecollectionbutyoucannotfinditbecausethehashCodereturnsadifferentvalue.Objectsstoredinacollectionshouldnotbemodifiedunlessyouknowwhatyouaredoing.

Manytimes,objectscontainfieldsthatarenotinterestingfromtheequalitypointofview.ThehashCodeandequalsmethodsshouldbeidempotenttothosefieldsandyoucanalterthosefieldsevenafterstoringtheobjectinaHashSetorinHashMap.

Asanexample,youmayadministertrianglesinobjectsmaintainingthecoordinatesoftheverticesandthecolorofthetriangle.However,youdonotcareaboutthecolorforequality,onlythatthetwotrianglesareattheexactsamelocationinthespace.Inthatcase,theequalsandhashCodemethodshouldnottakethefieldcolorintoaccount.Thisway,wecanpaintourtriangles;theywillstillbefoundinHashSetorHashMapnomatterwhatthecolorfieldis.

Page 307:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 308:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ImplementingequalsandhashCodeImplementingthesemethodsisfairlysimple.Asthisisaverycommontask,theIDEssupportthegenerationofthesemethods.ThesemethodsaretiedtogethersomuchthatthemenuitemsintheIDEsarenotseparate;theyofferyoutogeneratethesemethodsatonce.

AskingtheIDEtogeneratetheequalsmethodwillresultinsomethinglikethefollowingcode:

@Override

publicbooleanequals(Objecto){

if(this==o)returntrue;

if(o==null||getClass()!=o.getClass())returnfalse;

MyObjectJava7that=(MyObjectJava7)o;

returnObjects.equals(field1,that.field1)&&

Objects.equals(field2,that.field2)&&

Objects.equals(field3,that.field3);

}

Forthissample,wehavethreeObjectfieldsnamedfield1,field2,andfield3.Thecodewithanyothertypesandfieldswilllookverysimilar.

First,themethodchecksforobjectidentity.OneObjectalwaysequalsitself.Ifthereferencepassedasargumentisnullandnotanobject,ortheyareofdifferentclass,thenthisgeneratedmethodwillreturnfalse.Inothercases,thestaticmethodoftheclassObjects(notetheplural)willbeusedtocompareeachofthefields.

TheutilityclassObjectswasintroducedinJava7,hencethenameofthesampleclass.Thestaticmethods,equalsandhash,supporttheoverrideoftheObjectequalsandhashCodemethods.ThehashCodecreationbeforeJava7wasfairlycomplexandrequiredtheimplementationofmoduloarithmeticwithsomemagicnumbersthatishardtoexplainjustlookingatthecodewithoutknowingthemathematicsbehindit.

ThiscomplexityisnowhiddenbehindthefollowingObjects.hashmethod.

@Override

publicinthashCode(){

returnObjects.hash(field1,field2,field3);

}

ThegeneratedmethodsimplycallstheObjects.hashmethodpassingtheimportantfieldsasarguments.

Page 309:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 310:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HashSet

Now,weknowessentiallyalotofthingsabouthashessowecanbravelydiscusstheHashSetclass.HashSetisanimplementationoftheSetinterfacethatinternallyuseshashtable.Generally,thatisit.Youstoreobjectsthereandyoucanseeifanobjectisalreadythereornot.WhenthereisaneedforaSetimplementation,almostalwaysHashSetisthechoice.Almost...

Page 311:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 312:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

EnumSet

EnumSetcancontainelementsfromacertainenumeration.Recallthatenumerationsareclassesthathavefixedanumberofinstancesdeclaredinsidetheenumitself.Asthislimitsthenumberofthedifferentobjectinstances,andthisnumberisknownduringcompilationtime,theimplementationoftheEnumSetcodeisfairlyoptimized.Internally,EnumSetisimplementedasabitfieldandisagoodchoicewherebitfieldmanipulationscanbeused.

Page 313:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 314:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LinkedHashSet

LinkedHashSetisaHashSetthatalsomaintainsadoublylinkedlistoftheelementsitholds.WhenweiteratethoughaHashSet,thereisnoguaranteedorderoftheelement.WhentheHashSetismodified,thenewelementsareinsertedintooneofthebucketsand,possibly,thehashtablegetsresized.Thismeansthattheelementsgetrearrangedandgetintototallydifferentbuckets.IterationovertheelementsinHashSetjusttakesthebucketsandtheelementsinitinsomeorderthatisarbitraryfromthecallerpointofview.

LinkedHashSet,however,iteratesovertheelementsusingthelinkedlistitmaintainsandtheiterationisguaranteedtohappenintheordertheelementswereinserted.

Page 315:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 316:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SortedSet

TheSortedSetisaninterfacethatguaranteesthattheclassesimplementingitwilliterateoverthesetinasortedorder.TheordermaybethenaturalorderingoftheobjectsiftheobjectsimplementtheComparableinterfaceoraComparatorobjectmaydriveit.ThisobjectshouldbeavailablewhentheinstanceoftheclassimplementingtheSortedSetiscreated;inotherwords,ithastobeaconstructorparameter.

Page 317:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 318:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

NavigableSet

NavigableSetextendstheSortedSetinterfacewithmethodsthatletyoudoproximitysearchintheset.Thisessentiallyletsyousearchforanelementthatisinthesearchandislessthanthesearchedobject,lessorequaltothesearchedelement,greaterorequal,orgreaterthanthesearchedobject.

Page 319:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 320:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TreeSet

TreeSetisanimplementationofNavigableSetand,thiswaythisisalsoaSortedSetand,asamatteroffact,isalsoaSet.AsaSortableSetdocumentationimpliestherearetwotypesoftheconstructors,eachhavingmultipleversionsthough.OnerequiressomeComparator,theotheronereliesonthenaturalorderingoftheelements.

Page 321:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 322:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

List

Listisaninterfacethatrequiresimplementingclasstokeeptrackoftheorderoftheelements.TherearealsomethodsthataccessanelementbyindexanditerationdefinedbytheCollectioninterfacethatguaranteestheorderoftheelements.TheinterfacealsodefinesthelistIteratormethodthatreturnsanIteratoralsoimplementingtheListIteratorinterface.Thisinterfaceprovidesmethodsthatletthecallerinsertelementstothelistwhileiteratingthroughitandalsogoingbackandforthintheiteration.ItisalsopossibletosearchforacertainelementintheListbutmostimplementationsoftheinterfaceprovidepoorperformancewhilethesearchingissimplygoingthroughallelementsuntiltheelementsearchedforisfound.TherearemanyclassesimplementingthisinterfaceintheJDK.Here,wewillmentiontwo.

Page 323:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 324:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LinkedList

Thisisadoubly-linkedlistimplementationoftheListinterfacethathasareferencetotheprevious,andalsotothenextelementinthelistforeachelement.TheclassalsoimplementstheDequeinterface.Itisfairlycheaptoinsertordeleteanelementfromthelistbecauseitneedsonlytheadjustmentoffewreferences.Ontheotherhand,theaccesstoanelementbyindexwillneediterationfromthestartofthelist,orfromtheendofthelist,whicheverisclosertothespecifiedindexedelement.

Page 325:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 326:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ArrayListThisclassisanimplementationoftheListinterfacethatkeepsthereferencestotheelementsinanarray.Thatway,thisisfairlyfasttoaccessanelementbyindex.Ontheotherhand,insertinganelementtoArrayListcanbecostly.Itneedsmovingallreferencesabovetheinsertedelementoneindexhigher,anditmayalsorequireresizingthebackingarrayincasethereisnoroomintheoriginalonetostorethenewelement.Essentially,thismeansallocatinganewarrayandcopyingallreferencestoit.

ThereallocationofthearraymaybeoptimizedifweknowhowlargethearraywillgrowandcalltheensureCapacitymethod.Thiswillresizethearraytothesizeprovidedasargument,evenifthecurrentlyusedslotsarelessnumbered.

MyexperienceisthatnoviceprogrammersuseArrayListwhentheyneedalistwithoutconsideringthealgorithmicperformanceofthedifferentimplementations.IdonotactuallyknowwhythereisthispopularityofArrayList.Theactualimplementationusedinaprogramshouldbebasedonproperdecisionandnothabit.

Page 327:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 328:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

QueueQueueisacollectionthatusuallystoreselementforlateruse.Youcanputelementsintoaqueueandyoucanpullthemout.Animplementationmayspecifythegivenorder,thatmaybefirstinfirstout(FIFO)orlastinfirstout(LIFO)orsomeprioritybasedordering.

Onaqueue,youcaninvoketheaddmethodtoaddanelement,removetoremovetheheadelement,andtheelementmethodtoaccesstheheadelementwithoutremovingitfromthequeue.Theaddmethodwillthrowanexceptionwhenthereisacapacityproblemandtheelementcannotbeaddedtothequeue.Whenthequeueisempty,andthereisnoheadelement,theelementandremovemethodsthrowexception.

Asexceptionscanonlybeusedinexceptionalcases,andthecallingprogrammayhandlethesesituationsinthenormalcourseofthecode,thusallthesemethodshaveaversionthatjustreturnsomespecialvaluesignalingthesituation.Insteadofadd,acallermaycalloffertoofferanelementforstorage.Ifthequeuecannotstoretheelement,itwillreturnfalse.Similarly,peekwilltrytogetaccesstotheheadelementorreturnnullifthereisnone,andpollwillremoveandreturntheheadelementorjustreturnnullifthereisnone.

Notethatthesemethodsreturningnulljustmakethesituationambiguouswhentheimplementation,suchasLinkedList,allowsnullelements.Neverstoreanullelementinaqueue.

Page 329:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 330:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

DequeDequeisaninterfacewhichisadouble-endedqueue.ItextendstheQueueinterfacewiththemethodsthatallowaccesstobothendsofthequeuetoadd,lookat,andremoveelementsfrombothends.

FortheQueueinterfaceweneededsixmethods.Dequeuehavingtwomanageableendsneeds12methods.InsteadofaddwehaveaddFirstandaddLast.SimilarlywecanofferFirst,offerLastaswellaspeekFirst,peekLastandpollFirst,pollLast.ForsomereasonthemethodsthatimplementthefunctionalityoftheelementmethodonQueuearenamedgetFirstandgetLast.

SincethisinterfaceextendstheQueueinterfacethemethodsdefinedtherecanalsobeusedtoaccesstheheadofthequeue.InadditiontothesethisinterfacealsodefinesthemethodsremoveFirstOccurrenceandremoveLastOccurrencethatcanbeusedtoremoveaspecificelementinsidethequeue.Wecannotspecifytheindexoftheelementtoremoveandwealsocannotaccessanelementbasedonindex.TheremoveFirst/LastOccurrencemethods'argumentistheobjectthatistoberemoved.IfweneedthisfunctionalitywecanuseDequeevenifweaddandremoveelementsfromthesameendofthequeue.

WhyaretherethesemethodsinDequeandnotinQueue?ThesemethodshavenothingtodowithdoubleheadednessofDeque.Thereasonisthatmethodscannotbeaddedtointerfacesaftertheywerereleased.Ifweaddamethodtoaninterfacewebreakthebackwardcompatibilitybecauseallclassesthatimplementthatinterfacehavetoimplementthenewmethod.Java8introduceddefaultmethodsthateasedthisconstraint,buttheQueueinterfacewasdefinedinJava1.5andtheDequeinterfacewasdefinedinJava1.6.Therewasnowayatthattimetoaddthenewmethodstothealreadyexistinginterfaces.

Page 331:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 332:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Map

AMappairskeysandvalues.IfwewanttoapproachaMapfromtheCollectionpointofviewthenaMapisasetofkey/valuepairs.YoucanputkeyvaluepairsintoaMapandyoucangetavaluebasedonakey.KeysareuniquethesamewayaselementsinaSet.IfyoulookatthesourcecodeofthedifferentimplementationsoftheSetinterface,youmayseethatsomeofthemareimplementedasawrapperaroundaMapimplementationwherethevaluesaresimplydiscarded.

UsingMapsiseasyandalluring.Manylanguages,suchasPython,Go,JavaScript,Perl,andsoon,supportthisdatastructureonthelanguagelevel.However,usingaMapwhenanarraywouldbesufficientisabadpracticethatIhaveseenmanytimes,especiallyinscriptinglanguages.JavaisnotpronetothatnoviceprogrammererrorbutyoumaystillfindyourselfinasituationwhenyouwanttouseaMap,andstillthereisabettersolution.Itisageneralrulethatthesimplestdatastructureshouldbeusedthatissufficientfortheimplementationofthealgorithm.

Page 333:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 334:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HashMap

HashMapisahashtablebasedimplementationoftheMapinterface.Asthemapisbasedonahashtable,thebasicputandgetmethodsareperformedinconstanttime.Additionally,asMapisveryimportant,andbecausethemostfrequentlyusedimplementationintheJDKisHashMap,theimplementationisfairlyconfigurable.YoucaninstantiateHashMapusingthedefaultconstructorwithoutargument,butthereisalsoaconstructorthatdefinestheinitialcapacityandtheloadfactor.

Page 335:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 336:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IdentityHashMap

IdentityHashMapisaspecialMapthatimplementstheMapinterfaceliterally,butasamatteroffact,itviolatesthecontracttheMapinterfacedocumentationdefines.Itdoesitwithgoodreason.TheimplementationusesahashtablejustasHashMap,buttodecidetheequalityofthekeyfoundinthebucketcomparingwiththekeyelementprovidedasargumenttothegetmethoditusesObjectreference(==operator)andnotthemethodequals,whichisrequiredbydocumentationofMapinterface.

TheuseofthisimplementationisreasonablewhenwewanttodistinguishdifferentObjectinstancesaskeysthatotherwiseequaltoeachother.Usingthisimplementationforperformancereasonsisalmostcertainlyawrongdecision.Also,notethatthereisnoIdentityHashSetimplementationintheJDK.ProbablysuchcollectionissorarelyusedthatitsexistenceintheJDKwouldcausemoreharmthangoodalluringnoviceprogrammerstomisuse.

Page 337:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 338:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

DependencyinjectionInthepreviouschapterwebrieflyalreadydiscusseddependencyinjection(DI).Nowwewilldigintoitabitmoredetail.

Objectsusuallydonotworkontheirown.Mostofthetimetheimplementationdependsontheservicesofotherclasses.WhenwewanttowritesomethingtotheconsoleweusetheSystemclass.WhenwemanagethetableofguessesweneedColorobjectsandColorManager.

IncaseofwritingtotheconsolewemaynotrealizethedependencybecausetheclassbeingpartoftheJDKclasslibraryisavailableallthetimeandallweneedtodoistowriteSystem.out.println.Inthiscasethisdependencyiswiredintothecode.Wecannotsendtheoutputsomewhereelseunlesswechangethecode.Thisisnottooflexibleandinmanycasesweneedasolutionthatcanworkwithdifferentoutput,differentcolormanagerordifferentwhateverserviceourcodedependson.Thefirststeptodothatistohaveafieldthathasareferenceoftheobjectthatgivesourclasstheservice.IncaseofoutputthetypeofthefieldcanbeoftypeOutputStream.Thenext,moreinterestingstepishowthisfieldgetsvalue.

OneofthesolutionistouseDI.Inthisapproachsomeexternalcodepreparesthedependenciesandinjectsthemintotheobject.Whenthefirstcalltoamethodoftheclassisissuedallthedependenciesarealreadyfilledandreadytobeused.

Inthisstructure,wehavefourdifferentplayers:

TheclientobjectistheonethatgetstheinjectedserviceobjectsduringtheprocessServiceobjectorobjectsareinjectedintotheclientobjectInjectoristhecodethatperformstheinjectionInterfacesdefinetheservicethattheclientneeds

Ifwemovethelogicofthecreationoftheserviceobjectsfromtheclientcodethecodebecomesshorterandcleaner.Theactualcompetencyoftheclientclassshouldhardlyevercoverthecreationoftheserviceobjects.ForexampleaGameclasscontainsaTableinstancebutagameisnotresponsibletocreatetheTable.Itisgiventoittoworkwithit,justasinreallifethatwemodel.

Thecreationofserviceobjectsissometimesassimpleasissuingthenewoperator.Sometimesserviceobjectsalsodependonotherserviceobjectsandthatwayalsoactasclientsintheprocessofdependencyinjection.Inthiscasethecreationoftheserviceobjectsmaybealotoflines.Thestructureofthedependenciescanbeexpressedinadeclarativefashionthatdescribeswhichserviceobjectneedswhichotherserviceobjectsandalsowhatimplementationoftheserviceinterfacesaretobeused.Dependencyinjectioninjectorsworkwithsuchdeclarativedescriptions.Whenthereisaneedforanobjectthatneedsserviceobjectsthatthemselvesneedagainotherserviceobjectstheinjectorcreatestheserviceinstancesintheappropriateorderusingtheimplementationsthatarematchingthedeclarativedescriptions.Theinjectordiscoversallthedependenciestransitivelyandcreatesatransitiveclosuregraphofthedependencies.

ThedeclarativedescriptionoftheneededdependenciescanbeXML,oraspeciallanguagedeveloped

Page 339:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

especiallyforthedependencyinjectionoritcanevenbeJavaitselfusingspeciallydesignedfluentAPI(https://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/).XMLwasfirstusedinDIinjectors.LaterGroovybasedDomainSpecificLanguage(https://martinfowler.com/books/dsl.html)cameintopictureandJavafluentAPIapproach.WewilluseonlythelastonebeingthemostmodernandwewilluseSpringandGuiceDIcontainerssincetheyarethemostwell-knowninjectorimplementations.

Page 340:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 341:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ImplementingthegameCollectionswithoutexamplesareboring.Fortunately,wehaveourgamewhereweuseafewcollectionclassesandalsootheraspectsthatwewillexamineinthischapter.

Page 342:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 343:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ColorManagerWejumpedintothepoolfilledwithcollectionclassesfromtheimplementationoftheColorManagerclass.Let'srefreshthepartoftheclassthatisinterestingforusnow—theconstructor:

finalprotectedintnrColors;

finalprotectedMap<Color,Color>successor=newHashMap<>();

finalprivateColorfirst;

publicColorManager(intnrColors){

this.nrColors=nrColors;

first=newColor();

ColorpreviousColor=first;

for(inti=1;i<nrColors;i++){

finalColorthisColor=newColor();

successor.put(previousColor,thisColor);

previousColor=thisColor;

}

successor.put(previousColor,Color.none);

}

WewilluseHashMaptokeepthecolorsinanorderedlist.Atfirst,thechoiceofHashMapseemstobestrange.Verytrue,thatduringthecodingofColorManager,IalsoconsideredaList,whichseemedtobeamoreobviouschoice.WhenwehaveaList<Color>colorsvariable,thenthenextColormethodissomethinglikethis:

publicColornextColor(Colorcolor){

if(color==Color.none)

returnnull;

else

returncolors.get(colors.indexOf(color)+1);

}

Theconstructorwillbemuchsimpler,asshowninthefollowingpieceofcode:

finalList<Color>colors=newArrayList<>();

publicColorManager(intnrColors){

this.nrColors=nrColors;

for(inti=0;i<nrColors;i++){

colors.add(newColor());

}

colors.add(Color.none);

}

publicColorfirstColor(){

returncolors.get(0);

}

WhydidIchoosethemorecomplexsolutionandtheunobviousdatastructure?Thethingisperformance.WhenthenextColormethodisinvoked,thelistimplementationfirstfindstheelementcheckingalltheelementsinthelistandthenfetchesthenextelement.Thetimeisproportionaltothenumberofcolors.Whenournumberofcolorsincreases,thetimewillalsoincreasetojustgetthenextcolorhavingone.

Atthesametime,ifwefocusonnotthedatastructurethatcomesfromtheverbalexpressionofthetaskwewanttosolve(getthecolorsinasortedorder)butratherfocusontheactualmethodthatwewanttoimplement,nextColor(Color),thenwewilleasilycometotheconclusionthataMapismorereasonable.WhatweneedisexactlyaMap:havingoneelementwewantanotherrelatedtotheonewehave.Thekeyandthe

Page 344:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

valueisalsoColor.GettingthenextelementisconstanttimeusingHashMap.ThisimplementationisprobablyfasterthantheonebasedonArrayList.

Theproblemisthatitisonlyprobablyfaster.Whenyouconsiderrefactoringacodetohavebetterperformance,yourdecisionshouldalwaysbebasedonmeasurements.Ifyouimplementacodethatyouonlythinkisfaster,practiceshows,youwillfail.Inbestcase,youwilloptimizeacodetobeblazingfastandrunsduringtheapplicationserversetup.Atthesametime,optimizedcodeisusuallylessreadable.Somethingforsomething.Optimizationshouldneverbedoneprematurely.Codeforreadabilityfirst.Then,assesstheperformance,andincasethereisproblemwiththeperformance,thenprofiletheexecutionandoptimizethecodewhereithurtsthemostoftheoverallperformance.Micro-optimizationswillnothelp.DidIdoprematureoptimizationselectingtheHashMapimplementationinsteadofList?IfIactuallyimplementedthecodeusingListandthenrefactored,thenyes.IfIwasthinkingabouttheListsolutionandthenitcametomethatMapsolutionisbetterwithoutpriorcoding,thenIdidnot.Byyears,suchconsiderationswillcomeeasier,asyouwillalsoexperience.

Page 345:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 346:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheclasscolorWehavealreadylookedatthecodefortheclasscodeanditwasthesimplestclassintheworld.Inreality,asitisintheGitHubrepository(https://github.com/j9be/chapter04orhttps://github.com/PacktPublishing/Java-9-Programming-By-Example/tree/master/Chapter04),thecodeisabitmorecomplex:

packagepackt.java9.by.example.mastermind;

/**

*RepresentsacolorintheMasterMindtable.

*/

publicclassColor{

/**

*Aspecialobjectthatrepresentsa

*valuethatisnotavalidcolor.

*/

publicstaticfinalColornone=newColor();

}

WehaveaspecialcolorconstantnamednonethatweusetosignalareferencethatisoftypeColorbutisnotavalidColor.Inprofessionaldevelopment,weusedthenullvalueforalongtimetosignalinvalidreference,andbecausewearebackwardcompatible,westilluseit.However,itisrecommendedtoavoidthenullreferencewhereverpossible.

TonyHoare(https://en.wikipedia.org/wiki/Tony_Hoare),whoinventedthenullreferencein1965,admittedonetimethatthiswasamistakethatcostbillionsofdollarsintheITindustry.

Theproblemwiththenullvalueisthatittakesthecontrolawayfromtheclass,andthus,opensencapsulation.Ifamethodreturnsnullinsomesituation,thecallerisstrictlyrequiredtocheckthenullityandactaccordingtothat.Forexample,youcannotcallamethodonanullreferenceandyoucannotaccessanyfield.Ifthemethodreturns,aspecialinstanceoftheobjecttheseproblemsarelessserious.Ifthecallerforgetstocheckthespecialreturnvalueandinvokesmethodsonthespecialinstance,themethodsinvokedstillhavethepossibilitytoimplementsomeexceptionorerrorhandling.Theclasshasthecontrolencapsulatedandcanthrowaspecialexceptionthatmaygivemoreinformationabouttheerrorcausedbytheprogrammaticmistakebythecallernotcheckingthespecialvalue.

Page 347:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 348:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JavaDocandcodecommentsThereisalsoanotherdifferencebetweenwhatwepresentedhereearlierandthelisting.Thisisthecommentingofthecode.Codecommentsarepartoftheprogram,whichareignored,filteredoutbythecompiler.Thesecommentsaresolelyforthosewhomaintainorusethecode.

InJava,therearetwodifferentcomments.Thecodeenclosedbetween/*and*/arecomments.Thestartandtheendofthecommentdonotneedtobeonthesameline.Theothertypeofcommentstartswiththe//charactersandendsattheendoftheline.

Todocumentthecode,theJavaDoctoolcanbeused.JavaDocisaspecialtoolthatreadsthesourcecodeandextractsHTMLdocumentationabouttheclasses,methods,fields,andotherentitiesthathaveacommentstartingwiththe/**characters.ThedocumentationwillcontaintheJavaDoccommentsinaformattedwayandalsotheinformationthatisextractedfromtheprogramcode.

ThedocumentationalsoappearsasonlinehelpintheIDEwhenyoumovethemouseoveramethodcallorclassname,ifthereisany.TheJavaDoccommentcancontainHTMLcodes,butitgenerallyshouldnot.Ifreallyneeded,youcanuse<p>tostartanewparagraphorthe<pre>tagstoincludesomepreformattedcodesampleintothedocumentation,butnothingmoregivesrealbenefit.Documentationshouldbeasshortaspossibleandcontainasfewformattingaspossible.

TherearespecialtagsthatappearintheJavaDocdocumentation.TheseareprefilledbytheIDEswhenyoustarttotypeaJavaDocas/**andthenpressEnter.Theseareinsidethecommentandstartwiththe@character.Thereareapredefinedsetoftags:@author,@version,@param,@return,@exception,@see,@since,@serial,[email protected]@paramand@return.Theyareusedtodescribethemethodargumentsandthereturnvalue.Althoughwearenotthereyet,let'speekaheadtotheguessMatchmethodfromtheGuesserclass.

/**

*Aguessmatchesifallrowsinthetablematchestheguess.

*

*@paramguesstomatchagainsttherows

*@returntrueifallrowsmatch

*/

protectedbooleanguessMatch(Color[]guess){

for(Rowrow:table.rows){

if(!row.guessMatches(guess)){

returnfalse;

}

}

returntrue;

}

ThenameoftheparameterisautomaticallygeneratedbytheIDE.Whenyoucreatethedocumentation,writesomethingthatismeaningfulandnottautology.Manytimes,noviceprogrammersfeeltheurgetowriteJavaDoc,andthatsomethinghastobewrittenabouttheparameters.Theycreatedocumentationslikethis:

*@paramguessistheguess

Really?Iwouldneverhaveguessed.Ifyoudonotknowwhattowritetheretodocumenttheparameter,it

Page 349:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

mayhappenthatyouwerechoosingthenameoftheparameterexcellent.Thedocumentationofourprecedingexamplewilllookasfollows:

Focusonwhatthemethod,class,andinterfacedoesandhowitcanbeused.Donotexplainhowitworksinternally.JavaDocisnottheplacefortheexplanationofthealgorithmorthecoding.Itisusedtohelpusethecode.However,ifsomebodyhappenstoexplainhowamethodworks,itisnotadisaster.Commentscaneasilybedeleted.

Thereis,however,acommentthatisworsethannothing:outdateddocumentationthatisnotvalidanymore.Whenthecontractoftheelementhaschanged,butthedocumentationdoesnotfollowthechangeandismisleadingtheuserwhowantstocallthemethod,interface,orclasswhateverwillfaceseriousbugsandwillbeclueless.

Fromnowon,JavaDoccommentswillnotbelistedinprinttosavetrees,andelectronsintheeBookversion,buttheyarethereintherepositoryandcanbeexamined.

Page 350:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 351:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RowNow,wehaveColorsandeveninstancesifweneedhavingaColorManager.ThisisthetimetostoreColorsinRows.TheRowclassisabitlonger,butnottoocomplex.

packagepackt.java9.by.example.mastermind;

importjava.util.Arrays;

publicclassRow{

finalColor[]positions;

privateintmatchedPositions;

privateintmatchedColors;

ARowcontainsthreefields.Oneisthepositionsarray.EachelementofthearrayisaColor.ThematchedPositionsisthenumberofpositionsthatarematchedandmatchedColorsisthenumberofcolorsthatmatchacolorinthehiddenrowbutisnotonthepositionasinthehiddenrow.

publicstaticfinalRownone=newRow(Guesser.none);

ThenoneisaconstantthatcontainsaspecialRowinstancethatwewillusewhereverwewouldusenull.Theconstructorgetsthecolorsinanarraythatshouldbeintherow.

publicRow(Color[]positions){

this.positions=Arrays.copyOf(positions,positions.length);

}

Theconstructormakesacopyoftheoriginalarray.Thisisanimportantcodethatwewillexamineabit.Let'sreiteratethatJavapassesargumentsbyvalue.Itmeansthatwhenyoupassanarraytoamethod,youwillpassthevalueofthevariablethatholdsthearray.However,anarrayinJavaisanObjectjustaswellasanythingelse(exceptprimitiveslikeint).Therefore,whatthevariablecontainsisareferencetoanobjectthathappenstobeanarray.Ifyouchangetheelementsofthearray,youactuallychangetheelementsoftheoriginalarray.Thearrayreferenceiscopiedwhentheargumentpasses,butthearrayitself,andtheelements,arenot.

Thejava.util.Arraysutilityclassprovidesalotofusefultools.WecaneasilycodethearraycopyinginJavabutwhytoreinventthewheel?Inadditiontothat,arraysarecontinuousareaofmemorythatcanveryeffectivelybecopiedfromoneplacetoanotherusinglow-levelmachinecode.ThecopyOfmethodthatweinvokecallsthemethodSystem.arraycopywhichisanativemethodandassuchexecutesnativecode.

NotethatthereisnoguaranteethatArrays.copyOfinvokesthenativeimplementationsandthatthiswillbeextremelyfastincaseoflargearrays.TheveryversionIwastestinganddebuggingwasdoingitthatway,andwecanassumethatagoodJDKdoessomethingsimilar,effectiveandfast.

Afterwecopiedthearray,itisnotaproblemifthecallermodifiesthearraythatwaspassedtotheconstructor.Theclasswillhaveareferencetoacopythatwillcontainthesameelements.However,notethatifthecallerchangesanyoftheobjectsthatarestoredinthearray(notthereferenceinthearray,buttheobjectitselfthatisreferencedbyanarrayelement),thenthesameobjectismodified.Arrays.copyOfdoesnotcopytheobjectsthatarereferencedbythearray,onlythearrayelements.

Page 352:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Therowiscreatedalongwiththecolorsandthus,weusedafinalfieldfortheColorarray.Thematches,however,cannotbeknownwhenaRowiscreated.OneoftheplayerscreatestheRowandafterthat,theotherplayerwilltellthetwointvalues.Wedonotcreatetwosettersforthetwovalues,however,becausetheyarealwaysdefinedatthesametimeinthegametogether.

publicvoidsetMatch(intmatchedPositions,intmatchedColors){

if(matchedColors+matchedPositions>positions.length){

thrownewIllegalArgumentException(

"Numberofmatchescannotbemorethattheposition.");

}

this.matchedColors=matchedColors;

this.matchedPositions=matchedPositions;

}

ThesetMatchmethoddoesnotonlysetthevalues,butalsochecksthatthevaluesareconsistent.Thesumofthetwovaluescannotbemorethanthenumberofthecolumns.Thischeckensuresthatthecaller,whousestheAPIoftheRowclass,doesnotuseitinconsistently.IfthisAPIisusedonlyfrominsideourcode,thisassertionshouldnotbepartofthecode.Agoodcodingstyle,inthatcase,willensurethatthemethodisneverinvokedinconsistentlyusingunittests.WhenwecreateAPItouseoutofourcontrol,weshouldcheckthattheuseisconsistent.Failingtodoso,ourcodemaybehavejustweirdwhenusedinconsistently.Whenthecallersetsmatchestovaluesthatdonotmatchanypossibleguess,thegamemayneverfinishandthecallermayhaveahardtimefiguringoutwhatisgoingon.Thisfiguringoutprobablywillneedthedebugexecutionofourcode.

Ifwethrowanexceptioninthiscase,theprogramstopswherethebugis.Thereisnoneedtodebugthelibrary.

publicbooleanguessMatches(Color[]guess){

returnnrMatchingColors(guess)==matchedColors&&

nrMatchingPositions(guess)==matchedPositions;

}

Thenextmethoddecidesifaguess,givenasanargument,matchestheactualrow.Thismethodchecksthattheanswerstotheguessintherowcanbevalidifthecurrentguesswasinthehiddenrow.Theimplementationisfairlyshortandsimple.Aguessmatchesarowifthenumberofthecolorsmatchingandthenumberofpositionsmatchingarethesameasthenumbergivenintherow.Donotbeshytowriteshortmethods.Donotthinkthataone-linemethodthatessentiallycontainsonestatementisuseless.Whereverweusethismethod,wecouldalsowritetheexpression,whichisrightafterthereturnstatement,butwedonotfortworeasons.Thefirstandmostimportantreasonisthatthealgorithm,whichdecidesthatarowmatchesaguessbelongstotheimplementationoftheclassRow.Ifevertheimplementationchanges,theonlylocationwherethecodeistobechangedishere.Theotherreasonisalsoimportant,andthatisreadability.Inourcodebase,wecallthismethodfromabstractclassGuesser.Itcontainsanifstatementwiththefollowingexpression:

if(!row.guessMatches(guess)){

Woulditbemorereadableinthefollowingway:

if(!(nrMatchingColors(guess)==matchedColors&&nrMatchingPositions(guess)==matchedPositions)){

Iamcertainthatthemajorityoftheprogrammersunderstandtheintentionofthefirstversioneasier.IwouldevenrecommendimplementingthedoesNotMatchGuessmethodtoimprovethereadabilityofthecode

Page 353:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

evenmore.

publicintnrMatchingColors(Color[]guess){

intcount=0;

for(inti=0;i<guess.length;i++){

for(intj=0;j<positions.length;j++){

if(i!=j&&guess[i]==positions[j]){

count++;

}

}

}

returncount;

}

Thenumberofmatchingcolorsisthatwhichappearsbothintherowandtheguess,butnotinthesameposition.Thedefinition,andhowwecalculateit,isfairlysimpleandunambiguousincasenocolorcanappeartwiceinthehiddenrow.Incaseacolormayappearmultipletimesinthehiddenrow,thisimplementationwillcountalloccurrencesofthatcolorintheguessasmanytimesasitappearsinthehiddenrow.Ifwe,forexample,haveahiddenRRGBrowandtheguessisbYRR,thecalculationwillsay4.Itisamatterofagreementbetweentheplayershowtheycountinthiscase.Theimportantaspectisthattheyusethesamealgorithm,whichshouldbetrueinourcase,becausewewillasktheprogramtoplaybothplayers.Aswewillprogramthecodeourselves,wecantrustthatitwillnotcheat.

publicintnrMatchingPositions(Color[]guess){

intcount=0;

for(inti=0;i<guess.length;i++){

if(guess[i]==positions[i]){

count++;

}

}

returncount;

}

CountingthecolorsthatareOK,andalsoonthepositionwheretheyaresupposedtobe,isevensimpler.

publicintnrOfColumns(){

returnpositions.length;

}

ThismethodtellsthenumberofcolumnsintheRow.ThismethodisneededintheGameclassthatcontrolstheflowofawholegame.AsthisclassisinthesamepackageasRow,itcanaccessthefieldpositions.Icreatedthecodetogetthenumberofcolumnsasrow.positions.length.Butthen,Iwasreadingthecodenextdayandtoldmyself:Thisisuglyandunreadable!WhatIaminterestedinhereisnotsomemysteriouspositions'length;itisthenumberofcolumns.AndthenumberofcolumnsistheresponsibilityoftheRowclassandnotthebusinessofanyotherclass.IfIstarttostorethepositionsinaList,whichdoesnothavelength(ithasmethodsize),itisthesoleresponsibilityofRowandshouldnotaffectanyothercode.So,IcreatedthenrOfColumnsmethodtoimprovethecode.

Therestoftheclasscontainssomemoreverysimplemethodsthatareneededonlytodisplaythegameandnotforthealgorithmtoplay:

publicintnrColumns(){

returnpositions.length;

}

publicColorposition(inti){

returnpositions[i];

}

publicintmatchedPositions(){

Page 354:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

returnmatchedPositions;

}

publicintmatchedColors(){

returnmatchedColors;

}

}

Ifyouareapurist,youcanencapsulatethesemethodsintoaninnerclassnamedOutputorPrintandcallthemthroughafinalinstanceofitcreatedasafieldintheRowclass.ItisalsopossibletochangethevisibilityofthesefieldsfromprivatetoprotectedandimplementthesemethodsinaPrintableRowthatcanbeinstantiatedfromanalreadyexistingRowandimplementthesemethods.

ThefirstversionofPrintableRowwilllooklikethis:

publicclassPrintableRowextendsRow{

publicPrintableRow(Rowrow){

super(row.positions);

super.setMatch(row.matchedPositions,row.matchedColors);

}

//themethodsaredeletedfromtheprint...

}

Themethodsareexactlythesameasintheprecedingprint;theyarecutandpasted,orrathermoved,usingtheIDErefactoringsupportfromoneclasstotheother.

Whenyouwriteacode,pleaseneverusecopyandpaste.Howeveryoucanusecutandpastetomovecodefragmentsaround.Thedangerisinthecopypasteuse.Manydevelopersclaimthattheiruseofactualcopyandpasteisnotcopypasteprogramming.Theirreasoningisthattheychangethepastedcodesomuchthatithaspracticallynothingtodowiththeoriginalcode.Really?Inthatcasewhydidyouneedthecopiedcodewhenyoustartedthemodificationofit?Whynotstartfromscratch?ThatisbecauseifyouusetheIDE'scopyandpastefunctionalitythen,nomatterwhat,youdocopypasteprogramming.

ClassPrintableRowisprettyneatandseparatestheoutputconcernfromthecorefunctionality.Whenyouneedaninstance,itisnotaproblemthatyouhaveaRowinstancealreadyinhand.Theconstructorwillessentiallyclonetheoriginalclassandreturnaprintableversion.Whatbothersmeistheimplementationofthecloning.ThecodeintheconstructorcallsthesuperconstructorandthenamethodandalltheseworkwiththeoriginalfunctionalityoftheRowclass.TheyhavenothingtodowiththeprintabilitythatPrintableRowimplements.ThisfunctionalityactuallybelongstotheRowclass.Weshouldcreateaprotectedconstructorthatdoesthecloning:

protectedRow(RowcloneFrom){

this(cloneFrom.positions);

setMatch(cloneFrom.matchedPositions,cloneFrom.matchedColors);

}

TheconstructorofPrintableRowshouldsimplycallsuper(row)andthatisit.

Codeisneverfinishedandneverperfect.Inaprofessionalenvironment,programmersmanytimestendtofinishpolishingthecodewhenitisgoodenough.Thereisnocodethatcannotbemadebetter,butthereisadeadline.Thesoftwarehastobepassedontothetestersandusersandhastobeusedtohelpeconomy.Afterall,thatisthefinalgoal

Page 355:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ofaprofessionaldeveloper:haveacodethatsupportsthebusiness.Acodethatneverrunsisworthnothing.IdonotwantyoutothinkthattheexamplesthatIprovidedherewerecreatedperfectupfront.Thereasonforthatis(didyoureadcarefully?)becausetheyarenotperfect.AsIsaid,codeisneverperfect.WhenIfirstcreatedRow,itcontainedtheprintingmethodsinaninnerclass.Ididnotlikeit.Thecodewassmelly.So,IdecidedtomovethefunctionalitytotheRowclass.However,Istilldidnotlikethesolution.Then,Iwenttobed,slept,worked,andreturnedtoitafewdayslater.WhatIcouldnotcreatethedaybeforenowseemedobvious—thesemethodshavetobemovedtoasubclass.Nowcomesanotherdilemma.ShouldIpresentthisfinalsolutionorshouldIhaveherethedifferentversions?Insomecases,Iwilljustpresentthefinalversion.Inothercases,likethis,therearethingstolearnfromthedevelopmentstep.Inthesecases,Ipresentnotonlythecode,butpartofitsevolutiononhowitwascreated.IfyouwanttoseethosethatIdidnotdarepublishing,lookattheGithistory.Iadmit,sometimes,Icreatecodethatevenmakesmefacepalmadaylater.

Page 356:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 357:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TableTableisasimpleclassthathasonlyoneverysimplefunctionality.

publicclassTable{

finalColorManagermanager;

finalintnrColumns;

finalList<Row>rows;

publicTable(intnrColumns,ColorManagermanager){

this.nrColumns=nrColumns;

this.rows=newLinkedList<>();

this.manager=manager;

}

publicvoidaddRow(Rowrow){

rows.add(row);

}

}

Thereisonethingtomention,whichisnothingnew,butworthrepeating.Therowsvariableisdeclaredasfinalanditgetsthevalueintheconstructor.ThisisaList<Row>typevariable.Thefactthatitisfinalmeansthatitwillholdthesamelistobjectduringitslifetime.Thelength,members,andotherfeaturesofthelistmayandwillchange.Wewilladdnewrowstothislist.Finalobjectvariablesreferenceanobject,butitdoesnotguaranteethattheobjectitselfisimmutable.Itisonlythevariablethatdoesnotchange.

Whenyoudocodereviewandexplaintoyourcolleagueswhataclassdoes,andyoufindyourselfstartingtheexplanation"thisclassisverysimple"manytimes,itmeansthecodeisgood.Well,itmaybewronginotheraspects,buttheclass'granularityseemstobeokay.

Page 358:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 359:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GuesserGuesserandtheUniqueGuesserandGeneralGuessersubclassesarethemostinterestingclassesoftheprogram.Theyactuallyperformthetaskthatisthecoreofthegame.GivenaTablewithahiddenrow,theguesserhastocreatenewerandnewerguesses.

Todothis,aGuesserneedstogetaTablewhenitiscreated.Thisispassedasaconstructorargument.Theonlymethoditshouldimplementisguess,whichreturnsanewguessbasedonthetableandonitsactualstate.

Aswewanttoimplementaguesserthatassumesthatallcolorsinthehiddenrowaredifferent,andalsoonethatdoesnotmakethisassumption,wewillimplementthreeclasses.Guesserisanabstractclassthatimplementsonlythelogicthatisindependentfromtheassumptions.Thesemethodswillbeinheritedbybothactualimplementations:UniqueGuesserandGeneralGuesser.

Let'sgothroughtheactualcodeoftheclass:

packagepackt.java9.by.example.mastermind;

publicabstractclassGuesser{

protectedfinalTabletable;

privatefinalColorManagermanager;

publicGuesser(Tabletable){

this.table=table;

this.lastGuess=newColor[table.nrColumns];

this.manager=table.manager;

}

Thestateoftheguesseristhelastguessitmade.Althoughthisisonthelastrowofthetable,itismoreofaninternalmatteroftheguesser.Theguesserhasallthepossibleguesses,oneaftertheother;lastGuessistheonewhereitleftofflasttimeanditshouldcontinuefromtherewhenitisinvokedagain.

abstractprotectedvoidsetFirstGuess();

Settingthefirstguessverymuchdependsontheassumptionofcoloruniqueness.Thefirstguessshouldnotcontainduplicatedcolorsincasethehiddenrowdoesnot(atleastinourimplementation),whileGeneralGuesserisfreetoguessanytime,evenasfirstGuessallcolorstobethesame.

protectedfinalColor[]lastGuess;

publicstaticfinalColor[]none=newColor[]{Color.none};

Again,noneinthisclassisjustanobjectthatwetrytouseinsteadofnull,wheneverweneedtoreturnsomethingthatisareferencetoaGuessbutisnotreallyaguess.

protectedColor[]nextGuess(){

if(lastGuess[0]==null){

setFirstGuess();

returnlastGuess;

}else{

returnnextNonFirstGuess();

}

}

ThenextGuessmethodisaninternalmethodthatgeneratesthenextguess,whichjustcomesasweorderthe

Page 360:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

possibleguesses.ItdoesnotcheckanythingagainsttheTable;itonlygeneratesthenextguessalmostwithoutthinking.Theimplementationonhowwedothefirstguessandhowwedotheconsecutiveguessesaredifferent.Thus,wewillimplementthesealgorithmsindifferentmethodsandinvokethemfromhere.

ThenextNonFirstGuessmethodrepresentsthenextguessinthespecialcasewhentheguessisnotthefirstone:

privateColor[]nextNonFirstGuess(){

inti=0;

booleanguessFound=false;

while(i<table.nrColumns&&!guessFound){

if(manager.thereIsNextColor(lastGuess[i])){

lastGuess[i]=manager.nextColor(lastGuess[i]);

guessFound=true;

}else{

lastGuess[i]=manager.firstColor();

i++;

}

}

if(guessFound){

returnlastGuess;

}else{

returnnone;

}

}

Lookbackafewpageswherewedetailedhowthealgorithmworks.Wemadethestatementthatthiswayofworkingisverymuchlikethewaywecountwithdecimalnumbers.Bynow,youhaveenoughJavaknowledgeandprogrammingskilltounderstandwhatthemethoddoes.Itismoreinterestingtoknowwhyitiscodedthatway.

Hint:asalways,tobereadable.

ThereisthetemptationtoeliminatetheguessFoundvariable.Woulditnotbesimplertoreturnfromthemiddleofthemethodwhenwefindtheblessedguesses?Ifwedid,therewouldbenoneedtochecktheguessFoundvaluebeforereturningnonevalue.Thecodewouldnotgetthereifwereturnedfromthemiddleoftheloop.

Yes,itwouldbesimplertowrite.But,wecreatecodetobereadableandnotwritable.Yes,butlesscodeismorereadable.Notinthiscase!Returningfromaloopdegradesthereadability.Nottomention,thereturnstatementsarescatteredaroundinthemethodatdifferentstagesofexecution.

privateColor[]nextNonFirstGuess(){

inti=0;

while(i<table.nrColumns){

if(manager.thereIsNextColor(lastGuess[i])){

lastGuess[i]=manager.nextColor(lastGuess[i]);

returnlastGuess;

}else{

lastGuess[i]=manager.firstColor();

i++;

}

}

returnnone;

}

Whensomebodywritesacodeoptimizedinthatway,itissimilartoatoddlerwhomakeshisfirststepsandthenlooksproudlyatthemother.Okayboy/girl,youaregreat.Nowgoonandstartwalking.When

Page 361:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

youarethepostman,walkingwillbeboring.Thatwillbeyourprofession.So,slideasidetheprideandwriteboringcode.Professionalswriteboringcode.Won'titbeslow?

No!Itwillnotbeslow.Firstofall,itisnotslowuntiltheprofilerprovesthatthecodedoesnotmeetthebusinessrequirements.Ifitdoes,itisfastenough,nomatterhowslowitis.Slowisgoodaslongasitisokayforthebusiness.Afterall,JITshouldhavesometaskoptimizingthecodetorun.

ThenextmethodchecksiftheguessmatchesthepreviousguessesandtheirresultsontheTable:

privatebooleanguessMatch(Color[]guess){

for(Rowrow:table.rows){

if(!row.guessMatches(guess)){

returnfalse;

}

}

returntrue;

}

privatebooleanguessDoesNotMatch(Color[]guess){

return!guessMatch(guess);

}

AswehavetheguessmatchingalreadyimplementedintheclassRow,allwehavetodoisinvokethatmethodforeachrowinthetable.Ifallrowsmatch,thentheguesscanbegoodforthetable.Ifanyoftheformerguessesdonotmatch,thenthisguessgoesdownthedrain.

Aswecheckthenegatedexpressionofmatching,wecreatedanEnglishversionofthemethod.

Insituationslikethis,itcouldbeenoughtocreatetheguessDoesNotMatchversionofthemethod.However,thelogicalexecutionofthecodeismorereadableifthemethodisnotnegated.Therefore,itismoreerrorpronetowritetheguessDoesNotMatchmethodalone.Instead,wewillimplementtheoriginal,readableversionandtheauxmethodtobenothingmorethananegation.

Afteralltheauxmethods,hereweareimplementingthepublicmethodoftheGuesser.

publicRowguess(){

Color[]guess=nextGuess();

while(guess!=none&&guessDoesNotMatch(guess)){

guess=nextGuess();

}

if(guess==none){

returnRow.none;

}else{

returnnewRow(guess);

}

}

}

ItjusttakesthenextGuessandagainandagainuntilitfindsonethatmatchesthehiddenrow,orthereisnomoreguess.Ifitfindsaproperguess,itencapsulateittoaRowobjectandreturnitsothatitcanlaterbeaddedtotheTablebytheGameobjects.

Page 362:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 363:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

UniqueGuesserClassUniqueGuesserhastoimplementsetFirstGuess(allconcreteclassesextendinganabstractclassshouldimplementtheabstractmethodoftheparent)anditcanandwilloverridetheprotectednextGuessmethod:

packagepackt.java9.by.example.mastermind;

importjava.util.HashSet;

importjava.util.Set;

publicclassUniqueGuesserextendsGuesser{

publicUniqueGuesser(Tabletable){

super(table);

}

@Override

protectedvoidsetFirstGuess(){

inti=lastGuess.length-1;

for(Colorcolor=table.manager.firstColor();

i>=0;

color=table.manager.nextColor(color)){

lastGuess[i--]=color;

}

}

ThesetFirstGuessmethodselectsthefirstguessinsuchawaythatanypossiblecolorvariationsthatcomeafterthefirstonecreatetheguessesoneaftertheotherifwefollowthealgorithm.

TheauxisNotUniquemethodreturnstrueiftheguesscontainsduplicatecolors.Itisnotinterestingtoseehowmany.Ifallcolorsarethesame,oronlyonecolorappearstwice,itdoesnotmatter.Theguessisnotuniqueanddoesnotfitourguesser.Thismethodjudgesthat.

privatebooleanisNotUnique(Color[]guess){

finalSet<Color>alreadyPresent=newHashSet<>();

for(Colorcolor:guess){

if(alreadyPresent.contains(color)){

returntrue;

}

alreadyPresent.add(color);

}

returnfalse;

}

Todothis,itusesaSet,andanytimeanewcolorisfoundintheguessarray,thecolorisstoredintheset.Ifthesetcontainsthecolorwhenwefinditinthearray,itmeansthatthecolorwasalreadyusedbefore;theguessisnotunique.

@Override

protectedColor[]nextGuess(){

Color[]guess=super.nextGuess();

while(isNotUnique(guess)){

guess=super.nextGuess();

}

returnguess;

}

TheoverridingnextGuessmethodissimple.ItasksthesupernextGuessimplementationtomakeguessesbutthrowsawaythosethatitdoesnotlike.

Page 364:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

packagepackt.java9.by.example.mastermind;<br/><br/>publicclassGeneralGuesserextendsGuesser{<br/><br/>publicGeneralGuesser(Tabletable){super(table);}<br/><br/>@Override<br/>protectedvoidsetFirstGuess(){<br/>inti=0;<br/>for(Colorcolor=table.manager.firstColor();<br/>i<lastGuess.length;){<br/>lastGuess[i++]=color;<br/>}<br/>}<br/><br/>}

SettingthelastGuessitjustputsthefirstcoloronallcolumns.Guesscouldnotbesimpler.EverythingelseisinheritedfromtheabstractclassGuesser.

Page 365:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

packagepackt.java9.by.example.mastermind;<br/><br/>publicclassGame{<br/><br/>finalTabletable;<br/>finalprivateRowsecretRow;<br/>booleanfinished=false;<br/><br/>publicGame(Tabletable,Color[]secret){<br/>this.table=table;<br/>this.secretRow=newRow(secret);<br/>}<br/><br/>publicvoidaddNewGuess(Rowrow){<br/>if(isFinished()){<br/>thrownewIllegalArgumentException(<br/>"Youcannotguessonafinishedgame.");<br/>}<br/>finalintpositionMatch=secretRow.<br/>nrMatchingPositions(row.positions);<br/>finalintcolorMatch=secretRow.<br/>nrMatchingColors(row.positions);<br/>row.setMatch(positionMatch,colorMatch);<br/>table.addRow(row);<br/>if(positionMatch==row.nrOfColumns()){<br/>finished=true;<br/>}<br/>}<br/><br/>publicbooleanisFinished(){<br/>returnfinished;<br/>}<br/>}

ThinkaboutwhatIwroteearlieraboutshortmethods,andwhenyoudownloadthecodefromGitHubtoplaywithit,trytomakeitlookmorereadable.Youcan,perhaps,createanduseamethodnamedbooleanitWasAWinningGuess(intpositionMatch).

Page 366:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 367:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CreatinganintegrationtestWehavecreatedunittestsinthepreviouschapterandthereareunittestsforthefunctionalitiesimplementedintheclassesofthischapteraswell.Wewilljustnotprinttheseunittestshere.Insteadoflistingtheunittests,wewilllookatanintegrationtest.

Integrationtestsneedtheinvocationofmanyclassesworkingtogether.Theycheckthatthefunctionalitycanbedeliveredbythewholeapplication,oratleastalargerpartoftheapplication,anddonotfocusonasingleunit.Theyarecalledintegrationtestsbecausetheytesttheintegrationbetweenclasses.TheclassesaloneareallOK.Theyshouldnothaveanyproblemasitwasalreadyverifiedbytheunittests.Integrationfocusesonhowtheyworktogether.

IfwewanttotesttheGameclass,wewilleitherhavetocreatemocksthatmimicthebehavioroftheotherGameclasses,orwewilljustwriteanintegrationtest.Technically,anintegrationtestisverysimilartoaunittest.Manytimes,theverysameJUnitframeworkisusedtoexecutetheintegrationtests.Thisisthecasefortheintegrationtestofthisgame.

Thebuildtool,however,needstobeconfiguredtoexecutetheintegrationtestsonlywhenitisrequired.Usually,integrationtestexecutionsneedmoretime,andsometimesresources,suchasexternaldatabasethatmaynotbeavailableateachandeverydeveloperdesktop.Unittestsruneverytimetheapplicationiscompiledsotheyhavetobefast.Toseparatetheunitandintegrationtests,therearedifferenttechniquesandconfigurationoptions,butthereisnosuchmoreorlessde-factostandardlikethedirectorystructureintroducedbyMaven(lateradaptedbyGradle).

Inourcase,theintegrationtestdoesnotneedanyextraresourceanddoesnottakeenormoustimetorun.Itplaysagamefromthestarttotheendandplaystheroleofboththeplayers.Itisverymuchlikesomebodyplayingchesswiththemselves,makingastepandthenturningthetable.

Theaimofthiscodeistwofold.Ononehand,wewanttoseethatthecoderunsandplaysawholegame.Ifthegamefinishes,thenitisjustOK.Thisisaveryweakassertionandrealintegrationtestsperformlotsofassertions(onetesttestsonlyoneassertionthough).Wewillfocusontheotheraim—deliversomejoyandvisualizethegameontheconsoleintextformatsothatthereaderdoesnotgetbored.

Todothat,wewillcreateautilityclassthatprintsoutacolorandassignsletterstotheColorinstancesonthefly.ThisisthePrettyPrintRowclass.Thereareseverallimitationsinthisclassthatwehavetotalkaboutafterwelookatthecode.I'dsaythatthiscodeishereonlytodemonstratewhatnottodo,toestablishsomereasoningforthenextchapter,andwhyweneedtorefactorthecodewecreatedinthisone.

packagepackt.java9.by.example.mastermind;

importjava.util.HashMap;

importjava.util.Map;

publicclassPrettyPrintRow{

privatestaticfinalMap<Color,Character>

letterMapping=newHashMap<>();

privatestaticfinalStringletters="RGBYWb";

privatestaticintcounter=0;

Page 368:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privatestaticcharcolorToChar(Colorcolor){

if(!letterMapping.containsKey(color)){

letterMapping.put(color,letters.charAt(counter));

counter++;

}

returnletterMapping.get(color);

}

Thisistheheartofthisclass.Whenacoloristobeprinted,itgetsaletterassignedunlessitalreadyhasone.AstheMapcontainingtheassignmentsineachandeverygamethatisrunningintheJVMwillusethesamemapping,anewGameisstarted.ItallocatesnewColorsandwillsoonrunoutofthesixcharactersthatweallocatedhereintheStringconstant.

IftheGameinstancesarerunparallel,thenweareinevenmoretrouble.Theclassisnotthreadsafeatall.IftwothreadsconcurrentlycallthecolorToCharmethodforthesameColorinstance,(whichisnotlikelybecauseeachGameusesitsowncolor,butnotethatnotlikelyinprogrammingisverymuchlikeafamouslastwordsquoteonatombstone)thenboththreadsmayseeatthesametimethatthereisnoletterassignedtothecolorandbothwillassigntheletter(thesameletterortwodifferentletters,basedonluck)andincreasethecounteronceortwice.Atleast,whatwecansayisthattheexecutionisnondeterministic.

YoumayrecallthatIsaidviolatingthehashcontractisthesecondmostdifficulttofindbugaftermultithreadissues.Suchanondeterministiccodeisexactlythat:amultithreadissue.Thereisnoprizetofindthemostdifficultbug.Whentheapplicationdoesnotrun,andabugaffectstheproductionsystemforhoursordays,nobusinesspersonwillbehappy,andtheywillnotbeamazedafteryoufindthebug.Itmaybeanintellectualchallenge,buttherealvalueisnotcreatingthebugsinthefirstplace.

Asasummary,thiscodecanonlybeusedonceinaJVMbyasinglethread.Forthischapter,itisgood,thoughasmellyandshamefulcode,butitwillbeagoodexampleforthenextchapter,inwhichwewillsee,howtorefactortheapplicationsothatitwillnotneedsuchahackingtoprintoutthecolors.

CodesmellisatermmintedbyKentBack,accordingtoMartinFowler(http://martinfowler.com/bliki/CodeSmell.html).Itmeansthatsomecodelooksnotgood,norapparentlybad,butsomeconstructsmakethefeelinginthedeveloperthatitmaynotbegood.Asitisdefinedonthewebpage,"Acodesmellisasurfaceindicationthatusuallycorrespondstoadeeperprobleminthesystem."Thetermiswidelyacceptedandusedinsoftwaredevelopmentforthelast10years.

Therestofthecodeisplainandsimple:

publicstaticStringpprint(Rowrow){

Stringstring="";

PrintableRowpRow=newPrintableRow(row);

for(inti=0;i<pRow.nrOfColumns();i++){

string+=colorToChar(pRow.position(i));

}

string+="";

string+=pRow.matchedPositions();

string+="/";

string+=pRow.matchedColors();

returnstring;

}

Theintegrationtest,orratherthedemonstrationcode(asitdoesnotcontainanyassertionsotherthanitrunswithoutexception),definessixcolorsandfourcolumns.Thisisthesizeoftheoriginalgame.It

Page 369:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

createsacolormanager,andthenitcreatesatableandasecret.Thesecretcouldbejustanyrandomcolorselectionfromthesixcolorsthatisavailable(thereare360differentpossibilitiestestedintheUniqueGuesserTestunittestavailablefromGitHub).AsweknowthattheGuesserimplementationstartsfromoneendofthecolorsetandcreatesthenewguessessystematically,wewanttosetasecretthatitwillguessthelast.Thisisnotbecauseweareevil,butratherbecausewewanttoseethatourcodereallyworks.

ThedirectorystructureofthecodeisverysimilartotheoneweusedincaseoftheMavenbuildtool,ascanbeseenonthefollowingscreenshotcreatedonaWindowsmachine:

Thesourcecodeisunderthedirectorysrcandthemainandtestsourcecodefilesareseparatedintotwosubdirectorystructures.ThecompiledfileswillbegeneratedinthedirectorybuildwhenweuseGradle.Thecodeoftheintegrationtestclassisthefollowing:

packagepackt.java9.by.example.mastermind.integration;

importorg.junit.Assert;

importorg.junit.Test;

importpackt.java9.by.example.mastermind.*;

publicclassIntegrationTest{

finalintnrColors=6;

finalintnrColumns=4;

finalColorManagermanager=newColorManager(nrColors);

privateColor[]createSecret(){

Color[]secret=newColor[nrColumns];

intcount=0;

Colorcolor=manager.firstColor();

while(count<nrColors-nrColumns){

color=manager.nextColor(color);

count++;

}

for(inti=0;i<nrColumns;i++){

secret[i]=color;

color=manager.nextColor(color);

}

Page 370:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

returnsecret;

}

@Test

publicvoidtestSimpleGame(){

Tabletable=newTable(nrColumns,manager);

Color[]secret=createSecret();

System.out.println(

PrettyPrintRow.pprint(newRow(secret)));

System.out.println();

Gamegame=newGame(table,secret);

Guesserguesser=newUniqueGuesser(table);

while(!game.isFinished()){

Rowguess=guesser.guess();

if(guess==Row.none){

Assert.fail();

}

game.addNewGuess(guess);

System.out.println(PrettyPrintRow.pprint(guess));

}

}

}

TheeasiestwaytorunthetestisstartitfrominsidetheIDE.WhentheIDEimportstheprojectbasedonthebuildfile,beitaMavenpom.xmlorGradlebuild.gradle.IDEusuallyprovidesarunbuttonormenutostartthecode.Runningthegamewillprintoutthefollowingpieceofcodethatweworkedsohardoninthischapter:

RGBY0/0

GRWb0/2

YBbW0/2

BYGR0/4

RGYB2/2

RGBY4/0

Page 371:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 372:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

Inthischapter,weprogrammedatablegame:Mastermind.Wenotonlyprogrammedthemodelofthegame,butalsocreatedanalgorithmthatcanguess.WerevisitedsomeOOprinciplesanddiscussedwhythemodelwascreatedthewayitwas.Whilewecreatedthemodelofthegame,whichwewillrefineinthenextchapter,youhavelearnedaboutJavacollections,whatanintegrationtestis,andhowtocreateJavaDoc.

Page 373:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 374:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ExtendingtheGame-RunParallel,RunFasterInthischapter,wewillextendtheMastermindgame.Asitisnow,itcanguessthesecretthatwashiddenandalsohidethepegs.Thetestcodecanevendobothatthesametime.Itcanplayagainstitselfleavingusonlywiththefunofprogramming.Whatitcannotdoismakeuseofalltheprocessorsthatwehaveintoday'snotebooksandservers.Thecoderunssynchronousandutilizesonlyasingleprocessorcore.

Wewillalterthecodeextendingtheguessingalgorithmtosliceuptheguessingintosubtasksandexecutethecodeinparallel.Duringthis,wewillgetacquaintedwithJavaconcurrentprogramming.Thiswillbeahugetopicwithmanysubtlecornersandcaveatslurkinginthedark.Wewillgetintothosedetailsthatarethemostimportantandwillformafirmbaseforfurtherstudieswheneveryouneedconcurrentprograms.

Astheoutcomeofthegameisthesameasitwas,onlyfaster,wehavetoassesswhatfasteris.Todothat,wewillutilizeanewfeatureintroducedinJava9:microbenchmarkingharness.

Inthischapter,wewillcoverthefollowingtopics:

Themeaningofprocesses,threadsandfibersMultithreadinginJavaIssueswithmultithreadprogrammingandhowtoavoidthemLocking,synchronization,andblockingqueuesMicrobenchmarking

Page 375:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 376:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HowtomakeMastermindparallelTheoldalgorithmwastogothroughallthevariationsandtrytofindaguessthatmatchesthecurrentstateofthetable.Assumingthatthecurrentlyexaminedguessisthesecret,willwegetthesameanswersfortheguessesthatarealreadyonthetableastheanswersareactuallyonthetable?Ifyes,thenthecurrentguesscanbethesecret,anditisjustasgoodaguessasanyotherguesses.

Amorecomplexapproachcanimplementthemin-maxalgorithm(https://en.wikipedia.org/wiki/Minimax).Thisalgorithmdoesnotsimplygetthenextpossibleguessbutalsolooksatallthepossibleguessesandselectstheonethatshortenstheoutcomeofthegamethemost.Ifthereisaguessthatcanbefollowedbythreemoreguessesintheworstcase,andthereisanotherforwhichthisnumberisonlytwo,thenmin-maxwillchoosethelatter.Itisagoodexercisefortheinterestedreaders.Inthecaseofthesixcolorsandfourcolumnsforthepegs,themin-maxalgorithmsolvesthegameinnomorethan5steps.Thesimplealgorithmweimplementedalsosolvesthegamein5steps.However,wedonotgointhatdirection.

Instead,wewanttohaveaversionofthegamethatutilizesmorethanoneprocessor.Howcanyoutransformthealgorithmintoaparallelone?Thereisnosimpleanswertothis.Whenyouhaveanalgorithm,youcananalyzethecalculationsandpartsofthealgorithm,andyoucantrytofinddependencies.IfthereissomecalculationBthatneedsthedata,whichistheresultofanothercalculationA,thenitisobviousthatAcanonlybeperformedwhenBisready.Iftherearepartsofthealgorithmthatdonotdependontheoutcomeoftheothers,thentheycanbeexecutedinparallel.

Forexample,thequick-sorthastwomajortasks:partitioningandthensortingofthetwoparts.Itisfairlyobviousthatthepartitioninghastofinishbeforewestartsortingthetwopartitionedparts.However,thesortingtasksofthetwopartsdonotdependoneachother,theycanbedoneindependently.Youcangivethemtotwodifferentprocessors.Onewillbehappysortingthepartcontainingthesmallerelements;theotheronewillcarrytheheavier,largerones.

IfyouturnthepagesbacktoChapter3,OptimizingtheSort-MakingCodeProfessionalwhereweimplementedquick-sortinanon-recursiveway,youcanseethatwescheduledsortingtasksintoastackandthenperformedthesortingbyfetchingtheelementsfromthestackinawhileloop.Insteadofexecutingthesortrightthereinthecoreoftheloop,wecouldpassthetasktoanasynchronousthreadtoperformitandgobackforthenextwaitingtask.Wejustdonotknowhow.Yet.Thatiswhywearehereinthischapter.

Processors,threads,andprocessesarecomplexandabstractthingsandtheyarehardtoimagine.Differentprogrammershavedifferenttechniquestoimagineparallelprocessingandalgorithms.IcantellyouhowIdoitbutitisnotaguaranteethatthiswillworkforyou.Othersmayhavedifferenttechniquesintheirmind.Asamatteroffact,IjustrealizedthatasIwritethis,Ihaveactuallynevertoldthistoanyonebefore.Itmayseemchildish,butanyway,hereitgoes.

WhenIimaginealgorithms,Iimaginepeople.Oneprocessorisoneperson.Thishelpsmeovercomethefreakingfactthataprocessorcanmakebillionsofcalculationsinasecond.Iactuallyimagineabureaucratwearingabrownsuitanddoingthecalculations.WhenIcreateacodeforaparallelalgorithm,Iimaginemanyofthemworkingbehindtheirdesks.Theyworkaloneandtheydonottalk.Itisimportant

Page 377:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

thattheydonottalktoeachother.Theyareveryformal.Whenthereisaneedforinformationexchange,theystandupwithapieceofpapertheyhavewrittensomethingon,andtheybringittoeachother.Sometimes,theyneedapieceofpaperfortheirwork.Thentheystandup,gototheplacewherethepaperis,takeit,bringitbacktotheirdesk,andgoonworking.Whentheyareready,theygobackandbringthepaperback.Ifthepaperisnottherewhentheyneedit,theyqueueupandwaituntilsomeonewhohasthepaperbringsitthere.

HowdoesithelpwithMastermind?

Iimagineabosswhoisresponsiblefortheguesses.Thereisatableonthewallintheofficewiththepreviousguessesandtheresultsforeachrow.Thebossistoolazytocomeupwithnewguessessohegivesthistasktosubordinates.Whenasubordinatecomesupwithaguess,thebosscheckswhethertheguessisvalidornot.Hedoesnottrustthesubordinates,andiftheguessisgood,hemakesitasanofficialguess,puttingitonthetablealongwiththeresult.

Thesubordinatesdelivertheguesseswrittenonsmallpost-itnotes,andtheyputtheminaboxonthetableoftheboss.Thebosslooksattheboxfromtimetotime,andifthereisanote,thebosstakesit.Iftheboxisfullandasubordinatewantstoputapaperthere,thesubordinatestopsandwaitsuntilthebosstakesatleastonenotesothatthereissomeroomintheboxforanewnote.Ifthesubordinatesqueueuptodepositguessesinthebox,theyallwaitfortheirtime.

Thesubordinatesshouldbecoordinated;otherwise,theywilljustcomeupwiththesameguesses.Eachofthemshouldhaveanintervalofguesses.Forexample,thefirstoneshouldchecktheguessesfrom1234upuntil2134,thesecondshouldcheckfrom2134upuntil3124,andsoon,ifwedenotethecolorswithnumbers.

Willthisstructurework?Commonsensesaysthatitwill.However,bureaucrats,inthiscase,aremetaphorsandmetaphorsarenotexact.Bureaucratsarehuman,evenwhentheydonotseemlikeitmuchmorethanthreadsorprocessors.Theysometimesbehaveextremelystrangely,doingthingsthatnormalhumansdon'treallydooften.However,wecanstillusethismetaphorifithelpsusimaginehowparallelalgorithmswork.

Wecanimaginethatthebossgoesonholidayanddoesnottouchtheheapofpaperpilinguponthetable.Wecanimaginethatsomeoftheworkersareproducingresultsmuchfasterthantheothers.Asthisisonlyimagination,thespeedupcanbe1000times(thinkofatime-lapsevideo).Imaginingthesesituationsmayhelpusdiscoverspecialbehaviorthatrarelyhappens,butmaycauseproblems.Asthethreadsworkinparallel,manytimessubtledifferencesmayinfluencethegeneralbehaviorgreatly.

Insomeearlyversion,asIcodedtheparallelMastermindalgorithm,thebureaucratsstartedworkingandfilledtheboxofthebosswithguessesbeforethebosscouldputanyofthemonthetable.Astherewerenoguessesonthetable,thebureaucratssimplyfoundallpossiblevariationsintheirintervalbeingapossiblygoodguess.Thebossgainednothingbythehelpoftheparallelhelpers;theyhadtoselectthecorrectonesfromallpossibleguesses,whiletheguesserswerejustidle.

Anothertime,thebureaucratswerecheckingguessesagainstthetablewhilethebosswasputtingaguessononeofthemcreatedbeforehand.Andsomeofthebureaucratsfreakedoutsayingthatitisnotpossible

Page 378:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

tocheckaguessagainstatableifsomeoneischangingit.Moreprecisely,thecodeexecutinginonethread,threwConcurrentModificationExceptionwhentheListofthetablewasmodified.

Anothertime,Itriedtoavoidthetoofastworkofbureaucrats,andIlimitedthesizeoftheboxwheretheycouldputtheirpaperscontainingtheguesses.Whenthebossfinallyfoundthesecret,andthegamefinished,thebosstoldthebureaucratsthattheycouldgohome.Thebossdidthatbycreatingasmallpaperwiththeinstruction:youcangohome,andputitonthetablesofthebureaucrats.Whatdidthebureaucratsdo?Keptwaitingfortheboxtohavespaceforthepaper!(Untiltheprocesswaskilled.ThisiskindofequivalentonMacOSandonLinuxasendingtheprocessfromthetaskmanageronWindows.)Suchcodingerrorshappenand,toavoidasmanyaspossible,wehavetodoatleasttwothings.Firstly,wehavetounderstandhowJavamultithreadingworksandsecondly,haveacodeascleanaspossible.Forthesecond,wewillcleanupthecodeevenmoreandthenwewilllookathowtheparallelalgorithmdescribedearliercanbeimplementedinJava,runningontheJVMinsteadofutilizingbureaucrats.

Page 379:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 380:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RefactoringWhenwefinishedthepreviouschapter,wehadtheclassesoftheMastermindgamedesignedandcodedinaniceandperfectlyobjectorientedwaythatdidnotbreakanyoftheOOprinciples.Didwe?Absurd.Thereisnocode,exceptsometrivialexamples,thatcannotbemadetolooknicerorbetter.Usually,whenwedevelopcodeandfinishthecoding,itlooksgreat.Itworks,thetestsallrun,anddocumentationisready.Fromtheprofessionalpointofview,itreallyisperfect.Well,itisgoodenough.Thebigquestionthatwehavenottestedyetismaintainability.Whatisthecosttoalterthecode?

Thatisnotaneasyquestion,especiallybecauseitisnotadefiniteone.Altertowhat?Whatisthemodificationthatistobemadetothecode?Wedonotknowthatwhenwecreatethecodeinthefirstplace.Ifthemodificationistofixabug,thenitisobviousthatwedidnotknowthatbeforehand.Ifweknew,wewouldnothaveintroducedthebuginthefirstplace.Ifthisisanewfeature,thenthereisapossibilitythatthefunctionwasforeseen.However,usuallyitisnotthecase.Whenadevelopertriestopredictthefuture,andwhatfeaturestheprogramwillneedinthefuture,theyusuallyfail.Itisthetaskofthecustomertoknowthebusiness.Featuresneededaredrivenbythebusinessincaseofprofessionalsoftwaredevelopment.Afterall,thatiswhatitmeanstobeprofessional.

Eventhoughwedonotexactlyknowwhatneedstobealteredlaterinthecode,therearecertainthingsthatmaygivehintstoexperiencedsoftwaredevelopers.Usually,theOOcodeiseasiertomaintainthanthead-hoccode,andtherearecodesmellsthatonecanspot.Forexample,takealookatthefollowingcodelines:

while(guesser.guess()!=Row.none){

while(guesser.nextGuess()!=Guesser.none){

publicvoidaddNewGuess(Rowrow){

Color[]guess=super.nextGuess();

Wemaysensetheodorofsomethingstrange.(EachoftheselinesisinthecodeoftheapplicationaswefinisheditinChapter4,Mastermind-CreatingaGame.)ThereturnvalueoftheguessmethodiscomparedtoRow.none,whichisaRow.Then,wecomparethereturnvalueofnextGuesstoGuesser.none,whichshouldbeaGuesser.Whenweaddanewguesstosomething,weactuallyaddaRow.Finally,wecanrealizethatnextGuessreturnsaguessthatisnotanobjectwithitsowndeclaredclass.Aguessisjustanarrayofcolors.

ShouldweintroduceanotherlayerofabstractioncreatingaGuessclass?Willitmakethecodemoremaintainable?Orwillitonlymakethecodemorecomplex?Itisusuallytruethatthelesscodelineswehave,thelesspossibilitywehaveforbugs.However,sometimes,thelackofabstractionwillmakethecodecomplexandtangled.Whatisthecaseinthissituation?Howcanwedecidethatgenerally?

Themoreexperienceyouhave,theeasieryouwilltellbylookingatthecodeandacutelyknowingwhatmodificationsyouwanttomake.Manytimes,youwillnotbothermakingthecodemoreabstract,andmanyothertimes,youwillcreatenewclasseswithouthesitation.Whenindoubt,docreatethenewclassesandseewhatcomesout.Theimportantthingisnottoruinthealreadyexistingfunctionality.Youcandothatonlyifyouhavesufficientunittests.

Whenyouwanttointroducesomenewfunctionalityorfixabug,butthecodeisnotappropriate,youwillhavetomodifyitfirst.Whenyoumodifythecodesothatthefunctionalitydoesnotchange,theprocessis

Page 381:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

namedrefactoring.Youchangeasmallpartofthecodeinalimitedtime,andthenyoubuildit.Ifitcompilesandallunittestsrun,thenyoucangoon.Thehintistorunthebuildfrequently.Itislikebuildinganewroadnearanexistingone.Onceineveryfewmiles,youshouldmeettheoldline.Failingtodoso,youwillendupsomewhereinthemiddleofthedesertinatotallywrongdirection,andallyoucandoisreturntothestartingpoint—youroldto-be-refactoredcode.Effortwasted.

Itisnotonlythesafetythatadvisesustorunthebuildfrequently,itisalsotimelimitation.Refactoringdoesnotdirectlydeliverrevenue.Thefunctionalityoftheprogramistieddirectlytoincome.Nobodywillpayusforinfiniterefactoringwork.Refactoringhastostopsometimeanditisusuallynotthetimewhenthereisnothingtoberefactoredanymore.Thecodewillneverbeperfect,butyoumaystopwhenitisgoodenough.And,manytimes,programmersareneversatisfiedwiththequalityofthecode,andwhentheyarestoppedbysomeexternalfactor(usuallycalledprojectmanager),thecodeshouldcompileandtestsshouldrunsothatthenewfeatureandbugfixingcanbeperformedontheactualcodebase.

Refactoringisahugetopicandtherearemanytechniquesthatcanbefollowedduringsuchanactivity.ItissocomplexthatthereisawholebookaboutitbyMartinFowler(http://martinfowler.com/books/refactoring.html).

Inourcase,themodificationwewanttoapplytoourcodeistoimplementaparallelalgorithm.ThefirstthingwewillmodifyistheColorManager.Whenwewantedtoprintguessesandrowsontheterminal,wehadtoimplementsomebadtricks.Whynothavecolorimplementationsthatcanbeprinted?WecanhaveaclassthatextendstheoriginalColorclassandhasamethodthatreturnssomethingthatrepresentsthatcolor.Doyouhaveanycandidatenameforthatmethod?ItisthetoStringmethod.ItisimplementedintheObjectclassandanyclasscanfreelyoverrideit.Whenyouconcatenateanobjecttoastring,automatictypeconversionwillcallthismethodtoconverttheobjecttoString.Bytheway,itisanoldtricktouse""+objectinsteadofobject.toString()toavoidnullpointerexception.Needlesstosay,wedonotusetricks.ThetoStringmethodisalsoinvokedbytheIDEswhenthedebuggerwantstodisplaythevalueofsomeobject,soitisgenerallyrecommendedtoimplementtoStringiffornothingelse,thentoeasedevelopment.IfwehaveaColorclassthatimplementstoString,thenthePrettyPrintRowclassbecomesfairlystraightforwardandtricksless:

packagepackt.java9.by.example.mastermind;

publicclassPrettyPrintRow{

publicstaticStringpprint(Rowrow){

Stringstring="";

PrintableRowpRow=newPrintableRow(row);

for(inti=0;i<pRow.nrOfColumns();i++){

string+=pRow.pos(i);

}

string+="";

string+=pRow.full();

string+="/";

string+=pRow.partial();

returnstring;

}

}

Weremovedtheproblemfromtheprintingclass,butyoumayarguethattheissueisstillthere,andyouareright.Manytimes,whenthereisaprobleminaclassdesign,thewaytothesolutiontomovetheproblemfromtheclasstoanother.Ifitisstillaproblemthere,thenyoumaysplitthedesignmoreandmoreand,atthelaststage,youwillrealizethatwhatyouhaveisanissueandnotaproblem.

Page 382:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ToimplementaLetteredColorclassisalsostraightforward:

packagepackt.java9.by.example.mastermind.lettered;

importpackt.java9.by.example.mastermind.Color;

publicclassLetteredColorextendsColor{

privatefinalStringletter;

publicLetteredColor(Stringletter){

this.letter=letter;

}

@Override

publicStringtoString(){

returnletter;

}

}

Again,theproblemwaspushedforward.But,inreality,thisisnotaproblem.ItisanOOdesign.PrintingisnotresponsibleforassigningStringtocolorsfortheirrepresentation.Andthecolorimplementationitselfisalsonotresponsibleforthat.Theassignmenthastobeperformedwherethecolorismade,andthentheStringhastobepassedtotheconstructoroftheLetteredColorclass.ThecolorinstancesarecreatedinColorManagersowehavetoimplementthisintheColorManagerclass.Ornot?WhatdoesColorManagerdo?Itcreatesthecolorsand...

Whenyoucometoanexplanationordescriptionofaclassthatliststhefunctionalities,youmayimmediatelyseethatthesingleresponsibilityprinciplewasignored.ColorManagershouldmanagethecolors.Managingisprovidingawaytogetthecolorsinadefiniteorderandgettingthefirstandthenextwhenweknowonecolor.Weshouldimplementtheotherresponsibility—thecreationofacolorinaseparateclass.

Aclassthathasthesolefunctionalitytocreateaninstanceofanotherclassiscalledfactory.Thatisalmostthesameasusingthenewoperatorbutunlikenew,thefactoriescanbeusedmoreflexibly.Wewillseethatimmediately.TheColorFactoryinterfacecontainsasinglemethod,asfollows:

packagepackt.java9.by.example.mastermind;

publicinterfaceColorFactory{

ColornewColor();

}

Interfacesthatdefineonlyonemethodarenamedfunctionalinterfacesbecausetheirimplementationcanbeprovidedasalambdaexpressionattheplacewhereyouwoulduseanobjectthatisaninstanceofaclasswhichimplementsthefunctionalinterface.TheSimpleColorFactoryimplementationcreatesthefollowingColorobjects:

packagepackt.java9.by.example.mastermind;

publicclassSimpleColorFactoryimplementsColorFactory{

@Override

publicColornewColor(){

returnnewColor();

}

}

Itisverymuchlikehowwecreateaninterface,andthenanimplementation,insteadofjustwritingnewColor()inthecodeinColorManager.LetteredColorFactoryisabitmoreinteresting:

Page 383:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

packagepackt.java9.by.example.mastermind.lettered;

importpackt.java9.by.example.mastermind.Color;

importpackt.java9.by.example.mastermind.ColorFactory;

publicclassLetteredColorFactoryimplementsColorFactory{

privatefinalStringletters="0123456789ABCDEFGHIJKLMNOPQRSTVWXYZabcdefghijklmnopqrstvwxzy";

privateintcounter=0;

@Override

publicColornewColor(){

Colorcolor=newLetteredColor(letters.substring(counter,counter+1));

counter++;

returncolor;

}

}

Now,herewehavethefunctionalitythatassignsStringstotheColorobjectswhentheyarecreated.Itisveryimportantthatthecountervariablethatkeepstrackofthealreadycreatedcolorsisnotstatic.Thesimilarvariableinthepreviouschapterwasstaticanditmeantthatitcouldrunoutofcharactersasever-newerColorManagerscreatedtoomanycolors.ItactuallydidhappentomeduringtheunittestexecutionwhenthetestseachcreatedColorManagersandnewColorinstances,andtheprintingcodetriedtoassignnewletterstothenewcolors.ThetestswererunninginthesameJVMunderthesameclassloaderandtheunfortunatestaticvariablehadnocluewhenitcouldjuststartcountingfromzeroforthenewtests.Thedrawbackisthatsomebody,somewhere,hastoinstantiatethefactoryanditisnottheColorManager.ColorManageralreadyhasaresponsibilityanditisnottocreateacolorfactory.TheColorManagerhastogettheColorFactoryinitsconstructor:

packagepackt.java9.by.example.mastermind;

importjava.util.HashMap;

importjava.util.List;

importjava.util.Map;

publicclassColorManager{

finalprotectedintnrColors;

finalprotectedMap<Color,Color>successor=newHashMap<>();

privateColorfirst;

privatefinalColorFactoryfactory;

publicColorManager(intnrColors,ColorFactoryfactory){

this.nrColors=nrColors;

this.factory=factory;

createOrdering();

}

privateColor[]createColors(){

Color[]colors=newColor[nrColors];

for(inti=0;i<colors.length;i++){

colors[i]=factory.newColor();

}

returncolors;

}

privatevoidcreateOrdering(){

Color[]colors=createColors();

first=colors[0];

for(inti=0;i<nrColors-1;i++){

successor.put(colors[i],colors[i+1]);

}

}

publicColorfirstColor(){

returnfirst;

}

publicbooleanthereIsNextColor(Colorcolor){

returnsuccessor.containsKey(color);

Page 384:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

}

publicColornextColor(Colorcolor){

returnsuccessor.get(color);

}

publicintgetNrColors(){

returnnrColors;

}

}

YoumayalsonoticethatIcouldnotresistrefactoringthecreateColorsmethodintotwomethodstofollowthesingleresponsibilityprinciple.

Now,thecodethatcreatesColorManagerhastocreateafactoryandpassittotheconstructor.Forexample,theunittest'sColorManagerTestclasswillcontainthefollowingmethod:

@Test

publicvoidthereIsAFirstColor(){

ColorManagermanager

=newColorManager(NR_COLORS,Color::new);

Assert.assertNotNull(manager.firstColor());

}

Thisisthesimplestwayevertoimplementafactorydefinedbyafunctionalinterface.Justnametheclassandreferencethenewoperatorlikeitwasamethodbycreatingamethodreference.

ThenextthingwewillrefactoristheGuessclass,which,actually,wedidnothavesofar.AGuessclasscontainsthepegsoftheguessandcancalculatethenumberoffull(coloraswellasposition)andpartial(colorpresentbutinwrongposition)matches,andcanalsocalculatethenextGuessthatcomesafterthisguess.ThisfunctionalitywasimplementedintheGuesserclasssofar,butthisisnotreallythefunctionalityforhowweselecttheguesseswhencheckingthealreadymadeguessesonthetable.Ifwefollowthepatternwesetupforthecolors,wemayimplementthisfunctionalityinaseparateclassnamedGuessManager,butasfornow,itisnotneeded.Again,thisisnotblackandwhite.

ItisimportanttonotethataGuessobjectcanonlybemadeatonce.Ifitisonthetable,theplayerisnotallowedtochangeit.IfwehaveaGuessthatisnotyetonthetable,itisstilljustaGuessidentifiedbythecolorsandordersofthepegs.AGuessobjectneverchangesafteritwascreated.Suchobjectsareeasytouseinmultithreadprogramsandarecalledimmutableobjects:

packagepackt.java9.by.example.mastermind;

importjava.util.Arrays;

importjava.util.HashSet;

importjava.util.Set;

publicclassGuess{

finalstaticpublicGuessnone=newGuess(newColor[0]);

finalprivateColor[]colors;

privatebooleanuniquenessWasNotCalculated=true;

privatebooleanunique;

publicGuess(Color[]colors){

this.colors=Arrays.copyOf(colors,colors.length);

}

Theconstructoriscreatingacopyofthearrayofcolorsthatwerepassed.AsaGuessisimmutable,thisisextremelyimportant.Ifwejustkeeptheoriginalarray,anycodeoutsideoftheGuessclasscouldalterthe

Page 385:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

elementsofthearray,essentiallychangingthecontentofGuessthatisnotsupposedtobechanging:

publicColorgetColor(inti){

returncolors[i];

}

publicintnrOfColumns(){

returncolors.length;

}

/**

*CalculatethenextguessandreturnanewGuessobject.

*Theguessesareorderedintheorderofthecolorsas

*specifiedbythecolormanager.

*

*@parammanagerthatspecifiestheorderofthecolors

*canreturnthenextcolorafteronecolor.

*@returntheguessthatcomesafterthisguess.

*/

publicGuessnextGuess(ColorManagermanager){

finalColor[]colors=Arrays.copyOf(

this.colors,nrOfColumns());

inti=0;

booleanguessFound=false;

while(i<colors.length&&!guessFound){

if(manager.thereIsNextColor(getColor(i))){

colors[i]=manager.nextColor(colors[i]);

guessFound=true;

}else{

colors[i]=manager.firstColor();

i++;

}

}

if(guessFound){

returnnewGuess(colors);

}else{

returnGuess.none;

}

}

Inthismethod,westarttocalculatethenextGuessstartingwiththecolorarraythatiscontainedintheactualobject.Weneedaworkarraythatismodified,sowewillcopytheoriginal.Thefinalnewobjectcan,thistime,usethearrayweuseduringthecalculation,sothatwillneedaseparateconstructorthatdoesnotcreateacopy.Itispossibleextracode,butweshouldconsidermakingthatonlyifweseethatthatisthebottleneckinthecodeandwearenotsatisfiedwiththeactualperformance.

ThenextmethodjustchecksifthepassedGuesshasthesamenumberofcolorsastheactualone.Thisisjustasafetycheckusedbythenexttwomethodsthatcalculatethematches:

privatevoidassertCompatibility(Guessguess){

if(nrOfColumns()!=guess.nrOfColumns()){

thrownewIllegalArgumentException("Cannotcomparedifferentlengthguesses");

}

}

/**

*Countthenumberofcolorsthatarepresentontheguess

*butnotontheposwheretheyareintheotherguess.

*Ifthesamecolorisonmultiplepositiscounted

*foreachposonce.Forexamplethesecretis

*<pre>

*RGRB

*</pre>

*andtheguessis

*<pre>

*YRPR

*</pre>

*thenthismethodwillreturn2.

*

Page 386:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

*@paramguessistheactualguessthatweevaluate

*@returnthenumberofgoodcolorsnotinpos

*/

publicintnrOfPartialMatches(Guessguess){

assertCompatibility(guess);

intcount=0;

for(inti=0;i<nrOfColumns();i++){

for(intj=0;j<nrOfColumns();j++){

if(i!=j&&

guess.getColor(i)==this.getColor(j)){

count++;

}

}

}

returncount;

}

/**

*Countthenumberofcolorsthatarecorrectandareinpos.

*

*@paramguessistheactualguessthatweevaluate

*@returnthenumberofcolorsthatmatchinpos

*/

publicintnrOfFullMatches(Guessguess){

assertCompatibility(guess);

intcount=0;

for(inti=0;i<nrOfColumns();i++){

if(guess.getColor(i)==this.getColor(i)){

count++;

}

}

returncount;

}

TheisUniquemethodchecksifthereisanycolormorethanonceintheGuess.AstheGuessisimmutable,itmaynothappenthataGuessisuniqueonetimeandnotuniqueatanothertime.Thismethodshouldreturnthesameresultwheneveritiscalledonaspecificobject.Becauseofthat,itispossibletocachetheresult.Thismethoddoesthis,savingthereturnvaluetoaninstancevariable.

Youmaysaythatthisisprematureoptimization.Yes,itis.Idecidedtodoitforonereason.Itisdemonstration,andbasedonthat,youcantrytomodifythenextGuessmethodtodothesame:

/**

*@returntrueiftheguessdoesnot

*containanycolormorethanonce

*/

publicbooleanisUnique(){

if(uniquenessWasNotCalculated){

finalSet<Color>alreadyPresent=newHashSet<>();

unique=true;

for(Colorcolor:colors){

if(alreadyPresent.contains(color)){

unique=false;

break;

}

alreadyPresent.add(color);

}

uniquenessWasNotCalculated=false;

}

returnunique;

}

Methodsthatreturnthesameresultforthesameargumentsarecalledidempotent.Cachingthereturnvalueforsuchamethodcanbeveryimportantifthemethodiscalledmanytimesandthecalculationisusingalotofresources.Whenthemethodhasarguments,theresultcachingisnotsimple.Theobjectmethodhastoremembertheresultforallargumentsthatwerealreadycalculated,andthisstoragehastobeeffective.Ifittakesmoreresourcestofindthestoredresultthanthecalculationofit,thentheuseofcachenotonly

Page 387:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

usesmorememorybutalsoslowsdowntheprogram.Ifthemethodiscalledforseveralargumentsduringthelifetimeoftheobject,thenthestoragememorymayjustgrowtoolarge.Someoftheelementshavetobepurged—thosethatwillnotbeneededanymoreinthefuture.However,wecannotknowwhichelementsofthecachearenotneeded,sowewillhavetoguess.

Asyoucansee,cachingcangetcomplexveryfastand,todothatprofessionally,itisalmostalwaysbettertousesomereadilyavailablecacheimplementation.Thecachingweusehereisonlythetipoftheiceberg.Or,itisevenonlythesunshineglimpsingonit.

Therestoftheclassisfairlystandardandsomethingwehavetalkedaboutindetail—agoodcheckofyourknowledgeistounderstandhowtheequals,hashCode,andtoStringmethodsareimplementedthisway.IimplementedthetoStringmethodtohelpmeduringdebugging,butitisalsousedinthefollowingexampleoutput:

@Override

publicbooleanequals(Objectother){

if(this==other)returntrue;

if(other==null||!(otherinstanceofGuess))

returnfalse;

Guessguess=(Guess)other;

returnArrays.equals(colors,guess.colors);

}

@Override

publicinthashCode(){

returnArrays.hashCode(colors);

}

@Override

publicStringtoString(){

if(this==none){

return"none";

}else{

Strings="";

for(inti=colors.length-1;i>=0;i--){

s+=colors[i];

}

returns;

}

}

}

ThisismainlythemodificationthatIneededwhileIdevelopedtheparallelalgorithm.Now,thecodeisfairlyup-to-dateanddescribedtofocusonthemaintopicofthischapter:howtoexecutecodeinJavainparallel.

TheparallelexecutionofthecodeinJavaisdoneinthreads.YoumayknowthatthereisaThreadobjectinJavaruntime,butwithoutunderstandingwhatathreadinthecomputeris,itmakesnosense.Inthefollowingsubsections,wewilllearnwhatthesethreadsare,howtostartanewthread,howtosynchronizedataexchangebetweenthreads,andfinallyputallthistogetherandimplementtheMastermindparallelguessingalgorithm.

Page 388:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 389:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ProcessesWhenyoustartyourcomputer,theprogramthatstartsistheoperatingsystem(OS).TheOScontrolsthemachinehardwareandtheprogramsthatyoucanrunonthemachine.Whenyoustartaprogram,theOScreatesanewprocess.ItmeansthattheOSallocatesanewentryinatable(array)whereitadministerstheprocessesandfillsintheparametersthatitknows,andneedstoknow,abouttheprocess.Forexample,itregisterswhatmemorysegmenttheprocessisallowedtouse,whattheIDoftheprocessis,andwhichuserstartedfromwhichotherprocess.Youcannotstartaprocessjustoutofthinair.Whenyoudouble-clickonanEXEfile,youactuallytellthefileexplorer,whichisaprogramrunningasaprocess,tostarttheEXEfileasaseparateprocess.TheexplorercallsthesystemviasomeAPIandkindlyaskstheOStodothat.TheOSwillregistertheexplorerprocessastheparentofthenewprocess.TheOSdoesnotactuallystarttheprocess,butcreatesallthedatathatitneedstostartitand,whenthereissomefreeCPUresource,thentheprocessgetsstarted,andthenitgetspausedverysoon.YouwillnotnoticeitbecausetheOSwillstartitagainandagainandisalwayspausingtheprocessrepeatedly.Itneedstodoittoproviderunpossibilitiestoallprocesses.Thatway,weexperienceallprocessesrunningatthesametime.Inreality,processesdonotrunatthesametimeonasingleprocessor,buttheygettimeslotstorunoften.

IfyouhavemorethanoneCPUinthemachine,thenprocessescanactuallyrunatthesametime,asmanyCPUsasthereare.Astheintegrationgetsmoreadvancedtoday,desktopcomputershaveCPUsthatcontainmultiplecoresthatfunctionalmostlikeseparateCPUs.Onmymachine,Ihavefourcores,eachcapableofexecutingtwothreadssimultaneously;so,myMacisalmostlikean8CPUmachine.

Processeshaveseparatememories.Theyareallowedtouseonepartofthememoryandifaprocesstriestouseanotherpartthatdoesnotbelongtoit,theprocessorwillstopdoingso.TheOSwillkilltheprocess.

JustimaginehowfrustratedthedevelopersoftheoriginalUNIXcouldhavebeenthattheynamedtheprogramtostopaprocesstokill,andstoppingaprocessiscalledkillingit.Itislikemedievalageswhentheycutoffthehandofafelon.Youtouchthewrongpartofthememoryandgetkilled.Iwouldnotliketobeaprocess.

Thememoryhandlingbytheoperatingsystemisverycomplexinadditiontoseparatingtheprocessesfromeachother.Whenthereisnotenoughmemory,theOSwritespartofthememorytodiskfreeingupthememoryandreloadingthatpartwhenitisneededagain.Thisisaverycomplex,low-levelimplementedandhighlyoptimizedalgorithmthatistheresponsibilityoftheOS.

Page 390:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 391:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThreadsWhenIsaidthattheOSexecutestheprocessesintimeslots,Iwasnotabsolutelyprecise.Everyprocesshasoneormorethreads,andthreadsareexecuted.Athreadisthesmallestexecutionmanagedbyanexternalscheduler.Olderoperatingsystemsdidnothavethenotionofathreadandwereexecutingprocesses.Asamatteroffact,thefirstthreadimplementationsweresimplyduplicationsofprocessesthatweresharingthememory.

Youmayheartheterminology,lightweightprocess—itmeansathread.

Theimportantthingisthatthethreadsdonothavetheirownmemory.Theyusethememoryoftheprocess.Inotherwords,thethreadsthatruninthesameprocesshaveundistinguishedaccesstothesamememorysegment.Itisanextremelypowerfulpossibilitytoimplementparallelalgorithmsthatmakeuseofthemultiplecoresinthemachine,butatthesametime,itmayleadtobugs.

Imaginethattwothreadsincrementthesamelongvariable.Theincrementfirstcalculatestheincrementedvalueofthelower32bitsandthentheupper,iftherewereanyoverflowbits.ThesearetwoormorestepsthatmaybeinterruptedbytheOS.Itmayhappenthatonethreadincrementsthelower32bits,

Page 392:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

remembersthatthereissomethingtodototheupper32bits,startsthecalculation,buthasnotimetostoretheresultbeforeitgetsinterrupted.Then,anotherthreadincrementsthelower32bits,theupper32bits,andthenthefirstthreadjustsavestheupper32bitsthatitcalculated.Theresultgetsgarbled.Onanolder32-bitJavaimplementation,itwasextremelyeasytodemonstratethiseffect.Ona64-bitJavaimplementation,allthe64bitsareloadedintoregistersandsavedbacktothememoryinonestepsoitisnotthateasytodemonstratemultithreadissues,butitdoesnotmeanthattherearenone.

Whenathreadispausedandanotherthreadisstarted,theoperatingsystemhastoperformacontextswitch.Itmeansthat,amongotherthings,theCPUregistershavetobesavedandthensettothevaluethattheyshouldhavefortheotherthread.Acontextswitchisalwayssavingthestateofthethreadandloadingthepreviouslysavedstateofthethreadtobestarted.ThisisonaCPUregisterlevel.Thiscontextswitchistimeconsuming;therefore,themorecontextswitchesthataredone,themoreCPUresourceisusedforthethreadadministrationinsteadoflettingthemrun.Ontheotherhand,iftherearenotenoughswitches,somethreadsmaynotgetenoughtimeslotstoexecute,andtheprogramhangs.

Page 393:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 394:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

FibersJavadoesnothavefibers,butastherearesomelibrariesthatsupportfiberhandlings,itisworthmentioning.Afiberisafinerunitthanathread.Aprogramcodeexecutinginathreadmaydecidetogiveuptheexecutionandtellthefibermanagertojustexecutesomeotherfiber.Whatisthepointandwhyisitbetterthanusinganotherthread?Thereasonisthatthisway,fiberscanavoidpartofthecontextswitch.AcontextswitchcannotbeavoidedtotallybecauseadifferentpartofthecodethatstartstoexecuteitmayusetheCPUregistersinatotallydifferentway.Asitisthesamethread,thecontextswitchingisnotthetaskoftheOS,buttheapplication.

TheOSdoesnotknowifthevalueofaregisterisusedornot.Therearebitsintheregisters,andnoonecantellseeingonlytheprocessorstatewhetherthosebitsarerelevantforthecurrentcodeexecutionorjusthappentobethereinthatway.Theprogramgeneratedbyacompilerdoesknowwhichregistersareimportantandwhicharethosethatcanjustbeignored.Thisinformationchangesfromplacetoplaceinthecode,butwhenthereisaneedforaswitch,thefiberpassestheinformationofwhatisneededtobeswitchedatthatpointtothecodethatdoestheswitching.

Thecompilercalculatesthisinformation,butJavadoesnotsupportfibersinthecurrentversion.ThetoolsthatimplementfibersinJavaanalyzeandmodifythebytecodeoftheclassestodothisafterthecompilationphase.

Golang'sgoroutinesarefibersandthatiswhyyoucaneasilystartmanythousandgoroutinesinGo,butyoubetterlimitthenumberofthreadsinJavatoalowernumber.Theyarenotthesamethings.

Astheterminologylightweightprocessisfadingoutandusedbylessandlessfibers,manytimesarereferredtoaslightweightthreads.

Page 395:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 396:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

java.lang.ThreadAseverythinginJava(well,almost)isobject,ifwewanttostartanewthread,wewillneedaclassthatrepresentsthethread.Thisclassisjava.lang.ThreadbuiltintotheJDK.WhenyoustartaJavacode,theJVMautomaticallycreatesafewThreadobjectsandusesthemtorundifferenttasksthatareneededbyit.IfyoustartupVisualVM,youcanselecttheThreadstabofanyJVMprocessandseetheactualthreadsthatareintheJVM.Forexample,theVisualVMasIstartedithas29livethreads.Oneofthemisthethreadnamedmain.Thisistheonethatstartstoexecutethemainmethod(surprise!).Themainthreadstartedmostoftheotherthreads.Whenwewanttowriteamultithreadapplication,wewillhavetocreatenewThreadobjectsandstartthem.ThesimplestwaytodothatisnewThread(),andthencallingthestartmethodonthethread.ItwillstartanewThreadthatwilljustfinishimmediatelyaswedidnotgiveitanythingtodo.TheThreadclass,asitisintheJDK,doesnotdoourbusinesslogic.Thefollowingarethetwowaystospecifythebusinesslogic:

CreatingaclassthatimplementstheRunnableinterfaceCreatingaclassthatextendstheThreadclassandoverridestherunmethod

Thefollowingblockofcodeisaverysimpledemonstrationprogram:

publicclassThreadIntermingling{

staticclassMyThreadextendsThread{

privatefinalStringname;

MyThread(Stringname){

this.name=name;

}

@Override

publicvoidrun(){

for(inti=1;i<1000;i++){

System.out.print(name+""+i+",");

}

}

}

publicstaticvoidmain(String[]args){

Threadt1=newMyThread("t1");

Threadt2=newMyThread("t2");

t1.start();

t2.start();

System.out.print("started");

}

}

Theprecedingcodecreatestwothreadsandstartsthemoneaftertheother.Whenthestartmethodiscalled,itschedulesthethreadobjecttobeexecutedandthenreturns.Asaresult,thenewthreadwillsoonstartexecutingasynchronouslywhilethecallingthreadcontinuesitsexecution.Thetwothreads,andthemainthread,runparallelinthefollowingexampleandcreateanoutputthatlookssomethinglikethis:

startedt21,t22,t23,t24,t25,t26,t27,t28,t11,t29,t210,t211,t212,...

Theactualoutputchangesfromruntorun.Thereisnodefiniteorderoftheexecutionorhowthethreadsgetaccesstothesinglescreenoutput.Thereisnotevenguaranteethatineachandeveryexecution,themessagestartedisprintedbeforeanyofthethreadmessages.

Togetabetterunderstandingofthis,wewillhavetolookatthestatediagramofthreads.AJavaThread

Page 397:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

canbeinoneofthefollowingstates:

NEW

RUNNABLE

BLOCKED

WAITING

TIMED_WAITING

TERMINATED

ThesestatesaredefinedintheenumThread.State.Whenyoucreateanewthreadobject,itisintheNEWstate.Atthismoment,thethreadisnothingspecial,itisjustanobjectbuttheoperatingsystemexecution-schedulingdoesnotknowaboutit.Insomesense,itisonlyapieceofmemoryallocatedbytheJVM.

Whenthestartmethodisinvoked,theinformationaboutthethreadispassedtotheoperatingsystemandtheOSschedulesthethreadsoitcanbeexecutedbyitwhenthereisanappropriatetimeslot.Doingthisisaresourcefulactionandthatisthereasonwhywedonotcreateand,especially,donotstartnewThreadobjectsonlywhenitisneeded.InsteadofcreatingnewThreads,wewillkeeptheexistingthreadsforawhile,eveniftheyarenotneededatthemoment,andreuseanexistingoneifthereisonesuitable.

AthreadintheOScanalsobeinarunningstateaswellasrunnablewhentheOSschedulesandexecutesitatthemoment.JavaJDKAPIdoesnotdistinguishbetweenthetwoforgoodreason.Itwouldbeuseless.WhenathreadisintheRUNNABLEstateaskingifitisactuallyrunningfromthethreaditself,itwillresultinanobviousanswer:ifthecodejustreturnedfromthegetStatemethodimplementedintheThreadclass,thenitruns.Ifitwerenotrunning,itwouldnothavereturnedfromthecallinthefirstplace.IfthegetStatemethodwascalledfromanotherthread,thentheresultabouttheotherthreadbythetimethemethodreturnswouldbemeaningless.TheOSmayhavestopped,orstarted,thequeriedthreadseveraltimesuntilthen.

AthreadisinaBLOCKEDstatewhenthecodeexecutinginthethreadtriestoaccesssomeresourcethatisnotcurrentlyavailable.Toavoidconstantpollingofresources,theoperatingsystemprovideseffectivenotificationmechanismsothethreadsgetbacktotheRUNNABLEstatewhentheresourcetheyneedbecomesavailable.

AthreadisintheWAITorTIMED_WAITINGstatewhenitwaitsforsomeotherthreadorlock.TIMED_WAITINGisthestatewhenthewaitingstartedcallingaversionofamethodthathastimeout.

Finally,theTERMINATEDstateisreachedwhenthethreadfinishesitsexecution.Ifyouappendthefollowinglinestotheendofourpreviousexample,thenyouwillgetaTERMINATEDprintoutandalsoanexceptionthrownuptothescreencomplainingaboutillegalthreadstate,whichisbecauseyoucannotstartanalreadyterminatedthread:

System.out.println();

System.out.println(t1.getState());

System.out.println();

t1.start();

InsteadofextendingtheThreadclasstodefinewhattoexecuteasynchronously,wecancreateaclassthatimplementsRunnable.DoingthatismoreinlinewiththeOOprogrammingapproach.Thesomethingthatwe

Page 398:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

implementintheclassisnotafunctionalityofathread.Itismoreofasomethingthatcanbeexecuted.Itissomethingthatcanjustrun.

Ifthisexecutionisasynchronousinadifferentthread,oritisexecutedinthesamethreadthatwascallingtherunmethod,isadifferentconcernthathastobeseparated.Ifwedoitthatway,wecanpasstheclasstoaThreadobjectasaconstructorargument.CallingstartontheThreadobjectwillstarttherunmethodoftheobjectwepassed.Thisisnotthegain.ThegainisthatwecanalsopasstheRunnableobjecttoanExecutor(dreadfulname,huhh!).Executorisaninterface,andimplementationsexecuteRunnable(andalsoCallable,seelater)objectsinThreadsinanefficientway.ExecutorsusuallyhaveapoolofThreadobjectsthatareprepared,andintheBLOCKEDstate.WhentheExecutorhasanewtasktoexecute,itgivesittooneoftheThreadobjectsandreleasesthelockthatisblockingthethread.TheThreadgetsintotheRUNNABLEstate,executestheRunnable,andgetsblockedagain.ItdoesnotterminateandthuscanbereusedtoexecuteanotherRunnablelater.Thatway,Executorsavoidtheresourceconsumingprocessofthreadregistrationintotheoperatingsystem.

ProfessionalapplicationcodenevercreatesanewThread.ApplicationcodeusessomeframeworktohandletheparallelexecutionofthecodeorusesExecutorsprovidedbysomeExecutorServicetostartRunnableorCallableobjects.

Page 399:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 400:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Pitfalls

Wehavealreadydiscussedmanyoftheproblemsthatwemayfacewhendevelopingparallelprogram.Inthissection,wewillsummarizethemwiththeusualterminologyusedfortheproblems.Terminologyisnotonlyinteresting,butitisalsoimportantwhenyoutalkwithcolleaguestoeasilyunderstandeachother.

Page 401:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 402:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

DeadlocksDeadlockisthemostinfamousparallelprogrammingpitfall,andforthisreason,wewillstartwiththisone.Todescribethesituation,wewillfollowthemetaphorofbureaucrats.

Thebureaucrathastostampapaperhehasinhishand.Todothat,heneedsthestamp,andhealsoneedstheinkpad.First,hegoestothedrawerwherethestampisandtakesit.Then,hewalkstothedrawerwheretheinkpadisandtakestheinkpad.Heinksthestamp,pushesonthepaper.Then,heputsthestampbacktoitsplaceandthentheinkpadbackinitsplace.Everythingisnice,weareoncloud9.

Whathappensifanotherbureaucrattakestheinkpadfirstandthenthestampsecond?Theymaysoonendupasonebureaucratwiththestampinhandwaitingfortheinkpadandanotheronewiththeinkpadinhandwaitingforthestamps.And,theymayjuststaythere,frozenforever,andthenmoreandmorestarttowaitfortheselocks,thepapersnevergetstamped,andthewholesystemsinksintoanarchy.

Toavoidsuchsituations,thelockshavetobeorderedandthelocksshouldalwaysbeacquiredintheorder.Intheprecedingexample,thesimpleagreementthattheinkpadisacquiredfirstandthestampsecondsolvestheproblem.Whoeveracquiredthestampcanbesurethattheinkpadisfreeorwillsoonbefree.

Page 403:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 404:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RaceconditionsWetalkaboutraceconditionswhentheresultofacalculationmaybedifferentbasedonthespeedandCPUaccessofthedifferentparallelrunningthreads.Let'stakealookatthefollowingtwocodelines:

voidmethod1(){

1a=b;

2b=a+1;

}

voidmethod2(){

3c=b;

4b=c+2;

}

Ifthevalueofbatthestartoftheexecutionis0,andtwodifferentthreadsexecutethetwomethods,thentheorderofthelinescanbe1234,1324,1342,3412,3142,or3142.Anyexecutionorderofthefourlinesmayhappenwhichassuresthat1runsbefore2and3runsbefore4,butnootherrestrictions.Theoutcome,thevalueofb,iseither1or2attheendoftheexecutionofthesegments,whichmaynotbegoodandwhatwewantedwhencoding.

NotethattheimplementationoftheparallelMastermindgamealsohassomethinglikethis.Theactualguessesverymuchdependonthespeedofthedifferentthreads,butthisisirrelevantfromthefinalresultpointofview.Wemayhavedifferentguessesindifferentrunsandthatwaythealgorithmisnotdeterministic,butweareguaranteedtofindthefinalsolution.

Page 405:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 406:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Overusedlocks

Inmanysituations,itmayhappenthatthethreadsarewaitingonalock,whichprotectsaresourcefromconcurrentaccess.Iftheresourcecannotbeusedbymultiplethreadssimultaneously,andtherearemorethreadsthancanbeserved,thenthethreadsarestarving.However,inmanycases,theresourcecanbeorganizedinawaysothatthethreadscangetaccesstosomeoftheservicesthattheresourceprovides,andthelockingstructurecanbelessrestrictive.Inthatcase,thelockisoverusedandthesituationcanbemendedwithoutallocatingmoreresourceforthethreads.Itmaybepossibletouseseverallocksthatcontroltheaccesstothedifferentfunctionalityoftheresource.

Page 407:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 408:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Starving

Starvingisthesituationwhenseveralthreadsarewaitingforaresourcetryingtoacquirealockandsomethreadsgetaccesstothelockonlyafterextremelylongtimeornever.Whenthelockisreleasedandtherearethreadswaitingforit,thenoneofthethreadscangetthelock.Thereisusuallynoguaranteethatathreadgetsthelockifitwaitslongenough.Suchamechanismwouldrequireintensiveadministrationofthethreads,sortingtheminthewaitingqueue.Aslockingshouldbealowlatencyandhighperformanceaction,evenafewCPUclockcyclesaresignificant;therefore,thelocksdonotprovidethistypeoffairaccessbydefault.Notwastingtimewithfairnessinthreadschedulingisagoodapproach,incasethelockshaveonethreadwaiting.Themaingoaloflocksisnotschedulingthewaitingthreads,butratherpreventingparallelaccesstoresources.

Itislikeinashop.Ifthereissomebodyatthecashier,youwait.Itisalockbuiltinimplicitly.Itisnotaproblemifpeopledonotqueueupforthecashier,solongaslongthereisalmostalwaysonefree.However,whenthereareseveralqueuesbuiltupinfrontofthecashiers,thenhavingnoqueueandwaitingorderwillcertainlyleadtosomeverylongwaitingorderforsomeonewhoisslowtogetaccesstothecashier.Generally,thesolutionoffairnessandcreatingqueueofwaitingthreads(customers)isnotagoodsolution.Thegoodsolutionistoeliminatethesituationthatleadstowaitingqueues.Youcanemploymorecashiers,oryoucandosomethingtotallydifferentthatmakesthepeakloadsmaller.Inashop,youcangivediscounttodrivecustomerswhocomeinatoff-peakhours.Inprogramming,severaltechniquescanbeapplied,usually,dependingontheactualbusinesswecodeandfairschedulingoflocksisusuallyaworkaround.

Page 409:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 410:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ExecutorServiceExecutorServiceisaninterfaceintheJDK.AnimplementationoftheinterfacecanexecuteaRunnableorCallableclassinanasynchronousway.TheinterfaceonlydefinestheAPIfortheimplementationanddoesnotrequirethattheinvocationisasynchronousbut,inreality,thatisthemainpointimplementingsuchaservice.InvokingtherunmethodofaRunnableinterfaceinasynchronouswayissimplycallingamethod.Wedonotneedaspecialclassforthat.

TheRunnableinterfacedefinesonerunmethod.Ithasnoargumentsreturnsnovalueanddoesnotthrowanyexception.TheCallableinterfaceisparameterizedandtheonlymethoditdefines,call,hasnoargumentbutreturnsagenericvalueandmayalsothrowException.Inourcode,wewillimplementRunnableifwejustwanttorunsomething,andCallablewhenwewanttoreturnsomething.Bothoftheseinterfacesarefunctionalinterfaces,therefore,theyaregoodcandidatestobeimplementedusinglambda.

TohaveaninstanceofanimplementationofanExecutorService,wecanusetheutilityclassExecutors.ManytimeswhenthereisanXYZinterfaceintheJDK,therecanbeanXYZs(plural)utilityclassthatprovidesfactoryfortheimplementationsoftheinterface.Ifwewanttostartthet1taskmanytimes,wecandosowithoutcreatinganewThread.Weshouldusethefollowingexecutorservice:

publicclassThreadIntermingling{

staticclassMyThreadimplementsRunnable{

privatefinalStringname;

MyThread(Stringname){

this.name=name;

}

@Override

publicvoidrun(){

for(inti=1;i<1000;i++){

System.out.print(name+""+i+",");

}

}

}

publicstaticvoidmain(String[]args)

throwsInterruptedException,ExecutionException{

ExecutorServicees=Executors.newFixedThreadPool(2);

Runnablet1=newMyThread("t1");

Runnablet2=newMyThread("t2");

Future<?>f1=es.submit(t1);

Future<?>f2=es.submit(t2);

System.out.print("started");

f1.get();

f2.get();

System.out.println();

f1=es.submit(t1);

es.shutdown();

}

}

Thistime,wedonotgetanyexception.Instead,thet1taskrunssecondtime.Inthisexample,weareusingafixedsizethreadpoolthathastwoThreads.Aswewanttostartonlytwothreadssimultaneously,itisenough.Thereareimplementationsthatgrowandshrinkthesizeofthepooldynamically.Fixedsizepoolshouldbeusedwhenwewanttolimitthenumberofthethreadsorweknowfromsomeotherinformationsourcethenumberofthea-priorythreads.Inthiscase,itisagoodexperimenttochangethesizeofthepooltooneandseethatthesecondtaskwillnotstartinthiscaseuntilthefirstonefinishes.Theservicewillnothaveanotherthreadfort2andwillhavetowaituntiltheoneandonlyThreadinthepoolisfreed.

Page 411:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Whenwesubmitthetasktotheservice,itreturnsevenifthetaskcannotcurrentlybeexecuted.Thetasksareputinaqueueandwillstartexecutionassoonasthereisenoughresourcetostartthem.ThesubmitmethodreturnsaFutureobject,aswecanseeintheprecedingsample.

Itislikeaserviceticket.Youbringyourcartotherepairmechanic,andyougetaticket.Youarenotrequiredtostaythereuntilthecarisfixed,butatanytime,youcanaskifthecarisready.Allyouneedistheticket.Youcanalsodecidetowaituntilthecarisready.AFutureobjectisalsosomethinglikethat.Youdonotgetthevaluethatyouneed.Itwillbecalculatedasynchronously.However,thereisaFuturepromisethatitwillbethereandyourtickettoaccesstheobjectyouneedistheFutureobject.

WhenyouhaveaFutureobject,youcancalltheisDonemethodtoseeifitisready.Youcanstartwaitingforittocallgetwith,orwithout,sometimeout.Youcanalsocancelthetaskexecutingit,butinthatcase,theoutcomemaybequestionable.Justlike,incaseofyourcar,ifyoudecidetocancelthetask,youmaygetbackyourcarwiththemotordisassembled.Similarly,cancellingataskthatisnotpreparedforitmayleadtoresourceloss,openedandinaccessibledatabaseconnection(thisisapainfulmemoryforme,evenafter10years),orjustagarbledunusableobject.Prepareyourtaskstobecancelledordonotcancelthem.

Intheprecedingexample,thereisnoreturnvalueforFuturebecausewesubmittedaRunnableobjectandnotaCallableone.InthatcasethevaluepassedtotheFutureisnottobeused.Itisusuallynull,butthatisnothingtoleanon.

Thefinalandmostimportantthingthatmanydevelopersmiss,evenme,afternotwritingmultithreadJavaAPIusingcodeforyears,isshuttingdowntheExecutorService.TheExecutorServiceiscreatedandithasThreadelements.TheJVMstopswhenallnon-daemonthreadsarestopped.Itain'tovertillthefatladysings.

Athreadisadaemonthreadifitwassettobedaemon(invokingsetDaemon(true))beforeitwasstarted.Athreadisautomaticallydaemonofthestartingthreadisadaemonthread.DaemonthreadsarestoppedbytheJVMwhenallotherthreadsarefinishedandtheJVMwantstofinish.SomeofthethreadstheJVMexecutesitselfaredaemonthreads,butitislikelythatthereisnopracticaluseofcreatingdaemonthreadsinanapplicationprogram.

NotshuttingdowntheservicesimplypreventstheJVMfromstopping.Thecodewillhangafterthemainmethodfinishes.TotelltheExecutorServicethatthereisnoneedforthethreadsithas,wewillhavetoshutdowntheservice.Thecallwillonlystarttheshutdownandreturnimmediately.Inthiscase,wedonotwanttowait.TheJVMdoesanyway.Ifweneedtowait,wewillhavetocallawaitTermination.

Page 412:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 413:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ForkJoinPoolTheForkJoinPoolisaspecialExecutorServicethathasmethodstoexecuteForkJoinTaskobjects.Theseclassesareveryhandywhenthetaskthatwewanttoperformcanbesplitintomanysmalltasksandthentheresults,whentheyareavailable,aggregated.Usingthisexecutor,weneednotcareaboutthesizeofthethreadpoolandshuttingdowntheexecutor.Thesizeofthethreadpoolisadjustedtothenumberofprocessorsonthegivenmachinetohaveoptimalperformance.AstheForkJoinPoolisaspecialExecutorServicethatisdesignedforshortrunningtasks,itdoesnotexpectanytasktobetherelongerorbeingneededwhentherearenomoretaskstorun.Therefore,itisexecutedasadaemonthread;whentheJVMshutsdown,theForkJoinPoolautomaticallystopsandtheladydoesnotsinganymore.

Tocreateatask,theprogrammershouldextendeitherRecursiveTaskorRecursiveAction.Thefirstoneistobeusedwhenthereissomereturnvaluefromthetask,thesecondwhenthereisnocomputedvaluereturned.Theyarecalledrecursivebecausemanytimes,thesetaskssplittheproblemtheyhavetosolvesmallerproblemsandinvokethesetasksasynchronouslythroughthefork-joinAPI.

AtypicalproblemtobesolvedusingthisAPIisthequick-sort.IntheChapter3,OptimizingtheSort-MakingCodeProfessionalwecreatedtwoversionsofthequick-sortalgorithm.Oneusingrecursivecallsandonewithoutusingit.Wecanalsocreateanewone,which,insteadofcallingitselfrecursively,schedulethetasktobeexecuted,perhapsbyanotherprocessor.TheschedulingisthetaskoftheForkJoinPoolimplementationofExecutorService.

YoumayrevisitthecodeofQsort.javainChapter3,OptimizingtheSort-MakingCodeProfessional.HereistheversionthatisusingForkJoinPool:

publicclassFJQuickSort<E>{

finalprivateComparator<E>comparator;

finalprivateSwapperswapper;

publicFJQuickSort(Comparator<E>comparator,Swapperswapper){

this.comparator=comparator;

this.swapper=swapper;

}

publicvoidqsort(SortableCollection<E>sortable,

intstart,intend){

ForkJoinPoolpool=newForkJoinPool();

pool.invoke(newRASort(sortable,start,end));

}

privateclassRASortextendsRecursiveAction{

finalSortableCollection<E>sortable;

finalintstart,end;

publicRASort(SortableCollection<E>sortable,

intstart,intend){

this.sortable=sortable;

this.start=start;

this.end=end;

}

publicvoidcompute(){

if(start<end){

finalEpivot=sortable.get(start);

finalPartitioner<E>partitioner=

newPartitioner<>(comparator,swapper);

intcutIndex=partitioner.partition(

sortable,start,end,pivot);

Page 414:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

if(cutIndex==start){

cutIndex++;

}

RecursiveActionleft=

newRASort(sortable,start,cutIndex-1);

RecursiveActionright=

newRASort(sortable,cutIndex,end);

invokeAll(left,right);

left.join();

right.join();

}

}

}

Wheneveryoucansplityourtasksintosubtaskssimilartothewayitwasdoneintheprecedingquick-sortexample,IrecommendthatyouuseForkJoinPoolasanExecutorService.YoucanfindgooddocumentationontheAPIandtheuseontheJavaDocdocumentationofOracle.

Page 415:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 416:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

VariableaccessNowthatwecanstartthreadsandcreatecodethatrunsparallel,itistimetotalkalittlebitabouthowthesethreadscanexchangedatabetweeneachother.Atfirstglimpse,itseemsfairlysimple.Thethreadsusethesamesharedmemory;therefore,theyallcanreadandwriteallthevariablesthattheJavaaccessprotectionallowsthem.Thisistrue,exceptthatsomethreadsmayjustdecidenottoreadthememory.Afterall,iftheyhavejustrecentlyreadthevalueofsomevariable,whyreaditagainfromthememorytotheregistersifitwasnotmodified?Whowouldhavemodifiedthem?Let'sseethefollowingshortexample:

packagepackt.java9.by.example.thread;

publicclassVolatileDemonstrationimplementsRunnable{

privateObjecto=null;

privatestaticfinalObjectNON_NULL=newObject();

@Override

publicvoidrun(){

while(o==null);

System.out.println("oisnotnull");

}

publicstaticvoidmain(String[]args)

throwsInterruptedException{

VolatileDemonstrationme=newVolatileDemonstration();

newThread(me).start();

Thread.sleep(1000);

me.o=NON_NULL;

}

}

Whatwillhappen?Youmayexpectthatthecodestartsup,startsthenewthread,andoneminute,whenthemainthreadsetstheobjecttosomethingnotnull,willitstop?Itwillnot.

ItmaystoponsomeJavaimplementations,butinmostofthem,itwilljustkeepspinning.ThereasonforthatisthattheJITcompileroptimizesthecode.Itseesthattheloopdoesnothingandalsothatthevariablewilljustneverbenon-null.Itisallowedtoassumethatbecausethevariablesnotdeclaredvolatilearenotsupposedtobemodifiedbyanyotherthread,theJITiseligibletooptimize.IfwedeclaretheObjectovariabletobevolatile(withthevolatilekeyword),thenthecodewillstop.

Incaseyoutrytoremovethecalltosleep,thecodewillalsostop.This,however,doesnotfixtheissue.ThereasonisthatJIToptimizationkicksinonlyafterabout5000loopsofthecodeexecution.Beforethat,thecoderunsnaiveandstopsbeforetheoptimizationwilleliminatetheextraandregularlynotneededaccesstothenon-volatilevariable.

Ifthisissogruesome,thenwhydon'twedeclareallvariablestobevolatile?WhydoesJavanotdothatforus?Theanswerisspeed,andtounderstanditdeeper,wewilluseourmetaphor,theoffice,andthebureaucrat.

Page 417:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 418:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheCPUheartbeatThesedaysCPUsrunon2to4GHzfrequencyprocessors.Itmeansthataprocessorgets2to4times109clocksignalstodosomethingeverysecond.Aprocessorcannotdoanyatomicoperationfasterthanthis,andalsothereisnoreasontocreateaclockthatisfasterthanwhataprocessorcanfollow.ItmeansthataCPUperformsasimpleoperation,suchasincrementingaregisterinhalforquarterofananosecond.Thisistheheartbeatoftheprocessor,andifwethinkofthebureaucratashumans,whotheyare,thenitisequivalenttoonesecond,approximately,ifandastheirheartbeat.

Processorshaveregistersandcachesonthechipondifferentlevels,L1,L2,andsometimesL3;thereismemory,SSD,disk,network,andtapesthatmaybeneededtoretrievedata.

AccessingdatathatisintheL1cacheisapproximately0.5ns.Youcangrabapaperthatisonyourdesk—halfofasecond.L2cacheis7ns.Thisisapaperinthedrawer.Youhavetopushthechairabitback,benditinasittingposition,pulloutthedrawer,takethepaper,pushthedrawerback,andraiseandputthepaperonthedesk;ittakes10seconds,giveortake.

Mainmemoryreadis100ns.Thebureaucratstandsup,goestothesharedfileatthewall,hewaitswhileotherbureaucratsarepullingtheirpapersorputtingtheirsback,selectsthedrawer,pullsitout,takesthepaper,andwalksbacktothedesk.Thisistwominutes.Thisisvolatilevariableaccesseverytimeyouwriteasinglewordonadocumentandithastobedonetwice.Oncetoread,andoncetowrite,evenifyouhappentoknowthatthenextthingyouwilldoisjustfillanotherfieldoftheformonthesamepaper.

Modernarchitectures,wheretherearenomultipleCPUsbutrathersingleCPUswithmultiplecores,areabitfaster.Onecoremaychecktheothercore'scachestoseeiftherewasanymodificationonthesamevariable,butthisspeedsthevolatileaccessto20nsorso,whichisstillamagnitudeslowerthannonvolatile.

Althoughtherestislessfocusedonmultithreadprogramming,itisworthmentioninghere,becauseitgivesgoodunderstandingonthedifferenttimemagnitudes.

ReadingablockfromanSSD(4Kblockusually)is150,000ns.Inhumanspeed,thatisalittlebitmorethan5days.ReadingorsendingsomethingtoaserveroverthenetworkontheGblocalEthernetis0.5ms,whichislikewaitingforalmostamonthforthemetaphoricbureaucrat.Ifthedataoverthenetworkisonaspinningmagneticdisk,thenseektimeaddsup(thetimeuntilthediskrotatessothatthepartofthemagneticsurfacegetsunderthereadinghead)to20ms.Itis,approximately,ayearinhumanterms.

IfwesendanetworkpacketovertheAtlanticontheInternet,itisapproximatelyis150ms.Itislike14years,andthiswasonlyonesinglepackage;ifwewanttosenddataovertheocean,itmaybesecondsthatcountuptohistorictimes,thousandsofyears.Ifwecountoneminuteforamachinetoboot,itisequivalenttothetimespanofourwholecivilization.

WeshouldconsiderthesenumberswhenwewanttounderstandwhattheCPUisdoingmostofthetime:itwaits.Additionally,italsohelpscoolyournerveswhenyouthinkaboutthespeedofareal-lifebureaucrat.Theyarenotthatslowafterall,ifweconsidertheirheartbeat,whichimpliestheassumption

Page 419:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

thattheyhaveaheart.However,let'sgobacktoreallife,CPUs,andL1,L2cachesandvolatilevariables.

Page 420:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 421:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

VolatilevariablesLet'smodifythedeclarationoftheovariableinoursamplecodeasfollows:

privatevolatileObjecto=null;

Theprecedingcoderunsfineandstopsafterasecondorso.AnyJavaimplementationhastoguaranteethatmultiplethreadscanaccessvolatilefieldsandthevalueofthefieldisconsistentlyupdated.Thisdoesnotmeanthatvolatiledeclarationwillsolveallsynchronizationissues,butguaranteesthatthedifferentvariablesandtheirvaluechangerelationsareconsistent.Forexample,let'sconsiderwehavethefollowingtwofieldsincrementedinamethod:

privatevolatileinti=0,j=0;

publicvoidmethod(){

i++;j++;

}

Intheprecedingcode,readingiandjfromanotherthreadwillneverresultani>j.Withoutthevolatiledeclaration,thecompilerisfreetoreorganizetheexecutionoftheincrementoperationsifitneedsandthus,itwillnotguaranteethatanasynchronousthreadreadsconsistentvalues.

Page 422:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 423:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SynchronizedblockDeclaringvariablesarenottheonlytooltoensuretheconsistencybetweenthreads.ThereareothertoolsintheJavalanguageandoneofthemisthesynchronizedblock.Thesynchronizedkeywordispartofthelanguageanditcanbeusedinfrontofamethodoraprogramblockinsideamethod.

EveryobjectintheJavaprogramhasamonitorthatcanbelockedandunlockedbyanyrunningthread.Whenathreadlocksamonitor,itissaidthatthatthreadholdsthelock,andnotwothreadscanholdthelockofamonitoratatime.Ifathreadtriestolockamonitorthatisalreadylocked,itgetsBLOCKEDuntilthemonitorisreleased.Asynchronizedblockstartswiththesynchronizedkeyword,andthenanobjectinstancespecifiedbetweenparenthesesandtheblockcomes.Thefollowingsmallprogramdemonstratesthesynchronizedblock:

publicclassSynchronizedDemoimplementsRunnable{

publicstaticfinalintN=1000;

publicstaticfinalintMAX_TRY=1_000_000;

privatefinalcharthreadChar;

privatefinalStringBuffersb;

publicSynchronizedDemo(charthreadChar,StringBuffersb){

this.threadChar=threadChar;

this.sb=sb;

}

@Override

publicvoidrun(){

for(inti=0;i<N;i++){

synchronized(sb){

sb.append(threadChar);

sleep();

sb.append(threadChar);

}

}

}

privatevoidsleep(){

try{

Thread.sleep(1);

}catch(InterruptedExceptionignored){}

}

publicstaticvoidmain(String[]args){

booleanfailed=false;

inttries=0;

while(!failed&&tries<MAX_TRY){

tries++;

StringBuffersb=newStringBuffer(4*N);

newThread(newSynchronizedDemo('a',sb)).start();

newThread(newSynchronizedDemo('b',sb)).start();

failed=sb.indexOf("aba")!=-1||

sb.indexOf("bab")!=-1;

}

System.out.println(failed?

"failedafter"+tries+"tries":"notfailed");

}

}

Thecodestartstwodifferentthreads.OneofthethreadsappendsaatotheStringBuffer.Theotheroneappendsbb.Thisappendingisdoneintwoseparatestepswithasleepinbetween.ThesleepisneededtoavoidJITthatoptimizesthetwoseparatestepsintoone.Eachthreadexecutestheappend1000timeseachtimeappendingaorbtwotimes.AsthetwoappendsoneaftertheotherareinsideasynchronizedblockitcannothappenthatanabaorbabsequencegetsintotheStringBuffer.Whileonethreadexecutesthesynchronizedblock,theotherthreadcannotexecuteit.

Page 424:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IfIremovethesynchronizedblock,thentheJVMIusedtotestJavaHotSpot(TM)64-BitServerVM(build9-ea+121,mixedmode)printsoutthefailurewithatry-countaroundafewhundreds.

Itclearlydemonstrateswhatthesynchronizationmeans,butitdrawsourattentiontoanotherimportantphenomena.Theerroroccursonlyaroundeveryfewhundredthousandexecutionsonly.Itisextremelyrare,eventhoughthisexamplewasfurnishedtodemonstratesuchamishap.Ifabugappearssorare,itisextremelyhardtoreproduceand,evenmore,todebugandfix.Mostofthesynchronizationerrorsmanifestinmysteriouswaysandtheirfixingusuallyistheresultofmeticulouscodereviewratherthandebugging.Therefore,itisextremelyimportanttoclearlyunderstandthetruenatureofJavamultithreadbehaviorbeforestartingcommercialmultithreadapplication.

Thesynchronizedkeywordcanalsobeusedinfrontofamethod.Inthiscase,theobjecttoacquirethelockofistheobject.Incaseofastaticmethod,thesynchronizationisdoneonthewholeclass.

Page 425:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 426:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WaitandnotifyTherearefivemethodsimplementedintheclassObjectthatcanbeusedtogetfurthersynchronizationfunctionality:waitwiththreedifferenttimeoutargumentsignature,notify,andnotifyAll.Tocallwait,thecallingthreadshouldhavethelockoftheObjectonwhichwaitisinvoked.Itmeansthatyoucanonlyinvokewaitfrominsideasynchronizedblock,andwhenitiscalled,thethreadgetsBLOCKEDandreleasesthelock.WhenanotherthreadcallsnotifyallonthesameObject,thethreadgetsintotheRUNNABLEstate.Itcannotcontinueexecutionimmediatelyasitcannotgetthelockontheobject.ThelockisheldatthatmomentbythethreadthatjustcallednotifyAll.However,sometimeaftertheotherthreadreleases,thelockgetsoutofthesynchronizedblock,andthewaitingthreadcontinuestheexecution.

Iftherearemorethreadswaitingonanobject,allofthemgetoutoftheBLOCKEDstate.Thenotifymethodwakesonlyoneofthewaitingthreads.Thereisnoguaranteewhichthreadisawakened.

Thetypicaluseofwait,notify,andnotifyAlliswhenoneormorethreadsarecreatingObjectsthatareconsumedbyotherthread,orthreads.Thestoragewheretheobjectstravelbetweenthethreadsissomekindofqueue.Theconsumerwaitsuntilthereissomethingtoreadfromthequeue,andtheproducerputstheobjectsintothequeueoneaftertheother.Theproducernotifiestheconsumerswhenitstoressomethingintothequeue.Ifthereisnoroomleftinthequeue,theproducerhastostopandwaituntilthequeuehassomespace.Inthiscase,theproducercallsthewaitmethod.Towaketheproducerup,theconsumercallsnotifyAllwhenitreadssomething.

Theconsumerconsumestheobjectsfromthequeueinaloopandcallswaitonlyifthereisnothingtobereadfromthequeue.WhentheproducercallsnotifyAll,andthereisnoconsumerwaiting,thenotificationisjustignored.Itfliesaway,butthisisnotaproblem;consumersarenotwaiting.WhentheconsumerconsumesanobjectandcallsnotifyAllandthereisnoproducerwaiting,thesituationisthesame.Itisnotaproblem.

Itcannothappenthattheconsumerconsumes,callsnotifyAll,andafterthenotificationwasflyingintheairnotfindinganywaitingproducer,aproducerstartstowait.Thiscannothappenbecausethewholecodeisinasynchronizedblockanditensuresthatnoproducerisinthecriticalsection.Thisisthereasonwhywait,notify,andnotifyAllcanonlybeinvokedwhenthelockoftheObjectclassisacquired.

Iftherearemanyconsumers,whichareexecutingthesamecodeandareequivalentlygoodinconsumingtheobjects,thenitisanoptimizationtocallnotifyinsteadofnotifyAll.Inthatcase,notifyAllwilljustawakeallconsumerthreadsandall,buttheluckyonewillrecognizethattheywerewokenupbutsomebodyelsealreadygotawaywiththebait.

IrecommendthatyoupracticeatleastoncetoimplementablockingqueuethatcanbeusedtopassObjectsbetweenthreads.However,neverusethatcodeinproduction:startingwithJava1.5,thereareimplementationsoftheBlockingQueueinterface.Useonethatfitsyourneeds.Wewilltoo,inourexamplecode.

FeelluckythatyoucancodeinJava9.IstartedusingJavaprofessionallywhenitwas1.4andonceIhadtoimplementablockingqueue.Lifegetsjustbetterandeasierallthe

Page 427:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

timewithJava.

Inprofessionalcode,weusuallyavoidusingsynchronizedmethodsorblocksandvolatilefieldsaswellasthewaitandnotifymethods,notifyAlltoo,ifpossible.Wecanuseasynchronouscommunicationbetweenthreads,orpassthewholemultithreadingtotheframeworkforhandling.Synchronizedandvolatilecannotbeavoidedinsomespecialcaseswhentheperformanceofthecodeisimportant,orwecannotfindabetterconstruct.Sometimes,thedirectsynchronizationonspecificcodeanddatastructuresismoreefficientthantheapproachdeliveredbyJDKclasses.Itistonote,however,thatthoseclassesalsousetheselow-levelsynchronizationconstructs,soitisnotmagichowtheywork;andtodevelopyourself,youcanlookintothecodeoftheJDKclassesbeforeyouwanttoimplementyourownversion.Youwillrealizethatitisnotthatsimpletoimplementthesequeues;thecodeoftheclassesisnotcomplexandcompoundwithoutreason.Ifyoufindthecodesimple,itmeansthatyouareseniorenoughtoknowwhatnottoreimplement.Or,perhaps,youdonotevenrealizewhatcodeyouread.

Page 428:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 429:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LockLocksarebuiltinJava;everyObjecthasalockthatathreadmayacquirewhenitentersasynchronizedblock.Wediscussedthatalready.Insomeprogrammingcode,therearesituationswhenthiskindofstructureisnotoptimal.

Insomesituations,thestructureoflocksmaybelineduptoavoiddeadlock.ItmaybeneededtoacquirelockAbeforeBandtoacquireBbeforeC.However,Ashouldbereleasedassoonaspossible,nottopreventaccesstoresourceprotectedbylockD,butalsoneedinglockAbeforeit.Incomplexandhighlyparallelstructures,thelocksarestructuredmanytimesintotreeswhereaccessingaresourceathreadshouldclimbdownalongthetreetoaleafrepresentingtheresource.Inthisclimbing,thethreadgetsholdofalockonanode,thenalockonanodebelowit,andthenreleasesthelockabove,justlikearealclimberdescending(orclimbingupifyouimaginethetreewiththeleafsatthetop,whichismorerealistic,neverthelessgraphsusuallyshowtreesupsidedown).

Youcannotleaveasynchronizedblockremaininginanotherthatisinsidethefirstone.Synchronizedblocksarenested.Thejava.util.concurrent.LockinterfacedefinesmethodstohandlethatsituationandtheimplementationsarealsothereintheJDKtobeusedinourcode.Whenyouhavealock,youcancallthemethodslockandunlock.Theactualorderisinyourhandandyoucanwritethefollowinglineofcodetogetthelockingsequence:

a.lock();b.lock();a.unlock();c.lock()

Thefreedom,however,comeswithresponsibilityaswell.Thelocksandunlocksarenottiedtotheexecutionsequenceofthecode,likeincaseofsynchronizedblock,anditmaybeveryeasytocreatecodethatinsomecasejustlosesalocknotunlockingitrenderingsomeresourceunusable.Thesituationissimilartoamemoryleak:youwillallocate(lock)somethingandforgettorelease(unlock)it.Afterawhile,theprogramwillrunoutofresource.

Mypersonalrecommendationistoavoidusinglocksifpossibleandusehigher-levelconstructsandasynchronouscommunicationsbetweenthreads,suchasblockingqueues.

Page 430:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 431:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Condition

Thejava.util.concurrent.Conditioninterfaceinfunctionalityissimilartothebuilt-inwait,notify,andnotifyAll.AnyimplementationofLockshouldcreatenewConditionobjectsandreturnasaresulttotheinvocationofthenewConditionmethod.WhenthethreadhasaCondition,itcancallawait,signal,andsignalAllwhenthethreadhasthelockthatcreatedtheconditionobject.

ThefunctionalityisverysimilartothemethodsofObjectmentioned.However,thebigdifferenceisthatyoucancreatemanyConditionforasingleLockandtheywillworkindependentofeachother,butnotindependentoftheLock.

Page 432:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 433:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReentrantLock

ReentrantLockisthesimplestimplementationoftheinterfacelockintheJDK.Therearetwowaystocreatethistypeoflock:withandwithoutfairnesspolicy.IftheReentrantLock(Booleanfair)constructoriscalledwiththetrueargument,thenthelockwillbeassignedtothethreadthatiswaitingforthelockthelongesttimeincasetherearemanythreadswaiting.Thiswillavoidathreadmadetowaitforinfinitetimeandstarving.

Page 434:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 435:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReentrantReadWriteLockThisclassisanimplementationofReadWriteLock.ReadWriteLockisalockthatcanbeusedforparallelreadaccessandexclusivewriteaccess.Itmeansthatseveralthreadscanreadtheresourceprotectedbythelock,butwhenathreadwritestheresource,nootherthreadcangetaccesstoit,notevenreadduringthatperiod.AReadWriteLockissimplytwoLockobjectsreturnedbythereadLockandwriteLockmethods.TogetreadaccessonReadWriteLock,thecodehastoinvokemyLock.readLock().lock(),andtogetaccesstowritelock,myLock.writeLock().lock().Acquiringoneofthelocksandreleasingitintheimplementationiscoupledwiththeotherlock.Toacquireawritelock,nothreadshouldhaveanactivereadlock,forexample.

Thereareseveralintricaciesintheuseofthedifferentlock.Forexample,youcanacquireareadlock,butyoucannotgetawritelocksolongasyouhavethereadlock.Youhavetoreleasethereadlockfirsttoacquireawritelock.Thisisjustoneofthesimpledetails,butthisistheonethatnoviceprogrammershavetroublewithmanytimes.Whyisitimplementedthisway?Whyshouldtheprogramgetawritelock,whichismoreexpensive—insenseofhigherprobabilitylockingotherthreads—whenitstillisnotsurethatitwantstowritetheresource?Thecodewantstoreaditand.basedonthecontent.itmaylaterdecidethatitwantstowriteit.

Theissueisnotwiththeimplementation.Thedevelopersofthelibrarydecidedthisrule,notbecausetheyjustlikeditthatwayorbecausetheywereawareofparallelalgorithmsanddeadlockpossibilities.Whentwothreadshavereadlockandeachdecidestoupgradethelocktowritelock,thentheywouldintrinsicallycreateadeadlock.Eachwouldholdthereadlockwaitingforthewriteandnoneofthemwouldgetitever.

Ontheotherend,youcandowngradeawritelocktoareadlockwithoutriskingthatinthemeantimesomebodyacquiresawritelockandmodifiestheresource.

Page 436:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 437:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AtomicclassesAtomicclassesencloseprimitivevaluesintoobjectsandprovideatomicoperationsonthem.Wediscussedraceconditionsandvolatilevariables.Forexample,ifwehaveanintvariabletobeusedasacounterandwewanttoassignauniquevaluetoobjectsthatweworkwith,wecanincrementthevalueandusetheresultasauniqueID.However,whenmultiplethreadsusethesamecode,wecannotbesureaboutthevaluewereadaftertheincrement.Itmayhappenthatanotherthreadalsoincrementedthevalueinthemeantime.Toavoidthat,wewillhavetoenclosetheincrementandtheassignmentoftheincrementedvaluetoanobjectintoasynchronizedblock.ThiscanalsobedoneusingAtomicInteger.

IfwehaveavariableofAtomicInteger,thencallingincrementAndGetincrementsthevalueofintenclosedintheclassandreturnstheincrementedvalue.Whydoitinsteadofusingsynchronizedblock?ThefirstansweristhatifthefunctionalityisthereintheJDK,thenusingitislesslinethanimplementingitagain.DevelopersmaintainingthecodeyoucreateareexpectedtoknowtheJDKlibrariesbuthavetostudyyourcode,andthistakestimeandtimeismoney.

Theotherreasonisthattheseclassesarehighlyoptimizedand,manytimes,theyimplementthefeaturesusingplatformspecificnativecodethatgreatlyoverperformstheversionwecanimplementusingsynchronizedblocks.Worryingaboutperformancetooearlyisnotgood,butparallelalgorithmsandsynchronizationbetweenthreadsareusuallyusedwhenperformanceiscrucial;thus,thereisagoodchancethattheperformanceofthecodeusingtheatomicclassesisimportant.

Inthejava.util.concurrent.atomicpackage,thereareseveralclasses,AtomicInteger,AtomicBoolean,AtomicLong,andAtomicReferenceamongthem.Theyallprovidemethodsthatarespecifictotheencapsulatedvalue.

Themethod,whichisimplementedbyeveryatomicclass,iscompareAndSet.Thisisaconditionalvalue-settingoperationthathasthefollowingformat:

booleancompareAndSet(expectedValue,updateValue);

Whenitisappliedonanatomicclass,itcomparestheactualvaluewiththeoneexpectedValue,andiftheyarethesame,thenitsetsthevaluetoupdateValue.Ifthevaluewasupdated,themethodreturnstrueanditdoesallthisinanatomicaction.

Youmayaskthequestionthatifthismethodisinalloftheseclasses,whyistherenoInterfacedefiningthismethod?Thereasonforthisisthattheargumenttypesaredifferentbasedontheencapsulatedtype,andthesetypesareprimitives.Asprimitivescannotbeusedasgenerictypes,notevenagenericinterfacecanbedefined.IncaseofAtomicXXXArray,themethodhasanextrafirstargument,whichistheindexofthearrayelementhandledinthecall.

Thevariablesencapsulatedarehandledthesamewayasvolatile,asfarasthereorderingisconcerned,buttherearespecialmethodsthatloosentheconditionsabittobeusedwhenpossible,andperformanceiskey.

Thegeneraladviceistoconsiderusingatomicclasses,ifthereisoneusable,andyouwillfindyourself

Page 438:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

creatingasynchronizedblockforcheck-and-set,atomicincrement,oradditionoperations.

Page 439:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 440:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

BlockingQueue

BlockingQueueisaninterfacethatextendsthestandardQueueinterfacewithmethodsthataresuitabletobeusedbymultithreadapplications.Anyimplementationofthisinterfaceprovidesmethodsthatallowdifferentthreadstoputelementintothequeue,pullelementsoffthequeue,andwaitforelementsthatareinthequeue.

Whenthereisanewelementthatistobestoredinthequeue,youcanaddit,offerit,orputit.Thesearethenameofthemethodsthatstoreelementsandtheydothesamething,butabitdifferently.Theaddelementthrowsanexceptionifthequeueisfullandthereisnoroomfortheelement.Theofferelementdoesnotthrowexceptionbutreturnseithertrueorfalse,basedonthesuccess.Ifitcanstoretheelementinthequeue,itreturnstrue.Thereisalsoaversionofofferthatspecifiesatimeout.Thatversionofthemethodwaits,andreturnsonlyfalseifitcannotstorethevalueintothequeueduringtheperiod.Theputelementisthedumbestversion;itwaitsuntilitcandoitsjob.

Whentalkingaboutavailableroominaqueue,donotgetpuzzledandmixitwithgeneralJavamemorymanagement.Ifthereisnomorememory,andthegarbagecollectorcanalsonotreleaseany,youwillcertainlygetOutOfMemoryError.Exceptionisthrownbyadd,andfalseisreturnedbyoffer,whenthequeuelimitsarereached.SomeoftheBlockingQueueimplementationscanlimitthenumberofelementsthatcanbestoredatatimeinaqueue.Ifthatlimitisreached,thenthequeueisfullandcannotacceptmoreelements.

FetchingelementsfromaBlockingQueueimplementationalsohasfourdifferentways.Inthisdirection,thespecialcaseiswhenthequeueisempty.Inthatcase,removethrowsanexceptioninsteadofreturningtheelement,pollreturnsnullifthereisnoelement,andtakejustwaitsuntilitcanreturnanelement.

Finally,therearetwomethodsinheritedfromtheinterfaceQueuesthatdonotconsumetheelementfromthequeueonlylookat.Theelementreturntheheadofthequeueandthrowsanexceptionifthequeueisempty,andpeekreturnsnullifthereisnoelementinthequeue.Thefollowingtablesummarizestheoperationsborrowedfromthedocumentationoftheinterface:

Throwsexception Specialvalue Blocks Timesout

Insert add(e) offer(e) put(e) offer(e,time,unit)

Remove remove() poll() take() poll(time,unit)

Examine element() peek() notapplicable notapplicable

Page 441:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 442:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LinkedBlockingQueue

ThisisanimplementationoftheBlockingQueueinterface,whichisbackedupbyalinkedlist.Thesizeofthequeueisnotlimitedbydefault(tobeprecise,itisInteger.MAX_VALUE)butitcanoptionallybelimitedinaconstructorargument.Thereasontolimitthesizeinthisimplementationistoaidtheusewhentheparallelalgorithmperformsbetterwithlimitedsizequeue,buttheimplementationdoesnothaveanyrestrictiononthesize.

Page 443:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 444:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LinkedBlockingDeque

ThisisthesimplestimplementationoftheBlockingQueueandalsoitssubinterfaceBlockingDeque.Aswediscussedinthepreviouschapter,aDequeisadouble-endedqueuethathasadd,remove,offer,andsoon,typeofmethodsintheformofxxxFirstandxxxLasttodotheactwithoneortheotherendofthequeue.TheDequeinterfacedefinesgetFirstandgetLastinsteadofconsistentlynamingelementFirstandelementLast,sothisissomethingyoushouldgetusedto.Afterall,theIDEshelpwithautomaticcodecompletionsothisshouldnotbeareallybigproblem.

Page 445:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 446:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ArrayBlockingQueue

ArrayBlockingQueueimplementstheBlockingQueueinterface,hencetheQueueinterface.Thisimplementationmanagesaqueuewithfixedsizeelements.ThestorageintheimplementationisanarrayandtheelementsarehandledinaFIFOmanner:first-infirst-out.ThisistheclassthatwewillalsouseintheparallelimplementationofMastermindforthecommunicationbetweenthebossandthesubordinatedbureaucrats.

Page 447:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 448:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LinkedTransferQueue

TheTransferQueueinterfaceisextendingBlockingQueueandtheonlyimplementationofitintheJDKisLinkedTransferQueue.ATransferQueuecomeshandywhenathreadwantstohandoversomedatatoanotherthreadandneedstobesurethatsomeotherthreadtakestheelement.ThisTransferQueuehasamethodtransferthatputsanelementonthequeuebutdoesnotreturnuntilsomeotherthreadremoves(orpolls)it.Thatwaytheproducingthreadcanbesurethattheobjectputonthequeueisinthehandsofanotherprocessingthreadanddoesnotwaitinthequeue.ThemethodtransferalsohasaformattryTransferinwhichyoucanspecifysometimeoutvalue.Ifthemethodtimesouttheelementisnotputintothequeue.

Page 449:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 450:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IntervalGuesserWediscussedthedifferentJavalanguageelementsandJDKclassesthatareallavailabletoimplementparallelalgorithms.Now,wewillseehowtousetheseapproachestoimplementtheparallelguesserfortheMasterrmindgame.

TheclassthatperformsthecreationoftheguessesisnamedIntervalGuesser.ItcreatestheguessesbetweenastartandanendguessandsendsthemtoaBlockingQueue.TheclassimplementsRunnablesoitcanruninaseparateThread.ThepuristimplementationwillseparatetheRunnablefunctionalityfromtheintervalguessing,butasthewholeclassishardlymorethan50lines,itisforgivablesinimplementingthetwofunctionalitiesinasingleclass.

publicclassIntervalGuesserextendsUniqueGuesserimplementsRunnable{

privatefinalGuessstart;

privatefinalGuessend;

privateGuesslastGuess;

privatefinalBlockingQueue<Guess>guessQueue;

publicIntervalGuesser(Tabletable,Guessstart,Guessend,BlockingQueue<Guess>guessQueue){

super(table);

this.start=start;this.end=end;

this.lastGuess=start;

this.guessQueue=guessQueue;

nextGuess=start;

}

@Override

publicvoidrun(){

Guessguess=guess();

try{

while(guess!=Guess.none){

guessQueue.put(guess);

guess=guess();

}

}catch(InterruptedExceptionignored){

}

}

@Override

protectedGuessnextGuess(){

Guessguess;

guess=super.nextGuess();

if(guess.equals(end)){

guess=Guess.none;

}

lastGuess=guess;

returnguess;

}

publicStringtoString(){

return"["+start+","+end+"]";

}

}

TheimplementationisverysimpleasmostofthefunctionalityisalreadyimplementedintheabstractGuesserclass.ThemoreinterestingcodeistheonethatinvokedtheIntervalGuesser.

Page 451:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 452:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ParallelGamePlayerTheParallelGamePlayerclassimplementsthePlayerinterfacethatdefinestheplaymethod:

@Override

publicvoidplay(){

Tabletable=newTable(NR_COLUMNS,manager);

Secretsecret=newRandomSecret(manager);

GuesssecretGuess=secret.createSecret(NR_COLUMNS);

Gamegame=newGame(table,secretGuess);

finalIntervalGuesser[]guessers=createGuessers(table);

startAsynchronousGuessers(guessers);

finalGuesserfinalCheckGuesser=newUniqueGuesser(table);

try{

while(!game.isFinished()){

finalGuessguess=guessQueue.take();

if(finalCheckGuesser.guessMatch(guess)){

game.addNewGuess(guess);

}

}

}catch(InterruptedExceptionie){

}finally{

stopAsynchronousGuessers(guessers);

}

}

ThismethodcreatesaTable,aRandomSecretthatcreatestheguessusedasasecretinarandomway,aGameobject,IntervalGuessers,andaUniqueGuesser.TheIntervalGuessersarethebureaucrats;theUniqueGuesseristhebosswhocrosscheckstheguessesthattheIntervalGuesserscreate.ThemethodstartsofftheasynchronousguessersandthenreadstheguessesinaloopfromthemandputsthemonthetableiftheyareOKuntilthegamefinishes.Attheendofthemethod,inthefinallyblock,theasynchronousguessersarestopped.

ThestartandthestopmethodfortheasynchronousguessersuseExecutorService.

privateExecutorServiceexecutorService;

privatevoidstartAsynchronousGuessers(

IntervalGuesser[]guessers){

executorService=Executors.newFixedThreadPool(nrThreads);

for(IntervalGuesserguesser:guessers){

executorService.execute(guesser);

}

}

privatevoidstopAsynchronousGuessers(

IntervalGuesser[]guessers){

executorService.shutdown();

guessQueue.drainTo(newLinkedList<>());

}

Thecodeisquitestraightforward.Theonlythingthatmayneedmentionisthatthequeueoftheguessesisdrainedintoacollectionthatwedonotuseafterward.ThisisneededtohelpanyIntervalGuesserthatiswaitingwithasuggestedguessinhand,tryingtoputitintothequeue.Whenwedrainthequeue,theguesserthreadreturnsfromthemethodputintheguessQueue.put(guess);lineinIntervalGuesserandcancatchtheinterrupt.TherestofthecodedoesnotcontainanythingthatwouldberadicallydifferentfromwhatwehavealreadyseenandyoucanfinditonGitHub.

Thelastquestionthatwestillwanttodiscussinthischapterishowmuchspeeddidwegainmakingthecodeparallel?

Page 453:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 454:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MicrobenchmarkingMicrobenchmarkingismeasuringtheperformanceofasmallcodefragment.Whenwewanttooptimizeourcode,wewillhavetomeasureit.Withoutmeasurement,codeoptimizationislikeshootingblindfolded.Youwillnothitthetarget,butyoulikelywillshootsomebodyelse.

Shootingisagoodmetaphorbecauseyoushouldusuallynotdoit,butwhenyoureallyhavetothenyouhavenochoice.Ifthereisnoperformanceissueandthesoftwaremeetstherequirements,thenanyoptimization,includingspeedmeasurement,isawasteofmoney.Thisdoesnotmeanthatyouareencouragedtowriteslowandsloppycode.Whenwemeasureperformance,wewillcompareitagainstarequirement,andtherequirementisusuallyontheuserlevel.Somethinglike,theresponsetimeoftheapplicationshouldbelessthan2seconds.Todosuchameasurement,weusuallycreateloadtestsinatestenvironmentandusedifferentprofilingtoolsthattelluswhatisconsumingthemosttimeandwhereweshouldoptimize.Manytimes,itisnotonlyJavacode,butconfigurationoptimization,usinglargerdatabaseconnectionpool,morememory,andsimilarthings.

Microbenchmarkingisadifferentstory.ItisabouttheperformanceofasmallJavacodefragmentand,assuch,closertotheJavaprogramming.

Itisrarelyused,andbeforestartingtodoamicrobenchmarkforrealcommercialenvironment,wewillhavetothinktwice.Microbenchmarkisaluringtooltooptimizesomethingsmallwithoutknowingifitisworthoptimizingthatcode.Whenwehaveahugeapplicationthathasseveralmodulesrunonseveralservers,howcanwebesurethatimprovingsomespecialpartoftheapplicationdrasticallyimprovestheperformance?Willitpaybackinincreasedrevenuethatgeneratessomuchprofitthatwillcoverthecostweburnedintotheperformancetestinganddevelopment?Statistically,almostsurethatsuchanoptimizationincludingmicrobenchmarkingwillnotpayoff.

OnceIwasmaintainingthecodeofasenior'scolleague.Hecreatedahighlyoptimizedcodetorecognizeconfigurationkeywordsthatwerepresentinafile.Hecreatedaprogramstructurethatrepresentedadecisiontreebasedonthecharactersinthekeystring.Iftherewasakeywordintheconfigurationfilethatwasmisspelled,thecodethrewanexceptionattheveryfirstcharacterwhereitcoulddecidethatthekeywordcouldnotbecorrect.Toinsertanewkeyword,itneededtogetthroughthecodestructuretofindtheoccasioninthecodewherethenewkeywordwasfirstdifferentfromalreadyexistingonesandextendthedeeplynestedif/elsestructures.Toreadthelistofthehandledkeywordswaspossiblefromthecommentsthatlistedallthekeywordsthathedidnotforgettodocument.Thecodewasworkingblazinglyfast,probablysavingafewmillisecondsoftheservletapplicationstartuptime.Theapplicationwasstarteduponlyaftersystemmaintenanceeveryfewmonth.Youfeeltheirony,don'tyou?Seniorityisnotalwaysthenumberofyears.Luckyonescansavetheirinnerchild.

Sowhentousemicrobenchmarking?Icanseetwoareas:

Page 455:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

YouidentifiedthecodesegmentthateatsmostoftheresourcesinyourapplicationandtheimprovementcanbetestedbymicrobenchmarksYoucannotidentifythecodesegmentthatwilleatmostoftheresourcesinanapplicationbutyoususpectit

Thefirstistheusualcase.Thesecondiswhenyoudevelopalibrary,andyoujustdonotknowalltheapplicationsthatwilluseit.Inthiscase,youwilltrytooptimizethepartthatyouthinkisthemostcrucialformostoftheimagined,suspectedapplications.Eveninthatcase,itisbettertotakesomesampleapplicationsthatarecreatedbyusersofyourlibraryandcollectsomestatisticsabouttheuse.

Whyshouldwetalkaboutmicrobenchmarkingindetails?Whatarethepitfalls?Benchmarkingisanexperiment.ThefirstprogramsIwrotewasaTIcalculatorcodeandIcanjustcountthenumberofstepstheprogrammadetofactortwolarge(10digitsthosedays)primenumbers.Evenatthattime,IwasusinganoldRussianstopwatchtomeasurethetime,beinglazytocalculatethenumberofsteps.Experimentandmeasurementwaseasier.

Today,youcannotcalculatethenumberofstepstheCPUmakesevenifyouwanted.Therearesomanysmallfactorsthatmaychangetheperformanceoftheapplicationsthatareoutofcontroloftheprogrammer,whichmakesitimpossibletocalculatethesteps.Wehavethemeasurementleftforus,andwewillgainalltheproblemsofmeasurements.

Whatisthebiggestproblem?Weareinterestedinsomething,sayX,andweusuallycannotmeasurethat.So,wewillmeasureYinsteadandhopethatthevaluesofYandXarecoupledtogether.Wewanttomeasurethelengthoftheroom,butinsteadwemeasurethetimeittakesforthelaserbeamtotravelfromoneendtotheother.Inthiscase,thelengthXandthetimeYarestronglycoupled.Manytimes,XandYonlycorrelatemoreorless.Mostofthetimes,whenpeopledomeasurement,theXandYvalueshavenorelationtoeachotheratall.Still,peopleputtheirmoneyandmoreondecisionsbackedbysuchmeasurements.

Microbenchmarkingisnodifferent.Thefirstquestionishowtomeasuretheexecutiontime?SmallcoderunsshorttimesandSystem.currentTimeMillis()mayjustreturnthesamevaluewhenthemeasurementstartsandwhenitends,becausewearestillinthesamemillisecond.Eveniftheexecutionis10ms,theerrorofthemeasurementisstillatleast10%purelybecauseofthequantizationofthetimeaswemeasure.Luckily,thereisSystem.nanoTime().Butisthere?Justbecausethenamesaysitreturnsthenumberofnanosecondsfromaspecificstarttime,itdoesnotnecessarilymeanitreallycan.

ItverymuchdependsonthehardwareandtheimplementationofthemethodintheJDK.Itiscallednanobecausethisistheprecisionthatwecannotcertainlyreach.Ifitwasmicroseconds,thensomeimplementationmaybelimitedbythedefinition,evenifonthespecifichardware,thereisamorepreciseclock.However,thisisnotonlytheprecisionofanavailablehardwareclock;itisabouttheprecisionofthehardware.

Let'sremembertheheartbeatofthebureaucrats,andthetimeneededtoreadsomethingfrommemory.Callingamethod,suchasSystem.nanoTime(),islikeaskingthebellboyinahoteltorundownfromthesecondfloortothelobbyandpeekouttolookattheclockonthetowerontheothersideoftheroad,comeback,andtellsecondsprecisionwhatthetimewasitwhenweasked.Nonsense.Weshouldknowthe

Page 456:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

precisionoftheclockonthetowerandthespeedofthebellboyrunningfromthefloortothelobbyandback.ThisisabitmorethanjustcallingnanoTime.Thisiswhatamicrobenchmarkingharnessdoesforus.

TheJavaMicrobenchmarkingHarness(JMH)isavailableforsometimeasalibrary.ItisdevelopedbyOracleandusedtotunetheperformanceofsomecoreJDKclasses,andwithJava9,theseperformancemeasurementsandresultsbecomepartofthedistributedJDK.ThisisgoodnewsforthosewhodevelopJavaplatformfornewhardware,butalsofordevelopers,becauseitmeansthattheJMHisandwillbesupportedbyOracle.

"JMHisaJavaharnesstobuild,run,andanalyzenano/micro/milli/macrobenchmarkswritteninJavaandotherlanguagestargetingtheJVM."(quotefromtheofficialsiteofJMH,http://openjdk.java.net/projects/code-tools/jmh/).

Youcanrunjmhasaseparateprojectindependentfromtheactualprojectyoumeasure,oryoucanjuststorethemeasurementcodeinaseparatedirectory.Theharnesswillcompileagainsttheproductionclassfilesandwillexecutethebenchmark.Theeasiestway,asIsee,istousetheGradleplugintoexecuteJMH.Youcanstorethebenchmarkcodeinadirectorycalledjmh(thesamelevelasmainandtest)andcreateamainthatcanstartthebenchmark.

TheGradlebuildscriptisextendedwiththefollowinglines:

buildscript{

repositories{

jcenter()

}

dependencies{

classpath"me.champeau.gradle:jmh-gradle-plugin:0.2.0"

}

}

applyplugin:"me.champeau.gradle.jmh"

jmh{

jmhVersion='1.13'

includeTests=true

}

Andthemicrobenchmarkclassisasfollows:

publicclassMicroBenchmark{

publicstaticvoidmain(String...args)

throwsIOException,RunnerException{

Optionsopt=newOptionsBuilder()

.include(MicroBenchmark.class.getSimpleName())

.forks(1)

.build();

newRunner(opt).run();

}

@State(Scope.Benchmark)

publicstaticclassThreadsAndQueueSizes{

@Param(value={"1","4","8"})

StringnrThreads;

@Param(value={"-1","1","10","100","1000000"})

StringqueueSize;

}

@Benchmark

@Fork(1)

publicvoidplayParallel(ThreadsAndQueueSizest3qs)throwsInterruptedException{

intnrThreads=Integer.valueOf(t3qs.nrThreads);

intqueueSize=Integer.valueOf(t3qs.queueSize);

newParallelGamePlayer(nrThreads,queueSize).play();

Page 457:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

}

@Benchmark

@Fork(1)

publicvoidplaySimple(){

newSimpleGamePlayer().play();

}

}

ParallelGamePlayeriscreatedtoplaythegamewith-1,1,4,and8IntervalGuesserthreads,andineachcase,thereisatestrunningwithaqueueoflength1,10,100,and1million.Theseare16testexecutions.Whenthenumberofthreadsisnegative,thentheconstructorusesLinkedBlockingDeque.Thereisanotherseparatemeasurementthatmeasuresthenonparallelplayer.Thetestwasexecutedwithuniqueguessesandsecrets(nocolorusedmorethanonce)andtencolorsandsixcolumns.

Whentheharnessstarts,itdoesallthecalibrationsautomaticallyandrunsthetestsformanyiterationstolettheJVMstartup.Youmayrecallthecodethatjustneverstoppedunlessweusedthevolatilemodifierinforthevariablethatwasusedtosignalthecodetostop.ThathappenedbecausetheJITcompileroptimizedthecode.Thisisdoneonlywhenthecodewasalreadyrunafewthousandtimes.TheharnessmakestheseexecutionstowarmupthecodeandensurethatthemeasurementisdonewhenJVMisatfullspeed.

Runningthisbenchmarktakesapproximately15minutesonmymachine.Duringtheexecution,itisrecommendedtostopallotherprocessesandletthebenchmarkuseallavailableresources.Ifthereisanythingusingresourcesduringthemeasurement,thenitwillbereflectedintheresult.

Benchmark(nrThreads)(queueSize)ScoreError

playParallel1-115,636&pm;1,905

playParallel1115,316&pm;1,237

playParallel11015,425&pm;1,673

playParallel110016,580&pm;1,133

playParallel1100000015,035&pm;1,148

playParallel4-125,945&pm;0,939

playParallel4125,559&pm;1,250

playParallel41025,034&pm;1,414

playParallel410024,971&pm;1,010

playParallel4100000020,584&pm;0,655

playParallel8-124,713&pm;0,687

playParallel8124,265&pm;1,022

playParallel81024,475&pm;1,137

playParallel810024,514&pm;0,836

playParallel8100000016,595&pm;0,739

playSimpleN/AN/A18,613&pm;2,040

Theactualoutputoftheprogramisabitmoreverbose;itwaseditedforprintingpurposes.TheScorecolumnshowshowmanytimesthebenchmarkcanruninasecond.TheErrorshowsthatthemeasurementshowslessthan10%scattering.

Thefastestperformancewehaveiswhenthealgorithmrunsoneightthreads,whichisthenumberofthreadstheprocessorcanindependentlyhandleonmymachine.Itisinterestingthatlimitingthesizeofthequeuedidnothelptheperformance.Iactuallyexpectedittobedifferent.Usingaonemillionlengtharrayasablockingqueuehasahugeoverheadandthisisnotasurprisethat,inthiscase,theexecutionisslowerthanwhenwehaveonly100elementsinthequeue.Theunlimitedlinkedlist-basedqueuehandling,ontheotherhand,fairlyfastandclearlyshowsthattheextraspeedatthelimitedqueuefor100elementsdoesnotcomefromthefactthatthelimitdoesnotallowtheIntervalThreadstoruntoofar.

Page 458:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Whenwestartonethread,thenweexpectsimilarresults,aswhenweruntheserialalgorithm.Thefactthattheserialalgorithmbeatstheparallelalgorithmrunningononethreadisnotasurprise.Thethreadcreationandthecommunicationbetweenthemainthreadandtheextraonethreadhaveoverhead.Theoverheadissignificant,especiallywhenthequeueisunnecessarilylarge.

Page 459:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 460:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SummaryInthischapter,youlearnedalotofthings.Firstofall,werefactoredthecodetobereadyforfurtherdevelopmentthatusesparallelguessing.Wegotacquaintedwithprocessesandthreads,andweevenmentionedfibers.Afterthat,welookedathowJavaimplementsthreadsandhowtocreatecodethatrunsonmultiplethreads.Additionally,wesawthedifferentmeansthatJavaprovidestoprogrammersneedingparallelprograms,startingthreads,orjuststartingsometasksinalreadyexistingthreads.

Perhapsthemostimportantpartofthischapterthatyoushouldrememberisthemetaphorofbureaucratsandthedifferentspeeds.Thisisextremelyimportantwhenyouwanttounderstandtheperformanceofconcurrentapplications.AndIhopethatthisisacatchypicture,whichiseasytoremember.

TherewasahugetopicaboutthedifferentsynchronizationmeansthatJavaprovides,andyouhavealsolearnedaboutthepitfallsthatprogrammerscanfallintowhenprogrammingconcurrentapplications.

Lastbutnotleast,wecreatedtheconcurrentversionoftheMastermindguesserandalsomeasuredthatitisindeedfasterthantheversionthatusesonlyoneprocessor(atleastonmymachine).WeusedtheJavaMicrobenchmarkHarnesswiththeGradlebuildtoolanddiscussed,abit,howtoperformmicrobenchmarking.

Thiswasalongchapterandnotaneasyone.Imaytendtothinkthatthisisthemostcomplexandmosttheoreticalone.Ifyouunderstoodhalfofitatfirstread,youcanbeproud.Ontheotherhand,beawarethatthisisonlyagoodbasetostartexperimentingwithconcurrentprogrammingandthereisalongwaytobeingseniorandprofessionalinthisarea.And,itisnotaneasyone.Butfirstofall,beproudofyourselfattheendofthischapter.

Inthefollowingchapterswewilllearnmoreaboutwebandwebprogramming.Intheverynextchapterwewilldevelopourlittlegamesothatitcanruninaserverandtheplayercanplaywithitusingawebbrowser.Thiswillestablishthebasicknowledgeforwebprogramming.Laterwewillbuildonthisdevelopingwebbasedserviceapplications,reactiveprogrammingandallthetoolsandareasthatwillmakeaprofessionalJavadeveloper.

Page 461:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 462:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MakingOurGameProfessional-DoitasaWebappInthischapter,wewillprogramawebapplication.WewillbuildonwhatwehaveachievedalreadyandcreateawebversionoftheMastermindgame.Thistime,itwillnotonlyrunalone,guessingandansweringthenumberofpositionsandmatchedcolors,butalsocommunicatewiththeuseraskingfortheanswerstotheguesses.Thiswillbearealgame.WebprogrammingisextremelyimportantforJavaprogrammers.Mostoftheprogramsarewebapplications.TheuniversalclientavailableontheInternetisthewebbrowser.Thethin-client,webbrowser-basedarchitectureiswidelyacceptedinenterprisesaswell.Thereareonlysomeexceptionswhenthearchitecturehassomethingelsebutthewebclient.IfyouwanttobecomeaprofessionalJavadeveloper,youmustbefamiliarwithwebprogramming.Anditisalsofun!

Therearealotoftechnicaltopicsthatwewillvisitduringthedevelopment.Firstofall,wewilldiscussnetworkingandwebarchitecture.Thisistheconcretebaseofthewholebuilding.Itisnottoosexy,justlikewhenyouconstructthebuilding.Youspendalotofmoneyandeffortdiggingtrenches,andthenyouburytheconcreteandendupattheendofthephasewithwhatyouseeminglyhadbefore:flatground.Exceptthatthereisthebase.Buildingwithoutthisbase,thehousewouldeithercollapsesoonafterorduringtheprocessofbuilding.Networkingisjustasimportantforwebprogramming.Therearealotoftopicsthatseeminglyhavenothingtodowithprogramming.Still,itisthebaseofthebuildingandwhenyouprogramwebapplications,youwillalsofindthefunpartinit.

WewillalsotalkabitaboutHTML,CSS,andJavaScript,butnottoomuch.Wecannotavoidthembecausetheyarealsoimportantforwebprogramming,buttheyaretopicsthatyoucanlearnfromsomewhereelseaswell.Incaseyouarenotanexpertinsomeoftheseareas,thereareusuallyotherexpertsinenterpriseprojectteamswhocanextendyourknowledge.(Inthecaseofnetworking,thereisnomercy.)Inadditiontothat,JavaScriptisatopicsocomplexandhugethatitdeservesawholebooktostartwithit.ThereareonlyveryfewexpertswhodeeplyunderstandbothJavaandJavaScript.Iunderstandthegeneralstructureofthelanguageandtheenvironmentitrunsin,butIcannotkeepupwiththenewframeworksthatarereleasedeveryweekthesedays,havingmyfocusonotherareas.

YouwilllearnhowtocreateJavaapplicationsthatruninanapplicationserver,thistimeinJetty,andwewillseewhataservletis.Wewillcreateawebhelloworldapplicationtostartupfast,andthenwewillcreatetheservletversionofMastermind.Notethatwehardlyeverprogramservletsdirectlywithouttheaidofsomeframeworkthatimplementsthecodetohandleparameters,authentication,andmanyotherthingsthatarenotapplication-specific.Wewillstillsticktoanakedservletinthischapterbecauseitisnotpossibletoeffectivelyuseframeworks,suchasSpring,withoutfirstunderstandingwhataservletis.Springwillcomeinthenextchapter.

WewillmentionJavaServerPages(JSP)onlybecauseyoumaymeetsomelegacyapplication,whichwasdevelopedusingthattechnology,butmodernwebapplicationsdonotuseJSP.Still,JSPisapartoftheservletstandardandisavailableforuse.Thereareothertechnologiesthatweredevelopedintherecentpastbutdonotseemtobefuture-proofthesedays.Theyarestillusablebutappearonlyinlegacy

Page 463:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

applications,andchoosingthemforanewprojectisfairlyquestionable.Wewilltalkaboutthesetechnologiesshortlyinaseparatesection.

Bytheendofthischapter,youwillunderstandhowthebasicwebtechnologyworksandwhatthemajorarchitecturalelementsare,andyouwillbeabletocreatesimplewebapplications.ThisisnotenoughtobeaprofessionalJavawebdeveloperbutwillbeagoodgroundingforthenextchapter,wherewewillhavealookattheprofessionalframeworksusedintoday'senterprisesforrealapplicationdevelopments.

Page 464:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 465:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Webandnetwork

Programsrunoncomputers,andcomputersareconnectedtotheInternet.Thisnetworkwasdevelopedinthelast60years,firsttoprovidemilitarydatacommunicationthatisresilienttorocketattack,thenitwasextendedtobeanacademicnetwork,andlateritbecameacommercialnetworkusedbyanyoneandavailablealmostubiquitouslyallovertheEarth.

Thedesignofthenetwork,andtheresearch,startedasaresponsetotheflightofGagarinovertheEarthinthefifties.SendingGagarintospaceandtravellingovertheEarthwasademonstrationthatRussiacouldsendarocketanywhereontheglobe,possiblywithatomicexplosives.Itmeantthatanydatanetworkthatneededsomecentralcontrolwasnotresilienttosuchanattack.Itwasnotfeasibletohaveanetworkwithacentrallocationasasinglepointoffailure.Therefore,researchwasstartedtocreateanetworkthatgoesonworkingevenifanypartofitisbroughtdown.

Page 466:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 467:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IPThenetworkdeliversdatapacketsbetweenanytwocomputersconnectedtoit.TheprotocolusedonthenetworkisIP,whichissimplyanabbreviationofInternetProtocol.UsingIP,acomputercansendadatapackettoanother.Thepackagecontainsaheaderandthedatacontent.TheheadercontainstheInternetaddressesofthesenderandthetargetmachine,otherflags,andinformationaboutthepackage.Sincethemachinesarenotconnectedtoeachotherdirectly,routersforwardthepackets.Itislikepostofficessendingmailstoeachothertillitgetsintothehandsofthepostmanyouknow,whocandirectlydeliverittoyourmailbox.Todothat,theroutersusetheinformationintheheader.ThealgorithmandorganizationofhowtheroutersinteractarecomplexandsomethingweneednotknowtobeJavaprofessionals.

IfyoueverneedtoprograminordertosendIPpacketsdirectly,youshouldlookatjava.net.DatagramPacket,andtherestisimplementedintheJDK,theoperatingsystem,andonthefirmwareofthenetworkcard.Youcancreateadatapacket;sendingitandchangingthemodulatedvoltageonthenetworkcardoremittingphotonstothefiberisnotyourheadache.However,youwillallknowwhetheryoureallyneedtoprogramdatagramsdirectly.

IPhastwoversions.TheoldversionstillinuseisIPv4.ThenewversionthatcoexistswiththeoldoneisIPv6orIPng(ngstandsfornewgeneration).ThemajordifferencethatmayconcernaJavadeveloperisthatversion4uses32-bitaddressesandversion6uses128-bitaddresses.Whenyouseeaversion-4address,youwillseesomethinglike192.168.1.110,whichcontainsthefourbytesinadecimalformatseparatedbydots.IPv6addressesareexpressedas2001:db8:0:0:0:0:2:1,aseight16-bitnumbersexpressedinhexadecimalseparatedbycolons.

TheWebisabitmorecomplexthansendingdatapackets.Ifsendingadatapacketislikesendingaone-pageletter,thenawebpagedownloadislikediscussingacontractinpapermail.Thereshouldbeanagreementintheinitialpapermailastowhattosend,whattoanswer,andsoon,untilthecontractissigned.OntheInternet,thatprotocoliscalledTransmissionControlProtocol(TCP).Whileitishighlyunlikely(butpossible)thatyouwillmeetIProutingissues,beingaJavadeveloper,youcertainlymaymeetTCPprogramming.Therefore,wewillcovershortlyhowtheTCPworks.Beawarethatthisisverybrief.Really.YouwillnotbecomeaTCPexpertreadingthenextsection,butyouwillgetaglimpseofthemostimportantissuesthataffectwebprogramming.

Page 468:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 469:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TCP/IPTheTCPprotocolisimplementedintheoperatingsystemandprovidesahigherlevelofinterfacethanIP.WhenyouprogramTCP,youdonotdealwithdatagrams.Instead,youhaveachannelofbytestreamswhereyoucanputbytestobedeliveredtotheothercomputer,andyoucanreadbytesfromthechannelthatweresentbytheothercomputer,exactlyintheorderastheyweresent.Thisisakindofconnectionbetweentwocomputersand,what'smore,betweentwoprograms.

ThereareotherprotocolsthatareimplementedoverIPandwhicharenotconnection-oriented.OneofthemisUserDatagramProtocol(UDP),usedforserviceswhenthereisnoneedforconnections,whenthedatamaybelostanditismoreimportantthatthedatagetstothedestinationinatimelymannerthanlosingsomeofthepackets(videostreaming,telephony).Whenthedataamountissmallandincaseitisnotdelivered,itcanberequestedagain;thecostoflosingitischeap(DNSrequest,seethenextsection).

Whenapacketislostonthenetwork,orwhenitissenttwice,orwhenitisdeliveredsoonerthanalaterpackage,itishandledbytheTCPsoftwarelayerimplementedbytheoperatingsystem.ThislayerisalsopopularlycalledtheTCPstack.

SincetheTCPisaconnectedprotocol,thereisaneedforsomethingthattellstheTCPstackwhichstreamadatagrambelongstowhenitarrives.Thestreamisidentifiedbytwoports.Aportisa16-bitinteger.Oneidentifiestheprogramthatinitiatestheconnection,calledthesourceport.Theotheroneidentifiesthetargetprogram:thedestinationport.ThesearecontainedineachandeveryTCPpacketdelivered.WhenamachinerunsaSecureShell(SSH)serverandawebserver,theyusedifferentports,usuallyport22and80.Whenapackagecomesthatcontainsthedestinationportnumber22intheTCPheader,theTCPstackknowsthatthedatainthepacketbelongstothestreamhandledbytheSSHserver.Likewise,ifthedestinationportis80,thenthedatagoestothewebserver.

Whenweprogramaserver,weusuallyhavetodefinetheportnumber;otherwise,thereisnowaytheclientswillfindtheserverprogram.Webserversareusuallylistenonport80,andclientstrytoconnecttothatport.Theclientportisusuallynotimportantandnotspecified;itisallocatedbytheTCPstackautomatically.

Toconnectfromaclientcodetoaserveriseasy:onlyafewlinesofcode.Sometimes,itisonlyonelineofcode.However,underthehood,thereisalotofworkthattheTCPstackdoesthatweshouldcareabout—ittakestimetobuildupaTCPconnection.

Tohaveaconnection,theTCPstackhastosendadatagramtothedestinationtoknowthatitexists.Ifthereisnoserverlisteningontheport,sendingthedataoverthenetworkhasnoresult,exceptforwastingthenetworkbandwidth.Forthisreason,theclientfirstsendsanemptydatapacketcalledSYN.Whentheothersidereceivesit,itsendsbackasimilarpackagecalledSYN-ACK.Finally,theclientsendsapackagecalledACK.IfthepacketsgothroughtheAtlantic,thisisapproximately45msforeachpackage,whichisequivalentto45millionsecondsinbureaucrattime.Thisisalmostoneandahalfyears.Weneedthreeofthosetosetuptheconnection,andthereismore.

Page 470:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhenaTCPconnectionstarts,theclientdoesnotstarttosendthedatawithoutcontrol.Itsendssomedatapacketsandthenitwaitsfortheservertoacknowledgetheirreceipt.Itwouldnotonlybeuseless,butalsonetworkwasting,tosenddatathattheserverisnotpreparedtoacceptandhastothrowaway.TheTCPisdesignedtooptimizethenetworkusage.Therefore,theclientsendssomedata,andthenitwaitsfortheacknowledgement.TheTCPstackautomaticallymanagesthis.Iftheacknowledgementarrives,itsendsmorepackets,andifacarefullydesignedoptimizationalgorithm,implementedintheTCPstack,believesthatitisgoodtosendmore,itwillsendabitmoredatathaninthefirststep.Iftherearenegativeacknowledgementstellingtheclientthattheservercouldnotacceptsomeofthedataandhadtothrowitaway,thentheclientwilllowerthenumberofpacketsitsendswithoutacknowledgement.Butfirstitstartsslowandcautious.ThisiscalledTCPslowstartandwehavetobeawareofit.AlthoughitisalowlevelnetworkingfeatureithasconsequencesthatwehavetoconsiderinourJavacode:weusedatabaseconnectionpoolsinsteadofcreatinganewconnectiontothedatabaseeachtimethereisaneedforsomedata;wetrytomanagetohaveasfewconnectionstowebserversaspossibleusingtechniquessuchaskeep-alive,SPDYprotocol,orhttp/2.0(alsoreplacingSPDY).

Forastart,itisenoughthatTCPisconnection-orientedwhereyoubuildupaconnectiontoaserver,sendandreceivebytes,andfinallyclosetheconnection.Whenyouhaveanetworkperformanceproblem,youhavetolookattheissuesIlisted.

Page 471:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 472:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

DNS

TheTCPprotocolcreatesachannelusingtheIPaddressesofmachines.WhenyoutypeaURLinthebrowser,itusuallydoesnotcontainIPnumbers.Itcontainsmachinenames.ThenameisconvertedtoIPnumbersusingadistributeddatabasecalledDomainNameSystem(DNS).Thisdatabaseisdistributed,andwhenaprogramneedstoconvertanametoanaddress,itsendsDNSrequesttooneoftheDNSserversitknows.Theseserversqueryeachotherortelltheclientwhomtoask,untiltheclientknowstheIPaddressassignedtothename.Theserversandtheclientalsocachetherecentlyrequestednames,soansweringisfast.Ontheotherhand,whentheIPaddressofaserverchangesthisname,notallclientswillimmediatelyseetheaddressassignmentovertheglobe.TheDNSlookupcanbeeasilyprogrammed,andthereareclassesandmethodsinJDKthatsupportthis,butusuallyweneednotcareaboutthat;whenweprogram,itisdoneautomaticallyinwebprogramming.

Page 473:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 474:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheHTTPprotocolTheHypertextTransportProtocol(HTTP)isbuiltontopoftheTCP.WhenyoutypeaURLinabrowser,thebrowseropensaTCPchanneltotheserver(afterDNSlookup,ofcourse)andsendsaHTTPrequesttothewebserver.Theserver,afterreceivingtherequest,producesaresponseandsendsittotheclient.Afterthat,theTCPchannelmaybeclosedorkeptaliveforfurtherHTTPrequest-responsepairs.

Boththerequestandtheresponsecontainaheaderandanoptional(possiblyzero-length)body.Theheaderisinthetextformat,anditisseparatedfromthebodybyanemptyline.

Morepreciselytheheaderandthebodyareseparatedbyfourbytes:0x0D,0x0A,0x0D,and0x0A,whicharetwoCR,LFlineseparators.TheHTTPprotocolusescarriagereturnandlinefeedtoterminatelinesintheheader,andthus,anemptylineistwoCRLFfollowingeachother.

Thestartoftheheaderisastatuslineplusheaderfields.ThefollowingisasampleHTTPrequest:

GET/html/rfc7230HTTP/1.1

Host:tools.ietf.org

Connection:keep-alive

Pragma:no-cache

Cache-Control:no-cache

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0(Macintosh;IntelMacOSX10_11_6)AppleWebKit/537.36(KHTML,likeGecko)Chrome/52.0.2743.116Safari/537.36

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

DNT:1

Referer:https://en.wikipedia.org/

Accept-Encoding:gzip,deflate,sdch,br

Accept-Language:en,hu;q=0.8,en-US;q=0.6,de;q=0.4,en-GB;q=0.2

Thefollowingistheresponse:

HTTP/1.1200OK

Date:Tue,04Oct201613:06:51GMT

Server:Apache/2.2.22(Debian)

Content-Location:rfc7230.html

Vary:negotiate,Accept-Encoding

TCN:choice

Last-Modified:Sun,02Oct201607:11:54GMT

ETag:"225d69b-418c0-53ddc8ad0a7b4;53e09bba89b1f"

Accept-Ranges:bytes

Cache-Control:max-age=604800

Expires:Tue,11Oct201613:06:51GMT

Content-Encoding:gzip

Strict-Transport-Security:max-age=3600

X-Frame-Options:SAMEORIGIN

X-Xss-Protection:1;mode=block

X-Content-Type-Options:nosniff

Keep-Alive:timeout=5,max=100

Connection:Keep-Alive

Transfer-Encoding:chunked

Content-Type:text/html;charset=UTF-8

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="en"lang="en">

<headprofile="http://dublincore.org/documents/2008/08/04/dc-html/">

<metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>

<metaname="robots"content="index,follow"/>

Therequestdoesnotcontainabody.Thestatuslineisasfollows:

Page 475:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GET/html/rfc7230HTTP/1.1

Itcontainstheso-calledmethodoftherequest,theobjectthatisrequested,andtheprotocolversionusedbytherequest.Therestoftherequestoftheheadercontainsheaderfieldsthathavetheformat,label:value.Someofthelinesarewrappedintheprintedversion,butthereisnolinebreakinaheaderline.

Theresponsespecifiestheprotocolituses(usuallythesameastherequest),thestatuscode,andthemessageformatofthestatus:HTTP/1.1200OK

Afterthis,theresponsefieldscomewiththesamesyntaxasintherequest.Oneimportantheaderisthecontenttype:

Content-Type:text/html;charset=UTF-8

Itspecifiesthattheresponsebody(truncatedintheprintout)isHTMLtext.

TheactualrequestwassenttotheURL,https://tools.ietf.org/html/rfc7230,whichisthestandardthatdefinesthe1.1versionofHTTP.Youcaneasilylookintothecommunicationyourself,startingupthebrowserandopeningthedevelopertools.Suchatoolisbuiltintoeverybrowserthesedays.YoucanuseittodebugtheprogrambehavioronthenetworkapplicationlevellookingattheactualHTTPrequestsandresponsesonthebytelevel.Thefollowingscreenshotshowshowthedevelopertoolshowsthiscommunication:

Page 476:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 477:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 478:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HTTPmethodsThemethodthatisthefirstwordinthestatuslineoftherequesttellstheserverwhattodowiththerequest.Thestandarddefinesdifferentmethods,suchasGET,HEAD,POST,PUT,DELETE,andsomeothers.

TheclientusestheGETmethodwhenitwantstogetthecontentofaresource.InthecaseofaGETrequest,thebodyoftherequestisempty.Thisisthemethodusedbythebrowserwhenwedownloadawebpage.Itisalso,manytimes,themethodusedwhensomeprogramimplementedinJavaScriptandrunninginthebrowserasksforsomeinformationfromawebapplication,butitdoesnotwanttosendmuchinformationtotheserver.

WhentheclientusesPOST,theintentionisusuallytosendsomedatatotheserver.Theserverdoesreplyand,manytimes,thereisalsoabodyinthereply,butthemainpurposeoftherequest/replycommunicationistosendsomeinformationfromtheclienttotheserver.ThisistheoppositeoftheGETmethodinsomesense.

TheGETandPOSTmethodsarethemostfrequentlyusedmethods.AlthoughthereisageneralguidelinetouseGETtoretrievedataandPOSTtosenddatatotheserver,itisonlyarecommendation,andthereisnocleanseparationofthetwocases.Manytimes,GETisusedtosendsomedatatotheserver.Afterall,itisanHTTPrequestwithastatuslineandheaderfields,andalthoughthereisnobodyintherequest,theobject(partoftheURL)thatfollowsthemethodinthestatuslineisstillabletodeliverparameters.Manytimes,itisalsoeasytotestaservicethatrespondstoaGETrequestbecauseyouonlyneedabrowserandtotypeintheURLwiththeparameters,andlookattheresponseinthebrowserdevelopertools.YoushouldnotbesurprisedifyouseeanapplicationthatusesGETrequeststoexecuteoperationsthatmodifythestateonawebserver.However,notbeingsurpriseddoesnotmeanapproval.Youshouldbeawarethatinmostcases,thesearenotgoodpractices.WhenwesendsensitiveinformationusingtheGETrequest,theparametersintheURLareavailabletotheclientintheaddresslineofthebrowser.WhenwesendusingPOST,theparametersarestillreachablebytheclient(afterall,theinformationtheclientsendsisgeneratedbytheclientand,assuch,cannotbeunavailable),butnotthateasyforasimplesecurity-unawareusertocopy-pastetheinformationandsend,perhaps,toamalevolentthirdparty.ThedecisionbetweenusingGETandPOSTshouldalwaysconsiderpracticalitiesandsecurityissues.

TheHEADmethodisidenticaltoaGETrequest,buttheresponsewillnotcontainabody.Thisisusedwhentheclientisnotinterestedintheactualresponse.Itmayhappenthattheclientalreadyhastheobjectandwantstoseeifitwaschanged.TheLast-Modifiedheaderwillcontainthetimewhentheresourcewaslastchanged,andtheclientcandecideifithasaneweroneorneedstoaskfortheresourceinanewrequest.

ThePUTmethodisusedwhentheclientwantstostoresomethingontheserverandDELETEwhentheclientwantstoerasesomeresource.ThesemethodsareusedonlybyapplicationsusuallywritteninJavaScriptandnotdirectlybythebrowser.

Thereareothermethodsdefinedinthestandard,butthesearethemostimportantandfrequentlyusedones.

Page 479:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 480:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Statuscodes

Theresponsestartswiththestatuscode.Thesecodesarealsodefinedandtherearealimitednumberofcodesusableinaresponse.Themostimportantis200,whichsaysallisOK;theresponsecontainswhattherequestwanted.Thecodesarealwaysintherangeof100to599,containthreedigits,andaregroupedbythefirstdigit.

1xx:Thesecodesareinformationcodes.Theyarerarelyusedbutcanbeveryimportantinsomecases.Forexample,100meanscontinue.AservercansendthiscodewhenitgetsaPOSTrequestandtheserverwantstosignaltheclienttosendthebodyoftherequestbecauseitcanprocessit.Usingthiscode,andtheclientwaitingforthiscode,maysavealotofbandwidthifproperlyimplementedontheserverandalsoontheclient.2xx:Thesecodesmeansuccess.Therequestisansweredproperly,ortherequestedservicewasdone.Therearecodes,suchas200,201,202,andsoon,definedinthestandardandthereisadescriptionaboutwhentouseoneortheother.3xx:Thesecodesmeanredirection.OneofthesecodesissentwhentheservercannotdirectlyservicetherequestbutknowstheURLthatcan.Theactualcodescandistinguishbetweenapermanentredirect(whenitisknownthatallfuturerequestsshouldbesenttothenewURL)andtemporaryredirect(whenanylaterrequestshouldbesenthereandpossiblyservedorredirected),butthedecisioniskeptontheserverside.4xx:Theseareerrorcodes.Themostfamouscodeis404,whichmeansNotFound,thatis,theserverisnotabletorespondtotherequestbecausetheresourceisnotfound.401meansthattheresourcetoservetherequestmaybeavailablebutitrequiresauthentication.403isacodethatsignalsthattherequestwasvalidbutisstillrefusedtobeservedbytheserver.5xx:Thesecodesareservererrorcodes.Whenaresponseholdsoneoftheseerrorcodes,themeaningisthatthereissomeerrorontheserver.Thiserrorcanbetemporary,forexample,whentheserverisprocessingtoomanyrequestsandcannotrespondtoanewrequestwithacalculation-intensiveresponse(thisisusuallysignaledbyerrorcode503)orwhenthefeatureisnotimplemented(code501).Thegeneralerrorcode500isinterpretedasInternalError,whichmeansthatnoinformation,whatsoever,isavailableaboutwhatwasgoingwrongontheserver,butitwasnotgoingwellandhence,nomeaningfulresponse.

Page 481:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 482:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HTTP/2.0Afteralmost20yearssincethelastreleaseofHTTP,thenewversionofHTTPwasreleasedin2015.Thisnewversionoftheprotocolhasseveralenhancementsoverthepreviousversions.Someoftheseenhancementswillalsoaffectthewayserverapplicationswillbedeveloped.

ThefirstandmostimportantenhancementisthatthenewprotocolwillmakeitpossibletosendseveralresourcesparallellyinasingleTCPconnection.Thekeep-aliveflagisavailabletoavoidtherecreationoftheTCPchannel,butitdoesnothelpwhenaresponseiscreatedslowly.Inthenewprotocol,otherresourcescanalsobedeliveredinthesameTCPchannelevenbeforeonerequestisfullyserved.Thisrequirescomplexpackagehandlingintheprotocol,butthisishiddenfromtheserverapplicationprogrammeraswellasthebrowserprogrammer.Theapplicationserver,servletcontainer,andbrowserimplementthistransparently.

HTTP/2.0willalwaysbeencrypted,thereforeitwillnotbepossibletousehttpasaprotocolinthebrowserURL.Itwillalwaysbehttps.

Thefeaturethatwillneedchangesinservletprogrammingtoleveragetheadvantagesofthenewversionoftheprotocolisserverpush.Version4.0oftheservletspecificationincludessupportforHTTP/2.0,andthisversionisstillindraft.

ServerpushisanHTTPresponsetoarequestthatwillcomeinthefuture.Howcanaserveranswerarequestthatisnotevenissued?Well,theserveranticipates.Forexample,theapplicationsendsanHTMLpagethathasreferencestomanysmallpicturesandicons.TheclientdownloadstheHTMLpage,buildstheDOMstructure,analyzesit,andrealizesthatthepicturesareneeded,andsendstherequestforthepictures.Theapplicationprogrammerknowswhatpicturesarethereandmaycodetheservertosendthepicturesevenbeforethebrowserrequestsforit.EverysuchresponseincludesaURLthatthisresponseisfor.Whenthebrowserwantstheresource,itrealizesthatitisalreadythereanddoesnotissueanewrequest.InHttpServlet,theprogramshouldaccessPushBuilderviatherequest'snewgetPushBuildermethodandusethattopushdownresourcestotheclient.

Page 483:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 484:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CookiesCookiesaremaintainedbythebrowserandaresentintheHTTPrequestheaderusingtheCookieheaderfield.Eachcookiehasaname,value,domain,path,expirationtime,andsomeotherparameters.WhenarequestissenttoaURLthatmatchesthedomain,thepathofanon-expiredcookie,theclientsendsthecookietotheserver.Cookiesareusuallystoredinsmallfilesontheclientbythebrowserorinalocaldatabase.Theactualimplementationisthebusinessofthebrowser,andweneednotworryaboutit.Itisjustthetextinformationthatisnotexecutedbytheclient.Itisonlysentbacktotheserverwhensomerules(mainlydomainandpath)match.CookiesarecreatedbyserversandaresenttotheclientinHTTPresponsesusingtheSet-Cookieheaderfield.Thus,essentiallytheservertellstheclient,Hey,hereisthiscookie,wheneveryoucometomenexttime,showmethispieceofinformation,soIwillknowitisyou.

Cookiesareusuallytorememberclients.Advertisersandonlineshopsthatneedtorememberwhotheyaretalkingtoheavilyuseit.Butthisisnottheonlyuse.Thesedays,anyapplicationthatmaintainsusersessionsusescookiestochainuptheHTTPrequeststhatcomefromthesameuser.Whenyoulogintoanapplication,theusernameandpasswordyouusetoidentifyyourselfaresenttotheserveronlyonce,andinsubsequentrequests,onlyaspecialcookieissenttotheserverusedtoidentifythealreadyloggedinuser.Thisuseofcookiesemphasizeswhyitisimportanttousecookievaluesthatcannotbeeasilyguessed.Ifthecookieusedtoidentifyauseriseasilyguessable,thenanattackercouldjustcreateacookieandsendittotheservermimickingtheotheruser.Cookievalues,forthepurpose,areusuallylongrandomstrings.

Cookiesarenotalwayssentbacktotheserverwheretheyoriginate.Whenthecookieisset,theserverspecifiesthedomainoftheURLwherethecookieshouldbesentback.Thisisusedwhenadifferentserverfromtheoneprovidingtheservicesneedingauthenticationdoestheuserauthentication.

Applicationssometimesencodevaluesintocookies.Thisisnotnecessarilybad,thoughinmostactualcases,itis.Whenencodingsomethingintoacookie,weshouldalwaysconsiderthefactthatthecookietravelsthroughthenetworkandcangohugeasmoreandmoredataisencodedinitandcancreateunnecessaryburdenonthenetwork.Usually,itisbettertosendonlysomeunique,otherwisemeaningless,randomkey,andstorethevaluesinsomedatabase,beitondiskorinthememory.

Page 485:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 486:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ClientserverandwebarchitectureTheapplicationswedevelopedsofarwererunningonasingleJVM.Wealreadyhavesomeexperiencewithconcurrentprogrammingandthisissomethingthatwillcomehandynow.Whenweprogramawebapplication,apartofthecodewillrunontheserverandapartoftheapplicationlogicwillexecuteinthebrowser.TheserverpartwillbewritteninJava,thebrowserpartwillbeimplementedinHTML,CSS,andJavaScript.SincethisisaJavabookwewillfocusmainlyontheserverpart,butweshouldstillbeawareofthefactthatmanyofthefunctionalitiescanbeandshouldbeimplementedtoruninthebrowser.ThetwoprogramscommunicatewitheachotherovertheIPnetwork,thatis,theInternet,orinthecaseofanenterpriseinternalapplication,thenetworkofthecompany.

Today,abrowseriscapableofrunningverypowerfulapplications,allimplementedinJavaScript.Afewyearsago,suchapplicationsneededclientapplicationimplementedinDelphi,C++,orJava,usingthewindowingcapabilitiesoftheclientoperatingsystem.

Originally,theclient-serverarchitecturemeantthatthefunctionalityoftheapplicationwasimplementedontheclient,andtheprogramwasusinggeneralservicesonlyfromtheserver.Theserverprovideddatabaseaccessandfilestoragebutnothingmore.Later,thethree-tierarchitectureputthebusinessfunctionalityontheserversthatusedotherserversfordatabaseandothergeneralservices,andtheclientapplicationimplementedtheuserinterfaceandlimitedbusinessfunctionality.

Whenthewebtechnologystartedtopenetrateenterprisecomputing,thewebbrowserstartedtoreplacetheclientapplicationsinmanyusecases.Previously,thebrowsercouldnotruncomplexJavaScriptapplications.TheapplicationwasexecutedonthewebserverandtheclientdisplayedtheHTMLthattheservercreatedasapartoftheapplicationlogic.Everytimesomethingwaschangedontheuserinterface,thebrowserstartedacommunicationwiththeserver,andinaHTTPrequest-responsepair,thebrowsercontentwasreplaced.Awebapplicationwasessentiallyaseriesofformfillingandformdatasendingtotheserver,andtheserverrespondedwithHTML-formattedpages,presumablycontainingnewforms.

JavaScriptinterpretersweredevelopedandbecamemoreandmoreeffectiveandstandardized.Today,modernwebapplicationscontainHTML(whichisapartoftheclientcodeandisnotgeneratedbytheserveronthefly),CSS,andJavaScript.Whenthecodeisdownloadedfromthewebserver,theJavaScriptstartstoexecuteandcommunicatewiththeserver.ItisstillHTTPrequestsandresponses,buttheresponsesdonotcontainHTMLcode.Itcontainspuredata,usuallyintheJSONformat.ThisdataisusedbytheJavaScriptcodeandsomeofthedata,ifneeded,isdisplayedonthewebbrowserdisplayalsocontrolledbyJavaScript.Thisisfunctionallyequivalenttoathree-tierarchitecturewithsomeslightbutveryimportantdifferences.

Thefirstdifferenceisthatthecodeisnotinstalledontheclient.Theclientdownloadstheapplicationfromawebserver,andtheonlythingthatisinstalledisthemodernbrowser.Thisremovesalotofenterprisemaintenanceburdenandcost.

Theseconddifferenceisthattheclientisnotable,orislimited,toaccesstheresourcesoftheclientmachine.Thickclientapplicationscouldsaveanythinginalocalfileoraccessalocaldatabase.Thisisverylimited,forsecurityreasons,comparedtoaprogramrunningonthebrowser.Atthesametimethisis

Page 487:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ahandylimitationbecauseclientsaren'tandshouldn'tbeatrustedpartofthearchitecture.Thediskintheclientcomputerishardandexpensivetobackup.Itcanbestolenwithanotebook,andencryptingitiscostly.Therearetoolstoprotectclientstorage,butmostofthetime,storingthedataontheserveronlyisamoreviablesolution.

Itisalsoacommonprogramdesignerrortotrusttheclientapplication.Theclientphysicallycontrolstheclientcomputerandalthoughitcanbemadetechnicallyverydifficult,theclientcanstillovercomethesecuritylimitationsoftheclientdeviceandclientcode.Ifitisonlytheclientapplicationthatchecksthevalidityofsomefunctionalityordata,thenthephysicalsecurityprovidedbythephysicalcontroloftheserverisnotused.Wheneverdataissentfromtheclienttotheserver,thedatahastobecheckedinregardsofvalidity,nomatterwhattheclientapplicationis.Actually,sincetheclientapplicationcanbechanged,wejustdon'treallyknowwhattheclientapplicationreallyis.

Inthischapterand,asamatteroffact,intheentirebook,wefocusonJavatechnologies;thereforethesampleapplicationwillnotcontainalmostanyclienttechnology.IcouldnothelpbutcreatesomeCSS.Ontheotherhand,IdefinitelyavoidedJavaScript.Therefore,Ihavetoemphasizeagainthattheexampleistodemonstratetheprogrammingoftheserversideandstillprovidingsomethingthatreallyworks.AmodernapplicationwoulduseRESTandJSONcommunicationsandwouldnotplayaroundcreatingHTMLontheflyontheserverside.Originally,IwantedtocreateaJavaScriptclientandRESTserverapplication,butthefocuswasmovedsomuchfromserver-sideJavaprogrammingthatIdroppedthisidea.Ontheotherhand,youcanextendtheapplicationtobeonelikethat.

Page 488:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 489:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WritingservletsServletsareJavaclassesthatareexecutedinawebserverthatimplementstheservletcontainerenvironment.ThefirstwebserverscouldonlydeliverstaticHTMLfilestothebrowsers.ForeachURL,therewasanHTMLpageonthewebserverandtheserverdeliveredthecontentofthisfile,inresponsetoarequestsentbythebrowser.Verysoon,therewasaneedtoextendthewebserverstobeabletostartsomeprogramthatcalculatesthecontentoftheresponse,onthefly,whentherequestisprocessed.

ThefirststandardtodothatdefinedCGI.Itstartedanewprocesstorespondtoarequest.Thenewprocessgottherequestonitsstandardinput,andthestandardoutputwassentbacktotheclient.Thisapproachwastesalotofresources.Startinganewprocess,asyoulearnedinthepreviouschapter,iswaytoocostlyjusttorespondtoanHTTPrequest.Evenstartinganewthreadseemstobeunnecessary,butwiththat,weranabitahead.

ThenextapproachwasFastCGI,executingtheexternalprocesscontinuallyandreusingit,andthencamedifferentotherapproaches.Theapproachesafter

FastCGIallusein-processextensions.Inthesecases,thecodecalculatingtheresponserunsinsidethesameprocessasthewebserver.SuchstandardsorextensioninterfaceswereISAPIfortheMicrosoftIISserver,NSASPIfortheNetscapeserver,andtheApachemoduleinterface.Eachofthesemadeitpossibletocreateadynamicallyloadedlibrary(DLLonWindowsorSOfilesonUnixsystems)tobeloadedbythewebserverduring

startupandtomapcertainrequeststobehandledbythecodeimplementedintheselibraries.

WhensomebodyprogramsPHP,forexample,theApachemoduleextensionisthePHPinterpreterthatreadsthePHPcodeandactsuponit.WhensomebodyprogramsASPpagesfortheMicrosoftIIS,theISAPIextensionimplementingtheASPpageinterpreterisexecuted(well,thisisabitsloppyandoversimplifiedtosaybutworksasanexample).

ToJava,theinterfacedefinitionisaservletdefinedinJSR340asofversion3.1.

JSRstandsforJavaSpecificationRequest.ThesearerequestsformodificationoftheJavalanguage,libraryinterfaces,andothercomponents.Therequestsgothroughanevaluationprocess,andwhentheyareaccepted,theybecomeastandard.TheprocessisdefinedbytheJavaCommunityProcess(JCP).JCPisalsodocumentedandhasversions.Thecurrentversionis2.10andcanbefoundathttps://jcp.org/en/procedures/overview.TheJSR340standardcanbefoundathttps://jcp.org/en/jsr/detail?id=340.

Aservletprogramimplementstheservletinterface.UsuallythisisdoneviaextendingHttpServlet,theabstractimplementationoftheServletinterface.Thisabstractclassimplementsmethods,suchasdoGet,doPost,doPut,doDelete,doHead,doOption,anddoTrace,freetobeoverriddenbytheactualclassextendingit.Ifaservletclassdoesnotoverrideoneofthethesemethods,sendingthecorrespondingHTTPmethod,GET,POST,andsoon,willreturnthe405NotAllowedstatuscode.

Page 490:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 491:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HelloworldservletBeforegettingintothetechnicaldetails,let'screateanextremelysimplehelloworldservlet.Todoit,wesetupaGradleprojectwiththebuildfile,build.gradle,theservletclassinthefile,src/main/java/packt/java9/by/example/mastermind/servlet/HelloWorld.java,andlastbutnotleast,wehavetocreatethefilesrc/main/webapp/WEB-INF/web.xml.Thegradle.buildfilewilllookthefollowing:

applyplugin:'java'

applyplugin:'jetty'

repositories{

jcenter()

}

dependencies{

providedCompile"javax.servlet:javax.servlet-api:3.1.0"

}

jettyRun{

contextPath'/hello'

}

TheGradlebuildfileusestwoplugins,javaandjetty.Wehavealreadyusedthejavaplugininthepreviouschapter.ThejettypluginaddstaskssuchasjettyRunthatloadtheJettyservletcontainerandstartuptheapplication.ThejettypluginisalsoanextensionofthewarpluginthatcompileswebapplicationsintoaWebArchive(WAR)packagingformat.

TheWARpackagingformatispracticallythesameasJAR;itisazipfileanditcontainsalibdirectorythatcontainsalltheJARfilesthatthewebapplicationdependson.Theclassesoftheapplicationareinthedirectory,WEB-INF/classes,andthereisaWEB-INF/web.xmlfilethatdescribesservletURLmapping,whichwewillexploreindetailsoon.

Sincewewanttodevelopanextremelysimpleservlet,weaddtheservletAPIasadependencytotheproject.Thisis,however,notacompiledependency.TheAPIisavailablewhentheservletrunsinthecontainer.Still,ithastobeavailablewhenthecompilercompilesourcode;therefore,adummyimplementationisprovidedbytheartifactspecifiedasprovidedCompile.Becauseitisspecifiedthatway,thebuildprocesswillnotpackagethelibraryintothegeneratedWARfile.ThegeneratedfilewillcontainnothingthatisspecifictoJettyoranyotherservletcontainer.

Theservletcontainerwillprovidetheactualimplementationoftheservletlibrary.WhentheapplicationisdeployedandstartedinaJetty,theJetty-specificimplementationoftheservletlibrarywillbeavailableontheclasspath.WhentheapplicationisdeployedtoaTomcat,theTomcatspecificimplementationwillbeavailable.

Wecreateaclassinourproject,asfollows:

packagepackt.java9.by.example.mastermind.servlet;

importjavax.servlet.ServletException;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjava.io.IOException;

importjava.io.PrintWriter;

Page 492:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

publicclassHelloWorldextendsHttpServlet{

privateStringmessage;

@Override

publicvoidinit()throwsServletException{

message="Hello,World";

}

@Override

publicvoiddoGet(HttpServletRequestrequest,

HttpServletResponseresponse)

throwsServletException,IOException{

response.setContentType("text/html");

PrintWriterout=response.getWriter();

out.println("<h1>"+message+"</h1>");

}

@Override

publicvoiddestroy(){

}

}

Whentheservletisstarted,theinitmethodisinvoked.Whenitisputoutofservice,thedestroymethodiscalled.Thesemethodscanbeoverriddenandprovideamorefine-grainedcontrolthantheconstructorandotherfinalizationpossibilities.Aservletobjectmaybeputintoservicemorethanonce,andaftercallingdestroy,theservletcontainermayinvokeinitagain;thus,thiscycleisnotstrictlytiedtothelifecycleoftheobject.Usually,thereisnotmuchthatwedointhesemethods,butsometimes,youmayneedsomecodeinthem.

Also,notethatasingleservletobjectmaybeusedtoservemanyrequests,evenatthesametime;thus,theservletclassesandmethodsinitshouldbefairlythread-safe.Thespecificationdemandsthataservletcontainerusesonlyoneservletinstanceincasethecontainerrunsinanon-distributedenvironment.Incasethecontainerrunsonthesamemachineinseveralprocesses,eachexecutingaJVM,orevenondifferentmachines,therecanbemanyservletinstancesthathandletherequests.Generally,theservletclassesshouldbedesignedsuchthattheydonotassumethatonlyonethreadisexecutingthem,butatthesametime,theyshouldalsonotassumethattheinstanceisthesamefordifferentrequests.Wejustcannotknow.

Whatdoesitmeaninpractice?Youshouldnotuseinstancefieldsthatarespecifictoacertainrequest.Intheexample,thefieldinitializedtoholdthemessageholdsthesamevalueforeachandeveryrequest;essentially,thevariableisalmostafinalconstant.Itisusedonlytodemonstratesomefunctionalityfortheinitmethod.

ThedoGetmethodisinvokedwhentheservletcontainergetsanHTTPrequestwiththeGETmethod.Themethodhastwoarguments.Thefirstonerepresentstherequest,andthesecondonerepresentstheresponse.Therequestcanbeusedtocollectallinformationthatcomesintherequest.Intheprecedingexample,thereisnothinglikethat.Wedonotuseanyoftheinputs.Ifarequestcomestoourservlet,thenweanswertheHello,Worldstring,nomatterwhat.Later,wewillseeexampleswhenwereadtheparametersfromtherequest.Theresponsegivesmethodsthatcanbeusedtohandletheoutput.Intheexample,wefetchPrintWriter,whichistobeusedtosendcharacterstothebodyoftheHTTPresponse.Thisisthecontentthatappearsinthebrowser.Themimetypewesendistext/html,andthisissetbycallingthesetContentTypemethod.ThiswillgetintotheHTTPheaderfield,Content-Type.ThestandardandtheJavaDocdocumentationoftheclassesdefineallthemethodsthatcanbeused,andalsohowthese

Page 493:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

shouldbeused.

Finally,wehaveaweb.xmlfilethatdeclarestheservletsthatareimplementedinourcode.Thisis,justasthenameofthefileindicates,anXMLfile.Itdeclarativelydefinesalltheservletsthatareincludedinthearchiveandalsootherparameters.Intheexample,theparametersarenotdefined,onlytheservletandthemappingtotheURL.Sincewehaveonlyonesingleservletinthisexample,theWARfile,itismappedtotherootcontext.AllandeveryGETrequestthatarrivestotheservletcontainerandtothisarchivewillbeservedbythisservlet:

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appversion="2.5"

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<servlet>

<display-name>HelloWorldServlet</display-name>

<servlet-name>HelloWorldServlet</servlet-name>

<servlet-class>packt.java9.by.example.mastermind.servlet.HelloWorld</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>HelloWorldServlet</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

</web-app>

Page 494:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 495:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JavaServerPagesIpromisedyouthatIwouldnotboreyouwithJavaServerPagesbecausethatisatechnologyofthepast.Eventhoughitisthepast,itisstillnothistoryastherearemanyprogramsrunningthatstilluseJSPandcontainJSPcode.

JSPpagesarewebpagesthatcontainHTMLandJavacodemixed.WhenanHTTPrequestisservedbyaJSPpage,theservletcontainerreadstheJSPpage,executestheJavaparts,takestheHTMLpartsastheyare,andinthisway,mixingthetwotogether,createsanHTMLpagethatissenttothebrowser.

<%@pagelanguage="java"

contentType="text/html;charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<body>

<%for(inti=0;i<5;i++){%>

hallo<br/>

<%}%>

</body>

</html>

TheprecedingpagewillcreateanHTMLpagethatcontainsthetexthallofivetimes,eachinanewlineseparatedbythetagbr.Behindthescenes,theservletcontainerconvertstheJSPpagetoaJavaservlet,thencompilestheservletusingtheJavacompiler,andthenrunstheservlet.ItdoesiteverytimethereissomechangeinthesourceJSPfile;therefore,itisveryeasytoincrementallycraftsomesimplecodeusingJSP.ThecodethatisgeneratedfromtheprecedingJSPfileis138lineslong(ontheTomcat8.5.5version),whichissimplylongandboringtolisthere,butthepartthatmayhelptounderstandhowtheJavafilegenerationworksisonlyafewlines.

Ifyouwanttoseeallthelinesofthegeneratedservletclass,youcandeploytheapplicationintoaTomcatserverandlookatthedirectorywork/Catalina/localhost/hello/org/apache/jsp/.Itisararelyknownfactamongdevelopersthatthiscodeisactuallysavedtodiskandisavailable.SometimesithelpswhenyouneedtodebugsomeJSPpages.

Herearethefewinterestinglinesgeneratedfromtheprecedingcode:

out.write("\n");

out.write("<html>\n");

out.write("<body>\n");

for(inti=0;i<5;i++){

out.write("\n");

out.write("hallo<br/>\n");

}

out.write("\n");

out.write("</body>\n");

out.write("</html>\n");

TheJSPcompilermovestheinsideoftheJSPcodeoutandtheoutsidein.IntheJSPcode,JavaissurroundedbyHTML,andinthegeneratedservletJavasource,theHTMLissurroundedbyJava.Itislikewhenyouwanttomendclothes:thefirstthingistoturnthedressinsideout.

ItisnotonlytheJavacodethatyoucanmixintoHTMLintheJSPpagesbutalsotheso-calledtags.Tags

Page 496:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

arecollectedintotaglibraries,implementedinJava,andpackagedintoJARfiles,andtheyshouldbeavailableontheclasspathtobeused.TheJSPpageusingthetagsfromsomelibraryshoulddeclaretheuse:

<%@taglibprefix="c"

uri="http://java.sun.com/jsp/jstl/core"%>

ThetagslooklikeHTMLtags,buttheyareprocessedbytheJSPcompilerandexecutedbythecodeimplementedinthetagliblibrary.JSPmayalsorefertothevalueoftheJavaobjectsthatareavailableinthescopeoftheJSP.TodothisinsidetheHTMLpage,theJSPexpressionlanguagecouldbeused.

JSPwasoriginallycreatedtoeasethedevelopmentofawebapplication.Themainadvantageisthefaststartupofdevelopment.Thereisnolengthytimeforconfiguration,setup,andsooninthedevelopment,andwhenthereisanychangeintheJSPpage,thereisnoneedtocompilethewholeapplicationagain:theservletcontainergeneratestheJavacode,compilesittoclassfile,loadsthecodeintomemory,andexecutes.JSPwasacompetitorofMicrosoftASPpages,whichmixedHTMLwithVisualBasiccode.

Whentheapplicationstartstogrowbig,usingtheJSPtechnologycausesmoreproblemsthanaregood.Thecodethatmixesthebusinesslogicandtheviewoftheapplication,howitisrenderedinthebrowser,becomesmessy.DevelopingJSPrequiresfrontendtechnologyknowledge.AJavadeveloperisexpectedtoknowsomefrontendtechnologybutisrarelyadesignexpertandCSSguru.ModerncodealsocontainsJavaScript,manytimesembeddedintheHTMLpage.Afterall,thebigadvantageofJSPisthatitcontainscodethatrunsontheserveraswellasontheclient-sidecode.Thedevelopersfollowtheparadigmmanytimes,sodonotbesurprisedtoseesomelegacycodethatcontainsJava,HTML,CSS,andJavaScriptallmixedinaJSPfile.SinceJavaandJavaScriptaresyntacticallysimilarsometimes,itisnotobvioustoseewhatisexecutedontheserverandwhatisexecutedontheclient.IhaveevenseencodethatcreatedJavaScriptcodefromJavacodeinaJSPfile.Thatisatotalmixofdifferentresponsibilitiesandamessthatisnearlyimpossibletomaintain.ThisledtothetotaldeprecationofJSPasoftoday.

ThedeprecationofJSPisnotofficial.Itismyexpertopinion.YoumaymeetsomeexperienceddeveloperswhoarestillinlovewithJSP,andyoumayfindyourselfinprojectswhereyouarerequiredtodevelopprogramsinJSP.Itisnotshamefuldoingthat.Somepeopledoworseformoney.

Tomendthemessysituation,thereweretechnologiesthatadvocatedtheseparationoftheservercodeandtheclientfunctionalitymoreandmore.ThesetechnologiesincludeWicket,Vaadin,JSF,anddifferentJavatemplatingengines,suchasFreemarker,ApacheVelocity,andThymeleaf.TheselattertechnologiescanalsobeinterestingwhenyougeneratetextualoutputfromJavaevenwhenthecodeisnotweb-relatedatall.

Thesetechnologies,withdiscipline,helpedcontrolthedevelopmentandmaintenancecostsofmoderateandlargewebprojects,butthebasicproblemofthearchitecturewasstillthere:noclearseparationofconcerns.

Today,modernapplicationsimplementthecodeofawebapplicationinseparateprojects:onefortheclient,usingHTML,CSSandJavaScript,andaseparateonetoimplementserverfunctionalityinJava(orinsomethingelse,butwefocushereonJava).ThecommunicationbetweenthetwoistheRESTprotocol,

Page 497:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

whichwewillcoverinthesubsequentchapters.

Page 498:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 499:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HTML,CSS,andJavaScriptHTML,CSS,andJavaScriptareclient-sidetechnologies.Theseareextremelyimportantforwebapplications,andaprofessionalJavadevelopershouldhavesomeknowledgeaboutthem.NobodyexpectsyoutobeanexpertinJavaandinweb-clienttechnologiesatthesametime,thoughthisisnotimpossible.Acertainunderstandingisdesirable.

HTMListhetextualrepresentationofastructuredtext.Thetextisgivenascharacters,asinanytextfile.Tagsrepresentthestructure.Astarttagstartswitha<character,thenthenameofthetag,then,optionally,name="value"attributes,andfinallyaclosing>character.Anendtagstartswith</,thenthenameofthetag,andthen>.Tagsareenclosedintohierarchies;thus,youshouldnotcloseatagsoonerthantheonethatwasopenedlater.First,thetagthatwasopenedlasthastobeclosed,thenthenext,andsoon.Thisway,anyactualtagintheHTMLhasalevel,andalltagsthatarebetweenthestartandendtagsarebelowthistag.Sometagsthatcannotencloseothertagsortextdonothaveendtagsandstandontheirown.Considerthefollowingsample:

<html>

<head>

<title>thisisthetitle</title>

</head>

</html>

Thetagheadisunderhtml,andtitleisunderhead.Thiscanbestructuredintoatree,asfollows:

html

+head

+title

+"thisisthetitle"

ThebrowserstorestheHTMLtextinatreestructure,andthistreeistheobjectmodelofthewebpagedocument,thusthename,DocumentObjectModel(DOM)tree.

TheoriginalHTMLconceptmixedformattingandstructure,andevenwiththecurrentversionofHTML5,westillhavetagssuchasb,i,ttthatsuggestthebrowsertodisplaythetextbetweenthestartandendtagsinbold,italics,andteletype,respectively.

AsthenameHTML,standingforHypertextMarkupLanguage,suggests,thetextcancontainreferencestootherwebpagesintheformofhyperlinks.Theselinksareassignedtotextsusingtheatag(standingforanchor)ortosomeformthatmayconsistofdifferentfields,andwhenthesubmitbuttonoftheformispressed,thecontentofthefieldsissenttotheserverinaPOSTrequest.Whentheformissent,thecontentofthefieldsisencodedintheso-calledapplication/x-www-form-urlencodedform.

TheHTMLstructurealwaystriedtopromotetheseparationofstructureandformatting.Todoso,formattingwasmovedtostyles.StylesdefinedinCascadingStyleSheets(CSS)providemuchmoreflexibilityforformattingthanHTML;theformatofaCSSismoreeffectiveforformatting.TheaimtocreateCSSwasthatthedesigncanbedecoupledfromthestructureofthetext.IfIhadtochooseoneofthethree,IwouldoptforCSSastheonethatisleastimportantforJavaserver-sidewebdevelopersand,atthesametime,themostimportantfortheusers(thingsshouldlooknice).

Page 500:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JavaScriptisthethirdpillarofclient-sidetechnologies.JavaScriptisafullyfunctional,interpretedprogramminglanguageexecutedbythebrowser.ItcanaccesstheDOMtree,andreadandmodifyit.WhentheDOMtreeismodified,thebrowserautomaticallydisplaysthemodifiedpage.JavaScriptfunctionscanbescheduledandregisteredtobeinvokedwhensomeeventoccurs.Forexample,youcanregisterafunctiontobeinvokedwhenthedocumentisfullyloaded,whentheuserpressesabutton,clicksonalink,orjusthoversthemouseoversomesection.AlthoughJavaScriptwasfirstonlyusedtocreatefunnyanimationsonthebrowser,todayitispossible,andisausualpractice,toprogramfullyfunctionalclientsusingthecapabilitiesofthebrowser.TherearereallypowerfulprogramswritteninJavaScript,evensuchpower-hungryapplicationsasPCemulators.

Inthisbook,wefocusonJavaandusetheclient-sidetechnologiesasmuchasisneededfordemonstrationtechnologies.However,beingaJavawebdeveloperprofessional,youhavetolearnthesetechnologiesaswell,tosomeextentatleast,tounderstandwhataclientcandoandtobeabletocooperatewiththeprofessionalsresponsibleforfrontendtechnologies.

Page 501:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 502:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MastermindservletPlayingtheMastermindgameviatheWebisabitdifferentfromwhatitusedtobe.Tillnow,wedidnothaveanyuserinteractionandourclassesweredesignedaccordingly.Forexample,wecouldaddanewguesstothetable,alongwiththepartialandfullmatchescalculatedbytheprogram.Nowwehavetoseparatethecreationofanewguess,addittothegame,andsetthefullandpartialmatches.Thistime,wehavetodisplaythetablefirst,andtheuserhastocalculateandprovidethenumberofmatches.

Wehavetomodifysomeoftheclassestobeabletodothat.WeneedtoaddanewmethodtoGame.java:publicRowaddGuess(Guessguess,intfull,intpartial){assertNotFinished();finalRowrow=newRow(guess,full,partial);table.addRow(row);if(itWasAWinningGuess(full)){finished=true;}returnrow;}

Tillnow,wehadonlyonemethodthatwasaddinganewguess,andsincetheprogramknewthesecret,itwasimmediatelycalculatingthevalueoffullandpartial.ThenameofthemethodcouldbeaddNewGuess,overloadingtheoriginalmethod,butthistime,themethodisusednotonlytoaddanewguessbutalsotoaddoldguessestorebuildthetable.

Whentheprogramstarts,therearenoguesses.Theprogramcreatesone,thefirstone.Lateron,whentheusertellstheprogramthefullandpartialmatches,theprogramneedstheGamestructurewithTableandRowobjectscontainingGuessobjectsandthefullandpartialmatchvalues.Thesewerealreadyavailable,butwhenthenewHTTPhitcomesin,wehavetopullitfromsomewhere.Programmingaservlet,wehavetostorethestateofthegamesomewhereandrestoreitwhenanewHTTPrequesthitstheserver.

Page 503:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 504:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

StoringstateStoringthestatecanbedoneintwoplaces.Oneplace,whichwewillfirstdoinourcode,istheclient.Whentheprogramcreatesanewguess,itaddsittothetableandsendsanHTMLpagethatcontainsnotonlythenewguessbutalsoallthepreviousguessesandthefullandpartialmatchvaluesthattheusergaveforeachoftherows.Tosendthedatatotheserver,thevaluesarestoredinthefieldsofaform.Whentheformissubmitted,thebrowsergatherstheinformationinthefields,createsanencodedstringfromthecontentofthefields,andputsthecontentintothebodyofaPOSTrequest.

Theotherpossibilityforstoringtheactualstateisintheserver.Theservercanstorethestateofthegame,anditcanreconstructthestructurewhenitcreatesanewguess.Theprobleminthiscaseisknowingwhichgametouse.Theservercanandshouldstoremanygames,oneforeachuser,andusersmayusetheapplicationconcurrently.Itdoesnotnecessarilymeanstrongconcurrencyinthesamemeaningasweexaminedinthepreviouschapter.

Eveniftheusersarenotservedatthesametimeinmultiplethreads,therecanbegamesthatareactive.Imaginecnn.comtellingyouthatyoucannotreadthenewsatthemomentbecausesomebodyelseisreadingit.Therecanbemultipleusersplayingmultiplegames,andwhileservinganHTTPrequest,weshouldknowwhichuserweareserving.

Servletsmaintainsessionsthatcanbeusedforthispurposeaswewillseeinthenextsection.

Page 505:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 506:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

HTTPsessionWhenaclientsendsrequestsfromthesamebrowsertothesameservlet,theseriesofrequestsbelongtoonesession.Toknowthattherequestsbelongtothesamesession,theservletcontainerautomaticallysendsacookienamedJSESSIONIDtotheclient,andthiscookiehasalong,random,hard-to-guessvalue(tkojxpz9qk9xo7124pvanc1zasIruntheapplicationinJetty).TheservletmaintainsasessionstorethatcontainstheHttpSessioninstances.ThekeystringthattravelsinthevalueoftheJSESSIONIDcookieidentifiestheinstances.WhenanHTTPrequestarrivesattheservlet,thecontainerattachesthesessiontotherequestobjectfromthestore.Ifthereisnosessionforthekey,thenoneiscreated,andthecodecanaccessthesessionobjectbycallingtherequest.getSession()method.

AHttpSessionobjectcanstoreattributes.TheprogramcancallthesetAttribute(String,Object),getAttribute(String),andremoveAttribute(String)methodstostore,retrieve,ordeleteanattributeobject.EachattributeisassignedtoaStringandcanbeanyObject.

AlthoughthesessionattributestoreessentiallylooksassimpleasaMap<String,?>object,itisnot.Thevaluesstoredinthesessioncanbemovedfromonenodetoanotherwhentheservletcontainerrunsinaclusteredorotherdistributedenvironment.Todothat,thevaluesareserialized;therefore,thevaluesstoredinthesessionshouldbeSerializable.Failingtodosoisaverycommonnoviceerror.Duringdevelopment,executingthecodeinasimpledevelopmentTomcatorJettycontainerpracticallyneverserializesthesessiontodiskandneverloadsitfromtheserializedform.ThismeansthatthevaluessetusingsetAttributewillbeavailablebycallinggetAttribute.Werunintotroublethefirsttimetheapplicationgetsinstalledinaclusteredenvironment.AssoonasaHTTPrequestarrivesondifferentnodesgetAttributemayreturnnull.ThemethodsetAttributeiscalledononenodeandduringtheprocessingofthenextrequestgetAttributeonadifferentnodecannotdeserializetheattributevaluefromthedisksharedamongthenodes.Thisisusually,andsadly,theproductionenvironment.

You,asadeveloper,shouldalsobeawarethatserializingandde-serializinganobjectisaheavyoperationthatcostsseveralCPUcycles.IfthestructureoftheapplicationusesonlyapartoftheclientstateservingmostoftheHTTPrequests,thenthisisawasteofCPUtocreatethewholestateinmemoryfromaserializedformandthenserializingitagain.Insuchcases,itismoreadvisabletostoreonlyakeyinthesessionandusesomedatabase(SQLorNoSQL)orsomeotherservicetostoretheactualdatareferencedbythekey.Enterpriseapplicationsalmostexclusivelyusethisstructure.

Page 507:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

packagepackt.java9.by.example.mastermind.servlet;<br/><br/>importpackt.java9.by.example.mastermind.Color;<br/>importpackt.java9.by.example.mastermind.Table;<br/><br/>importjavax.inject.Inject;<br/>importjavax.inject.Named;<br/><br/>publicclassHtmlTools{<br/>@Inject<br/>Tabletable;<br/><br/>@Inject<br/>@Named("nrColumns")<br/>privateintNR_COLUMNS;<br/><br/>publicStringtag(StringtagName,String...attributes){<br/>StringBuildersb=newStringBuilder();<br/>sb.append("<").append((tagName));<br/>for(inti=0;i<attributes.length;i+=2){<br/>sb.append("").<br/>append(attributes[i]).<br/>append("=\"").<br/>append(attributes[i+1]).<br/>append("\"");<br/>}<br/>sb.append(">");<br/>returnsb.toString();<br/>}<br/><br/>publicStringinputBox(Stringname,Stringvalue){<br/>returntag("input","type","text","name",name,"value",value,"size","1");<br/>}<br/><br/>publicStringcolorToHtml(Colorcolor,introw,intcolumn){<br/>returntag("input","type","hidden","name",paramNameGuess(row,column),<br/>"value",color.toString())+<br/>tag("div","class","color"+color)+<br/>tag("/div")+<br/>tag("div","class","spacer")+<br/>tag("/div");<br/>}<br/><br/><br/>publicStringparamNameFull(introw){<br/>return"full"+row;<br/>}<br/><br/>publicStringparamNamePartial(introw){<br/>return"partial"+row;<br/>}<br/><br/>publicStringparamNameGuess(introw,intcolumn){<br/>return"guess"+row+column;<br/>}<br/><br/>publicStringtableToHtml(){<br/>StringBuildersb=newStringBuilder();<br/>sb.append("<html><head>");<br/>sb.append("<linkrel=\"stylesheet\"type=\"text/css\"href=\"colors.css\">");<br/>sb.append("<title>Mastermindguessing</title>");<br/>sb.append("<body>");<br/>sb.append(tag("form","method","POST","action","master"));<br/><br/>for(introw=0;row<table.nrOfRows();row++){<br/>for(intcolumn=0;column<NR_COLUMNS;column++){<br/>sb.append(colorToHtml(table.getColor(row,column),row,column));<br/>}<br/><br/>sb.append(inputBox(paramNameFull(row),""+table.getFull(row)));<br/>sb.append(inputBox(paramNamePartial(row),""+table.getPartial(row)));<br/>sb.append("<p>");<br/>}<br/>returnsb.toString();<br/>}<br/>}

<html><br/><head><br/><linkrel="stylesheet"type="text/css"href="colors.css"><br/><title>Mastermindguessing</title><br/><body><br/><formmethod="POST"action="master"><br/><inputtype="hidden"name="guess00"value="3"><br/><divclass="color3"></div><br/><divclass="spacer"></div><br/><inputtype="hidden"name="guess01"value="2"><br/><divclass="color2"></div><br/><divclass="spacer"></div><br/><inputtype="hidden"name="guess02"value="1"><br/><divclass="color1"></div><br/><divclass="spacer"></div><br/><inputtype="hidden"name="guess03"value="0"><br/><divclass="color0"></div><br/><divclass="spacer"></div><br/><inputtype="text"<br/>name="full0"value="0"size="1">

Page 508:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

<br/><inputtype="text"<br/>name="partial0"value="2"size="1"><br/><p><br/><inputtype="hidden"name="guess10"value="5"><br/><divclass="color5"></div><br/><br/>...deletedcontentthatjustlooksalmostthesame...<br/><br/><p><br/><inputtype="submit"value="submit"><br/></form><br/></body><br/></head><br/></html>

.color0{<br/>background:red;<br/>width:20px;<br/>height:20px;<br/>float:left<br/>}<br/>.color1{<br/>background-color:green;<br/>width:20px;<br/>height:20px;<br/>float:left<br/>}<br/>....color2to.color5isdeleted,contentisthesameexceptdifferentcolors...<br/><br/>.spacer{<br/>background-color:white;<br/>width:10px;<br/>height:20px;<br/>float:left<br/>}

Page 509:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 510:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

DependencyinjectionwithGuiceTheservletclassisverysimpleasshowninthefollowing:

packagepackt.java9.by.example.mastermind.servlet;

importcom.google.inject.Guice;

importcom.google.inject.Injector;

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

importjavax.servlet.ServletException;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjava.io.IOException;

publicclassMastermindextendsHttpServlet{

privatestaticfinalLoggerlog=LoggerFactory.getLogger(Mastermind.class);

publicvoiddoGet(HttpServletRequestrequest,

HttpServletResponseresponse)

throwsServletException,IOException{

doPost(request,response);

}

publicvoiddoPost(HttpServletRequestrequest,

HttpServletResponseresponse)

throwsServletException,IOException{

Injectorinjector=

Guice.createInjector(newMastermindModule());

MastermindHandlerhandler=

injector.getInstance(MastermindHandler.class);

handler.handle(request,response);

}

}

Becausemanythreadsuseservletsconcurrently,andthuswecannotuseinstancefieldsholdingdataforasinglehit,theservletclassdoesnothingelsebutcreateanewinstanceofaMastermindHandlerclassandinvokeitshandlemethod.SincethereisanewinstanceofMastermindHandlerforeachrequest,itcanstoreobjectsinfieldsspecifictotherequest.Tocreateahandler,weusetheGuicelibrarycreatedbyGoogle.

Wehavealreadytalkedaboutdependencyinjection.ThehandlerneedsaTableobjecttoplay,aColorManagerobjecttomanagethecolors,andaGuesserobjecttocreateanewguess,butcreatingtheseorfetchingsomeprefabricatedinstancesfromsomewhereisnotthecorefunctionalityofthehandler.Thehandlerhastodoonething:handletherequest;theinstancesneededtodothisshouldbeinjectedfromoutside.ThisisdonebyaGuiceinjector.

TouseGuice,wehavetolistthelibraryamongthedependenciesinbuild.gradle:

applyplugin:'java'

applyplugin:'jetty'

repositories{

jcenter()

}

dependencies{

providedCompile"javax.servlet:javax.servlet-api:3.1.0"

testCompile'junit:junit:4.12'

compile'org.slf4j:slf4j-api:1.7.7'

compile'ch.qos.logback:logback-classic:1.0.11'

compile'com.google.inject:guice:4.1.0'

Page 511:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

}

jettyRun{

contextPath'/hello'

}

Thenwehavetocreateaninjectorinstancethatwilldotheinjection.Theinjectoriscreatedwiththefollowinglineintheservlet:

Injectorinjector=Guice.createInjector(newMastermindModule());

TheinstanceofMastermindModulespecifieswhattoinjectwhere.ThisisessentiallyaconfigurationfileintheJavaformat.Otherdependencyinjectorframeworksused,anduse,XMLandannotationstodescribetheinjectionbindingandwhattoinjectwhere,butGuicesolelyusesJavacode.ThefollowingistheDIconfigurationcode:

publicclassMastermindModuleextendsAbstractModule{

@Override

protectedvoidconfigure(){

bind(int.class)

.annotatedWith(Names.named("nrColors")).toInstance(6);

bind(int.class)

.annotatedWith(Names.named("nrColumns")).toInstance(4);

bind(ColorFactory.class).to(LetteredColorFactory.class);

bind(Guesser.class).to(UniqueGuesser.class);

}

}

ThemethodsusedintheconfiguremethodarecreatedinafluentAPImannersothatthemethodscanbechainedoneaftertheotherandthatthecodecanbereadalmostlikeEnglishsentences.AgoodintroductiontofluentAPIcanbefoundathttps://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/.Forexample,thefirstconfigurationlinecouldbereadinEnglishas

Bindtotheclassintwhereveritisannotatedwiththe@Nameannotationhavingvalue"nrColor"totheinstance6.

(Notethattheintvalue6isautoboxedtoanIntegerinstance.)

TheMastermindHandlerclasscontainsfieldsannotatedwith@Injectannotation:

@Inject

@Named("nrColors")

privateintNR_COLORS;

@Inject

@Named("nrColumns")

privateintNR_COLUMNS;

@Inject

privateHtmlToolshtml;

@Inject

Tabletable;

@Inject

ColorManagermanager;

@Inject

Guesserguesser;

ThisannotationisnotGuice-specific.@Injectisapartofthejavax.injectpackageandisastandardpartofJDK.JDKdoesnotprovidethedependencyinjector(DI)frameworkbutsupportsthedifferentframeworkssothattheycanusestandardJDKannotations,andincasetheDIframeworkisreplaced,theannotationsmayremainthesameandnotframework-specific.

Page 512:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhentheinjectoriscalledtocreateaninstanceofMastermindHandler,itlooksattheclassandseesthatithasanintfieldannotatedwith@Injectand@Named("nrColors"),andfindsintheconfigurationthatsuchafieldshouldhavethevalue6.ItinjectsthevaluetothefieldbeforereturningtheMastermindHandlerobject.Similarly,italsoinjectsthevaluesintotheotherfields,andifitshouldcreateanyoftheobjectstobeinjected,itdoes.Iftherearefieldsintheseobjects,thentheyarealsocreatedbyinjectingotherobjectsandsoon.

ThiswaytheDIframeworkremovestheburdenfromtheprogrammers'shouldertocreatetheinstances.Thisissomethingfairlyboringandisnotthecorefeatureoftheclassesanyway.Instead,itcreatesalltheobjectsneededtohaveafunctionalMastermindHandlerandlinksthemtogetherviatheJavaobjectreferences.Thisway,thedependenciesofthedifferentobjects(MastermindHandlerneedsGuesser,ColorManager,andTable;ColorManagerneedsColorFactory;andTablealsoneedsColorManager,andsoon)becomeadeclaration,specifiedusingannotationsonthefields.Thesedeclarationsareinsidethecodeoftheclasses,anditistherightplaceforthem.Whereelsecouldwespecifywhattheclassneedstoproperlyfunctionthanintheclassitself?

TheconfigurationinourexamplespecifiesthatwhereverthereisaneedforColorFactory,wewilluseLetteredColorFactory,andthatwhereverweneedGuesser,wewilluseUniqueGuesser.Thisisseparatedfromthecodeandithastobelikethat.Ifwewanttochangetheguessingstrategy,wereplacetheconfigurationandthecodeshouldworkwithoutmodifyingtheclassesthatusetheguesser.

GuiceiscleverenoughandyouneednotspecifythatwhereverthereisaneedforTable,wewilluseTable:thereisnobind(Table.class).to(Table.class).FirstIcreatedalinelikethatintheconfiguration,butGuicerewardedmewithanerrormessage,andnow,writingitagaininplainEnglish,Ifeelreallystupid.IfIneedatableIneedatable.Really?

Page 513:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 514:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheMastermindHandlerclassWehavealreadystartedthelistingoftheMastermindHandlerclass,andsincethisclassismorethanahundredlines,Iwillnotincludeithereasawhole.Themostimportantmethodofthisclassishandle:

publicvoidhandle(HttpServletRequestrequest,

HttpServletResponseresponse)

throwsServletException,IOException{

Gamegame=buildGameFromRequest(request);

GuessnewGuess=guesser.guess();

response.setContentType("text/html");

PrintWriterout=response.getWriter();

if(game.isFinished()||newGuess==Guess.none){

displayGameOver(out);

}else{

log.debug("Addingnewguess{}tothegame",newGuess);

game.addGuess(newGuess,0,0);

displayGame(out);

}

bodyEnd(out);

}

Weperformthreesteps.Step1iscreatingthetableandwedoitfromtherequest.Ifthisisnotthestartofthegame,thereisalreadyatableandtheHTMLformcontainsallpreviousguesscolorsandtheanswerstothose.Then,asthesecondstep,wecreateanewguessbasedonthat.Step3istosendthenewHTMLpagetotheclient.

Again,thisisnotamodernapproach,creatingHTMLontheservletcode,butdemonstratingpureservletfunctionalitywithREST,JSON,andJavaScriptwithsomeframeworkwouldmakethischapteraloneafewhundredpageslong,anditwoulddefinitelydistractourfocusfromJava.

PrintingHTMLtexttoaPrintWriterisnotsomethingthatshouldbenewtoyouatthispointinthisbook;therefore,wewillnotlistthatcodehere.YoucandownloadtheworkingexampleonGitHub.Thebranchforthisversionofthecodeisnosession.Insteadofprinting,wewillfocusontheservletparameterhandling.

TherequestparametersareavailableviathegetParametermethod,whichreturnsthestringvalueofaparameter.Thismethodassumesthatanyparameter,beitGETorPOST,appearsonlyonceintherequest.Incasethereareparametersthatappearmultipletimes,thevalueshouldhavebeenastringarray.Insuchacase,weshouldusegetParameterMap,whichreturnsthewholemapwiththeStringkeysandString[]values.Eventhoughwedonothavemultiplevaluesforanykeythistime,andwealsoknowthevaluesofthekeyscomingasPOSTparameters,wewillstillusethelattermethod.Thereasonforthisisthatwewilllaterusethesessiontostorethesevalues,andwewanttohaveamethodthatisreusableinthatcase.

IfyoulookattheearliercommitsintheGitrepository,youwillseethatthefirstversionusedgetParameterandIrefactoreditonlylaterwhenIcreatedthesecondversionoftheprogram,whichstoresthestateinasession.Neverbelieveifanyonetellsyouthatprogramsarecreatedperfectlyupfrontwithoutanyrefactoringduringdevelopment.Donotfeelashamedtocreatefoolishcodeandrefactoritlater.Itisonlyshamefulifyoudonotrefactorit.

Page 515:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Togettothatweconverttherequest'sMap<String,String[]>toMap<String,String>:

privateGamebuildGameFromRequest(HttpServletRequestrequest){

returnbuildGameFromMap(toMap(request));

}

privateMap<String,String>toMap(HttpServletRequestrequest){

log.debug("convertingrequesttomap");

returnrequest.getParameterMap().entrySet().

stream().collect(

Collectors.toMap(

Map.Entry::getKey,

e->e.getValue()[0]));

}

Then,weusethatmaptore-createthegame:

privateGamebuildGameFromMap(Map<String,String>params){

finalGuesssecret=newGuess(newColor[NR_COLUMNS]);

finalGamegame=newGame(table,secret);

for(introw=0;

params.containsKey(html.paramNameGuess(row,0));

row++){

Color[]colors=getRowColors(params,row);

Guessguess=newGuess(colors);

finalintfull=Integer.parseInt(params.get(html.paramNameFull(row)));

finalintpartial=Integer.parseInt(params.get(html.paramNamePartial(row)));

log.debug("Addingguesstogame");

game.addGuess(guess,full,partial);

}

returngame;

}

TheconversionfromStringtointisdoneviathemethodparseInt.ThismethodthrowsNumberFormatExceptionwhentheinputisnotanumber.Trytorunthegame,usethebrowser,andseehowJettyhandlesthecasewhentheservletthrowsanexception.Howmuchvaluableinformationdoyouseeinthebrowserthatcanbeusedbyapotentialhacker?Fixthecodesothatitaskstheuseragainifanyofthenumbersarenotwellformatted!

Page 516:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 517:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

StoringstateontheserverTheapplicationstateshouldusuallynotbesavedontheclient.Theremaybesomespecialcaseinadditiontotheonewhereyouwriteeducationalcodeandwanttodemonstratehowtodoit.Generally,thestateoftheapplicationrelatedtotheactualuseisstoredinthesessionobjectoronsomedatabase.Thisisespeciallyimportantwhentheapplicationrequeststheusertoenteralotofdataanddoesnotwanttheusertolosetheworkifthereissomehiccupintheclientcomputer.

Youspendalotoftimeselectingtheappropriateitemsinanonlineshop,choosingtheappropriateitemsthatworktogether,creatingaconfigurationofyournewmodelairplane,andallofasudden,thereisablackoutinyourhome.Ifthestatewerestoredontheclientyou'dhavehadtostartfromscratch.Ifthestateisstoredontheserver,thestateissavedtodisk;theserversareduplicated,fedbybattery-backedpowersupplies,andwhenyourebootyourclientmachinewhenthepowercomesbackinyourhome,youlogin,andmiraculously,theitemsareallthereinyourshoppingbasket.Well,itisnotamiracle;itiswebprogramming.

Inourcase,thesecondversionwillstorethestateofthegameinthesession.Thiswilllettheuserhavethegamerestoresolongasthesessionisthere.Iftheuserquitsandrestartsthebrowser,thesessiongetslostandanewgamecanstart.

Sincethereisnoneedtosendtheactualcolorsandmatchinginhiddenfieldsthistime,theHTMLgenerationismodifiedabit,andthegeneratedHTMLwillalsobesimpler:

<html>

<head>

<linkrel="stylesheet"type="text/css"href="colors.css">

<title>Mastermindguessing</title>

<body>

<formmethod="POST"action="master">

<divclass="color3"></div>

<divclass="spacer"></div>

<divclass="color2"></div>

<divclass="spacer"></div>

<divclass="color1"></div>

<divclass="spacer"></div>

<divclass="color0"></div>

<divclass="spacer"></div>0

<divclass="spacer"></div>2<p>

<divclass="color5"></div>

...

<divclass="spacer"></div>

<divclass="color1"></div>

<divclass="spacer"></div>

<inputtype="text"name="full2"value="0"size="1"><inputtype="text"name="partial2"value="0"size="1">

<p>

<inputtype="submit"value="submit">

</form>

</body>

</head></html>

Thenumberoffullandpartiallymatchingcolorsisdisplayedasasimplenumber,sothisversiondoesnotallowcheatingorchangingpreviousresults.(Thesearethenumbers0and2afterthedivtagsthathavetheCSSclassspacer.)

ThehandlemethodinMastermindHandleralsochanges,asshowninthefollowing:

Page 518:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

publicvoidhandle(HttpServletRequestrequest,

HttpServletResponseresponse)

throwsServletException,IOException{

Gamegame=buildGameFromSessionAndRequest(request);

GuessnewGuess=guesser.guess();

response.setContentType("text/html");

PrintWriterout=response.getWriter();

if(game.isFinished()||newGuess==Guess.none){

displayGameOver(out);

}else{

log.debug("Addingnewguess{}tothegame",newGuess);

game.addGuess(newGuess,0,0);

sessionSaver.save(request.getSession());

displayGame(out);

}

bodyEnd(out);

}

ThisversionoftheclassgetsaSessionSaverobjectinjectedbytheGuiceinjector.Thisisaclassthatwecreate.ThisclasswillconvertthecurrentTableintosomethingthatisstoredinthesession,anditalsorecreatesthetablefromthedatastoredinthesession.ThehandlemethodusesthebuildGameFromSessionAndRequestmethodtorestorethetableandtoaddthefullandpartialmatchanswersthattheuserjustgaveintherequest.Whenthemethodcreatesanewguessandfillsitinthetable,andalsosendsittotheclientintheresponse,itsavesthestateinthesessionbycallingthesavemethodviathesessionSaverobject.

ThebuildGameFromSessionAndRequestmethodreplacestheotherversion,whichwenamedbuildGameFromRequest:

privateGamebuildGameFromSessionAndRequest(HttpServletRequestrequest){

Gamegame=buildGameFromMap(sessionSaver.restore(request.getSession()));

Map<String,String>params=toMap(request);

introw=getLastRowIndex(params);

log.debug("lastrowis{}",row);

if(row>=0){

finalintfull=Integer.parseInt(params.get(html.paramNameFull(row)));

finalintpartial=Integer.parseInt(params.get(html.paramNamePartial(row)));

log.debug("settingfull{}andpartial{}forrow{}",full,partial,row);

table.setPartial(row,partial);

table.setFull(row,full);

if(full==table.nrOfColumns()){

game.setFinished();

}

}

returngame;

}

NotethatthisversionhasthesameillnessofusingtheparseIntmethodfromtheIntegerclassinJDK,whichthrowsanexception.

Page 519:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 520:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheGameSessionSaverclassThisclasshasthreepublicmethods:

save:Thissavesatabletotheusersessionrestore:Thisgetsatablefromtheusersessionreset:Thisdeletesanytablethatmaybeinthesession

Thecodeoftheclassisthefollowing:

publicclassGameSessionSaver{

privatestaticfinalStringSTATE_NAME="GAME_STATE";

@Inject

privateHtmlToolshtml;

@Inject

Tabletable;

@Inject

ColorManagermanager;

publicvoidsave(HttpSessionsession){

Map<String,String>params=convertTableToMap();

session.setAttribute(STATE_NAME,params);

}

publicvoidreset(HttpSessionsession){

session.removeAttribute(STATE_NAME);

}

publicMap<String,String>restore(HttpSessionsession){

Map<String,String>map=

(Map<String,String>)

session.getAttribute(STATE_NAME);

if(map==null){map=newHashMap<>();}

returnmap;

}

privateMap<String,String>convertTableToMap(){

Map<String,String>params=newHashMap<>();

for(introw=0;row<table.nrOfRows();row++){

for(intcolumn=0;

column<table.nrOfColumns();column++){

params.put(html.paramNameGuess(row,column),

table.getColor(row,column).toString());

}

params.put(html.paramNameFull(row),

""+table.getFull(row));

params.put(html.paramNamePartial(row),

""+table.getPartial(row));

}

returnparams;

}

}

Whenwesavethesessionandconvertthetabletoamap,weuseaHashMap.Theimplementationinthiscaseisimportant.TheHashMapclassimplementstheSerializableinterface;therefore,wecanbesafeputtingittothesession.ThisalonedoesnotguaranteethateverythinginHashMapisSerializable.ThekeysandthevaluesinourcaseareStrings,andfortunately,theStringclassalsoimplementstheSerializableinterface.Thisway,theconvertedHashMapobjectcanbesafelystoredinthesession.

Alsonotethat,althoughserializationcanbeslow,storingHashMapinasessionissofrequentthatitimplementsitsownserializationmechanism.Thisimplementationisoptimizedandavoidsserializationbeingdependentontheinternalstructureofthemap.

Page 521:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ItistimetothinkaboutwhywehavetheconvertTableToMapmethodinthisclassandbuildGameFromMapinMastermindHandler.ConvertingthegameandthetableinittoaMapandtheotherwayroundshouldbeimplementedtogether.Theyarejusttwodirectionsofthesameconversion.Ontheotherhand,theimplementationoftheTabletoMapdirectionshoulduseaMapversionthatisSerializable.Thisisverymuchrelatedtosessionhandling.ConvertingaMapobject,ingeneral,toaTableobjectisonelevelhigher,restoringthetablefromwhereveritwasstored:client,session,database,orinthemoistureofthecloud.Sessionstorageisonlyonepossibleimplementation,andmethodsshouldbeimplementedintheclassthatmeetstheabstractionlevel.Thebestsolutioncouldbetoimplementtheseinaseparateclass.Youhavehomework!

Theresetmethodisnotusedfromthehandler.ThisisinvokedfromtheMastermindclass,thatis,theservletclasstoresetthegamewhenwestartit:

publicvoiddoGet(HttpServletRequestrequest,

HttpServletResponseresponse)

throwsServletException,IOException{

GameSessionSaversessionSaver=newGameSessionSaver();

sessionSaver.reset(request.getSession());

doPost(request,response);

}

Withoutthis,playingthegameagainstthemachineoncewouldjustdisplaythefinishedgameeverytimewewanttostartitagain,untilweexitthebrowserandrestartitorexplicitlydeletetheJSESSIONIDcookiesomewhereintheadvancedmenuofthebrowser.Callingresetdoesnotdeletethesession.Thesessionremainsthesame,andthusthevalueofJSESSIONIDtoo,butthegameisdeletedfromthesessionobjectthattheservletcontainermaintains.

Page 522:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 523:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RunningtheJettywebservletSincewehaveincludedtheJettypluginintoourGradlebuild,thetargetsofthepluginareavailable.TostartJettyisaseasyastypingthefollowing:gradlejettyRun

Thiswillcompilethecode,buildtheWARfile,andstarttheJettyservletcontainer.Tohelpusremember,italsoprintsthefollowingonthecommandline:Runningathttp://localhost:8080//hello

WecanopenthisURLandseetheopeningscreenofthegamewiththecolorsthattheprogramcreatedasafirstguess:

Nowitistimetohavesomefunandplaywithourgame,givinganswerstotheprogram.Donotmakeit

easyforthecode!Refertothefollowingscreenshot:

Atthesametime,ifyoulookattheconsolewhereyouhavetypedgradlejettyRun,youwillseethatthecodeisprintingoutlogmessages,asshowninthefollowingscreenshot:

Theseprintoutscomethroughtheloggerthatwehaveinourcode.Inthepreviouschapters,weusedtheSystem.out.printlnmethodcallstosendinformationalmessagestotheconsole.Thisisapracticethatshouldnotbefollowedinanyprogramthatismorecomplexthanahelloworld

Page 524:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 525:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Logging

ThereareseveralloggingframeworksavailableforJavaandeachhasadvantagesanddisadvantages.ThereisonebuiltintoJDKinthejava.util.loggingpackageandaccessingtheloggerissupportedbytheSystem.getLoggermethod:theSystem.LoggerandSystem.LoggerFinderclasses.Eventhoughjava.util.logginghasbeenavailableinJavasinceJDK1.4,alotofprogramsuseotherloggingsolutions.Inadditiontothebuilt-inlogging,wehavetomentionlog4j,slf4jandApacheCommonsLogging.Beforegettingintothedetailsofthedifferentframeworks,let'sdiscusswhyitisimportanttouselogginginsteadofjustprintingtothestandardoutput.

Page 526:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 527:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ConfigurabilityThemostimportantreasonisconfigurabilityandeaseofuse.Weuseloggingtorecordinformationabouttheoperationofcode.Thisisnotthecorefunctionalityoftheapplicationbutisinevitabletohaveaprogramthatcanbeoperated.Therearemessagesweprintouttothelog,whichcanbeusedbytheoperatingpersonneltoidentifyenvironmentalissues.Forexample,whenanIOExceptionisthrownanditgetslogged,theoperationmaylookatthelogsandidentifythatthediskgotfull.Theymaydeletefiles,oraddanewdiskandextendthepartition.Withoutthelogs,theonlyinformationwouldbethattheprogramdoesnotwork.

Thelogsarealsousedmanytimestohuntdownbugs.Someofthebugsdonotmanifestinthetestenvironmentandareverydifficulttoreproduce.Insuchacase,thelogsthatprintoutdetailedinformationabouttheexecutionofthecodearetheonlysourceoffindingtherootcauseofsomeerror.

SinceloggingneedsCPU,IObandwidth,andotherresources,itshouldbecarefullyexaminedwhatandwhentolog.Thisexaminationandthedecisionscouldbedoneduringprogramming,andasamatteroffact,thatistheonlypossibilityifweusedSystem.out.printlnforlogging.Ifweneedtofindabug,weshouldlogalot.Ifwelogalot,theperformanceofthesystemwillgodown.Theconclusionisthatwehavetologonlyifitisneeded.Ifthereisabuginthesystemthatcannotbereproduced,thedevelopersasktheoperationtoswitchondebugloggingforashortperiod.SwitchingonandoffdifferentpartsofloggingisnotpossiblewhenSystem.out.printlnisused.Whenthedebuglevellogisswitchedon,theperformancemaygodownforawhile,butatthesametime,thelogsbecomeavailableforanalysis.Atthesametime,theanalysisissimplerwhenwehavetofindtheloglinesthatarerelevant(andyoudonotknowbeforehandwhicharerelevant)ifthereisasmall(afewhundredmegabyteslogfile)ratherthanalotof2-GBcompressedlogfilestofindthelinesin.

Usingalogframework,youcandefineloggersthatidentifythesourceofthelogmessagesandloglevels.Astringusuallyidentifiesthelogger,anditisacommonpracticetousethenameoftheclassfromwhichthelogmessageiscreated.Thisissuchacommonpracticethatthedifferentlogframeworksprovidefactoryclassesthatgettheclassitself,insteadofitsname,togetalogger.

Thepossiblelogginglevelsmaybeslightlydifferentindifferentloggingframeworks,butthemostimportantlevelsareasfollows:

FATAL:Thisisusedwhenthelogmessageisaboutsomeerrorthatpreventstheprogramfromcontinuingitsexecution.ERROR:Thisisusedwhenthereissomesevereerror,buttheprogramcanstillgoonfunctioningalthough,probably,insomelimitedmanner.WARNING:Thisisusedwhenthereissomeconditionthatisnotadirectproblembutmaylaterleadtoanerrorifnotattended.Forexample,theprogramrecognizesthatadiskisnearfull,somedatabaseconnectionsanswerwithinlimitsbutclosetothetimeoutvalue,andsimilarsituations.INFO:Thisisusedtocreatemessagesaboutnormaloperationsthatmaybeinterestingtooperateandarenotanerrororwarning.Thesemessagesmayhelptheoperationtodebugtheoperationalenvironmentsettings.DEBUG:Thisisusedtologinformationabouttheprogramthatisdetailedenough(hopefully)tofinda

Page 528:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

buginthecode.Thetrickisthatwhenweputthelogstatementintothecode,wedonotknowwhatbugitcouldbe.Ifweknew,webetterfixedit.TRACE:Thisisevenmoredetailedinformationabouttheexecutionofthecode.

Thelogframeworksareusuallyconfiguredusingsomeconfigurationfile.Theconfigurationmaylimitthelogging,switchingoffcertainlevels.Inanormaloperationalenvironment,thefirstthreelevelsareusuallyswitchedon,andINFO,DEBUG,andTRACEareswitchedonwhenreallyneeded.Itisalsopossibletoswitchonandoffcertainlevelsonlyforcertainloggers.IfweknowthattheerroriscertainlyintheGameSessionSaverclass,thenwecanswitchontheDEBUGlevelonlyforthatclass.

Logfilesmayalsocontainotherinformationthatwedidnotdirectlycodeandwouldbeverycumbersometoprinttothestandardoutput.Usually,eachlogmessagecontainstheprecisetimewhenthemessagewascreated,thenameofthelogger,and,manytimes,theidentifierofthethread.Imagineifyouwereforcedtoputallthistoeachandeveryprintlnargument;youwouldprobablysoonwritesomeextraclasstodothat.Don't!Ithasalreadybeendoneprofessionally:itistheloggerframework.

Loggerscanalsobeconfiguredtosendthemessagetodifferentlocations.Loggingtotheconsoleisonlyonepossibility.Loggingframeworksarepreparedtosendmessagestofiles,database,WindowsEventRecorder,syslogservice,ortoanyothertarget.Thisflexibility,whichmessagetoprint,whatextrainformationtoprint,andwheretoprintisreachedbyseparatingthedifferenttasksthattheloggerframeworkdoesintoseveralclassesfollowingthesingleresponsibilityprinciple.

Theloggerframeworksusuallycontainloggersthatcreatethelogs,formattersthatformatthemessagefromtheoriginalloginformation,manytimes,addinginformationsuchasthreadIDandtimestamp,andappendersthatappendtheformattedmessagetosomedestination.Theseclassesimplementinterfacesdefinedintheloggingframeworkandnothingbutthesizeofthebookstopsusfromcreatingourownformattersandappenders.

Whenalogisconfigured,theappendersandformattersareconfigured,giventheclassthatimplementsthem.Therefore,whenyouwanttosendsomelogstosomespecialdestination,youarenotlimitedtotheappendersthatareprovidedbytheauthorsoftheframework.Therearealotofindependentopen-sourceprojectsfordifferentloggingframeworksprovidingappendersfordifferenttargets.

Page 529:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 530:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PerformanceThesecondreasontousealoggingframeworkisperformance.Althoughitisnotgoodtooptimizeforperformancebeforeweprofilethecode(prematureoptimization),usingsomemethodologyknowntobeslowandinsertingseverallinesintoourperformance-criticalcode,invokingslowmethodsisnotreallyprofessionaleither.Usingawell-established,highlyoptimizedframeworkinawaythatisindustrybestpracticeshouldnotbequestionable.

UsingSystem.out.printlnsendsthemessagetoastreamandreturnsonlywhentheIOoperationisdone.Usingreallogginghandlestheinformationtotheloggerandletstheloggerdotheloggingasynchronously,anditdoesnotwaitforcompletion.Itisreallyadrawbackthatloginformationmaybelostifthereissomesystemfailure,butthisisusuallynotaseriousissueconsideringhowrarelythathappensandwhatisontheothersideofthewage:performance.Whatdoweloseifthereisamissingdebugloglinewhenthediskgotfull,anywayrenderingthesystemunusable?

Thereisoneexceptiontothis:auditlogging—whensomeloginformationaboutthetransactionsofthesystemhastobesavedforlegalreasonssothattheoperationandtheactualtransactionscanbeaudited.Insuchacase,theloginformationissavedinatransactionalmanner,makingthelogpartofthetransaction.Becausethatisatotallydifferenttypeofrequirement,auditloggingisnotusuallydonewithanyoftheseframeworks.

Also,System.out.printlnisnotsynchronizedandthatwaydifferentthreadsmayjustgarbletheoutput.Logframeworkspayattentiontothisissue.

Page 531:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 532:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LogframeworksThemostwidelyusedloggingframeworkisApachelog4j.Itcurrentlyhasasecondversionthatisatotalrewriteofthefirstversion.Itisveryversatileandhasmanyappendersandformatters.Theconfigurationoflog4jcanbeinXMLorpropertiesfileformat,anditcanalsobeconfiguredthroughAPI.

Theauthoroflog4jversion1createdanewloggingframework:slf4j.Thislogginglibraryisessentiallyafaçadethatcanbeusedtogetherwithanyotherloggingframework.Thus,whenyouuseslf4jinalibraryyoudevelop,andyourcodeisaddedtoaprogramasadependencythatusesadifferentloggingframework,itiseasytoconfigureslf4jtosendthelogstotheloggersoftheotherframework.Thus,thelogswillbehandledtogetherandnotinseparatefile,whichisdesirabletodecreasethecostofoperation.Whendevelopingyourlibrarycodeoranapplicationthatusesslf4j,thereisnoneedtoselectanotherlogframeworktoslf4j.Ithasitsownsimpleimplementationcalledbacklog.

ApacheCommonsLoggingisalsoafaçadewithitsownloggingimplementationifnothingelsefails.Themajordifferencefromslf4jisthatitismoreflexibleinconfigurationandwhatunderlyingloggingtouse,anditimplementsarun-timealgorithmtodiscoverwhichloggingframeworkisavailableandistobeused.Theindustrybestpracticeshowsthatthisflexibility,whichalsocomeswithhighercomplexityandcost,isnotneeded.

Page 533:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 534:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Java9loggingJava9includesafacadeimplementationforlogging.Theuseisverysimpleandwecanexpectthatloggingframeworkswillverysoonstarttosupportthisfaçade.ThefactthatthisfaçadeisbuiltintotheJDKhastwomajoradvantage:

Thelibrariesthatwanttologdonotneedtohaveanydependencyonanyloggingframeworkorloggingfaçadeanymore.TheonlydependencyistheJDKlogfaçadethatisthereanyway.TheJDKlibrariesthatlogthemselvesusethisfaçadeandthustheywilllogintothesamelogfileastheapplication.

IfweusetheJDK-providedloggingfaçadethestartoftheColorManagerclasswillbechangedtothefollowing:

packagepackt.java9.by.example.mastermind;

importjavax.inject.Inject;

importjavax.inject.Named;

importjavax.inject.Singleton;

importjava.util.HashMap;

importjava.util.Map;

importjava.lang.System.Logger;

importstaticjava.lang.System.Logger.Level.DEBUG;

@Singleton

publicclassColorManager{

protectedfinalintnrColors;

protectedfinalMap<Color,Color>successor=newHashMap<>();

privateColorfirst;

privatefinalColorFactoryfactory;

privatestaticfinalLoggerlog=System.getLogger(ColorManager.class.getName());

@Inject

publicColorManager(@Named("nrColors")intnrColors,

ColorFactoryfactory){

log.log(DEBUG,"creatingcolorManagerfor{0}colors",

nrColors);

Inthisversionwedonotimporttheslf4jclasses.Insteadweimportthejava.lang.System.Loggerclass.

NotethatwedonotneedtoimporttheSystemclass,becausetheclassesfromthejava.langpackageareautomaticallyimported.ThisisnottruefortheclassesthatarenestedclassesintheSystemclass.

TogetaccesstotheloggertheSystem.getLoggerstaticmethodiscalled.Thismethodfindstheactualloggerthatisavailableandreturnsoneforthenamethatwepassasargument.ThereisnoversionofthemethodgetLoggerthatacceptstheclassastheargument.IfwewanttosticktotheconventionthenwehavetowriteColorManager.class.getName()togetthenameoftheclassorwecanwritetherethenameoftheclassasastring.Thesecondapproachhasthedrawbackthatitdoesnotfollowthechangeofthenameoftheclass.IntelligentIDEslikeIntelliJ,Eclipse,orNetbeansrenamethereferencestoclassesautomaticallybuttheyhaveahardtimewhenthenameoftheclassisusedinastring.

TheinterfaceSystem.Loggerdoesnotdeclaretheconveniencemethodserror,debug,warning,andsoon,thatarefamiliarfromotherloggingframeworksandfaçade.Thereisonlyonemethodnamedlogandthefirst

Page 535:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

argumentofthismethodistheleveloftheactuallogweissue.Thereareeightlevelsdefined:ALL,TRACE,DEBUG,INFO,WARNING,ERROR,andOFF.Whencreatingalogmessagewearesupposedtouseoneofthemiddlesixlevels.ALLandOFFaremeanttobepassedtotheisLoggablemethod.Thismethodcanbeusedtocheckiftheactuallogginglevelgetsloggedornot.Forexample,ifthelevelissettoINFOthenmessagessentwithDEBUGorTRACEwillnotbeprinted.

TheactualimplementationislocatedbytheJDKusingtheserviceloaderfunctionality.Thelogimplementationhastobeinamodulethatprovidestheinterfacejava.lang.System.LoggerFinderviasomeimplementation.InotherwordsthemoduleshouldhaveaclassthatimplementstheLoggerFinderinterfaceandthemodule-info.javashoulddeclarewhichclassitisusingthecode:

providesjava.lang.System.LoggerFinderwith

packt.java9.by.example.MyLoggerFinder;

TheMyLoggerFinderclasshastoextendtheLoggerFinderabstractclasswiththemethodgetLogger.

Page 536:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 537:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LoggingpracticeThepracticeofloggingisverysimple.Ifyoudonotwanttospendtoomuchtimeexperimentingwithdifferentloggingsolutionsandyoudonothavesomespecialrequirement,thensimplygowithslf4j,addtheJARtothedependencylistasacompiledependency,andstartusinglogginginthesourcecode.

Sinceloggingisnotinstance-specific,andloggersimplementthreadsafety,thelogobjectsthatweusuallyusearestoredinastaticfield,andsincetheyareusedaslongastheclassisused,theprogramrunningthefieldisalsofinal.Forexampleusingtheslf4jfaçadewecangetaloggerwiththefollowingcommand:privatestaticfinalLoggerlog=LoggerFactory.getLogger(MastermindHandler.class);

Togetthelogger,theloggerfactoryisused,whichjustcreatestheloggerorreturnstheonethatisalreadyavailable.

Thenameofthevariableisusuallylogorlogger,butdonotbesurprisedifyouseeLOGorLOGGER.Thereasonforuppercasingthenameofthevariableisthatsomestaticcodeanalysischeckerstreatstaticfinalvariablesasconstants,astheyreallyare,andtheconventionintheJavacommunityistouseuppercasenamesforsuchvariables.Itisamatteroftaste;manytimeslogandloggerareusedinlowercase.

Tocreatealogitemthemethodstrace,debug,info,warn,anderrorcreateamessagewiththerespectivelevelasthenameimplies.Forexample,considerthefollowingline:

log.debug("Addingnewguess{}tothegame",newGuess);

Itcreatesadebugmessage.Slf4jhassupportforformattingusingthe{}literalinsidestrings.Thisway,thereisnoneedtoappendthestringfromsmallparts,andincasetheactuallogitemisnotsenttothelogdestination,theformattingwillnotperform.IfweuseStringconcatenationinanyformtopassastringasanargument,thentheformattingwillhappenevenifdebugloggingisnotdesiredaspertheexample.

Theloggingmethodsalsohaveaversionthatgetsonlytwoarguments:aStringmessageandThrowable.Inthiscase,theloggingframeworkwilltakecareoftheoutputoftheexceptionandthestacktracealongwithit.Ifyoulogsomethinginexceptionhandlingcode,logtheexceptionandlettheloggerformatit.

Page 538:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 539:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

OthertechnologiesWediscussedtheservlettechnology,abitofJavaScript,HTML,andCSS.Whenprogramminginarealprofessionalenvironment,thesetechnologiesaregenerallyused.Thecreationoftheuserinterfaceofapplications,however,wasnotalwaysbasedonthesetechnologies.Olderoperatingsystem-nativeGUIapplicationsaswellasSwing,AWT,andSWTuseadifferentapproachtocreateUI.TheybuilduptheUIfacingtheuserfromprogramcode,andtheUIisbuiltasahierarchicalstructureofcomponents.Whenwebprogrammingstarted,Javadevelopershadexperiencewithtechnologiesliketheseandprojectscreatedframeworksthattriedtohidethewebtechnologylayer.

OnetechnologyworthmentioningisGoogleWebToolkit,whichimplementstheserveraswellasthebrowsercodeinJava,butsincethereisnoJavaenvironmentimplementedinthebrowsers,ittranspiles(converts)theclientpartofthecodefromJavatoJavaScript.Thelastreleaseofthetoolkitwascreatedtwoyearsagoin2014andsincethenGooglehasreleasedothertypesofwebprogrammingtoolkitsthatsupportnativeJavaScript,HTML,andCSSclientdevelopment.

Vaadinisalsoatoolkitthatyoumaycomeacross.ItletsyouwriteGUIcodeontheserverinJava.ItisbuiltontopofGWTandiscommerciallysupported.ItmaybeagoodchoiceincasetherearedevelopersavailablewhohaveexperiencewithGUIdevelopmentinJavabutnotinwebnativetechnologies,andtheapplicationdoesnotrequirespecialusabilitytuningontheclientside.Atypicalintranetcorporateapplicationcanselectitasatechnology.

JavaServerFaces(JSF)isatechnologythattriestooffloadtheclient-sidedevelopmentoftheapplicationfromthedevelopersprovidingwidgetsreadytobeusedandtheserverside.ItisacollectionofseveralJavaSpecificationRequests(JSR)andthereareseveralimplementations.ThecomponentsandtheirrelationsareconfiguredinXMLfilesandtheservercreatestheclientnativecode.Inthistechnology,thereisnotranspilationfromJavatoJavaScript.Itismorelikeusingalimitedbuthugesetofwidgets,limitingtheusetothoseonly,andgivingupdirectprogrammingofthewebbrowser.Ifonehastheexperienceandknowledge,however,theycancreatenewwidgetsinHTML,CSS,andJavaScript.

TherearemanyothertechnologiesthatweredevelopedtosupportwebapplicationsinJava.Themodernapproachadvocatedbymostofthebigplayersistodeveloptheserversideandtheclientsideusingseparatetoolsetsandmethodologies,andconnectthetwousingRESTcommunication.

Page 540:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 541:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

Inthischapter,youlearntthestructureofwebprogramming.ThiswasnotpossiblewithoutunderstandingthebasicsofTCP/IPnetworking,whichistheprotocoloftheInternet.TheapplicationlevelprotocolthatisusedoverthatisHTTP,currentlyinaverynewversion2.0,whichisstillnotsupportedbytheservletstandard.WecreatedaversionoftheMastermindgamethat,thistime,canreallybeplayedusingthebrowserandwestarteditinadevelopmentenvironmentusingJetty.Weexaminedhowtostorethegamestateandimplementedtwoversions.Finally,welearnedthebasicsofloggingandwelookedatothertechnologies.Atthesametime,wealsolookedatthedependencyinjectionimplementationGuicefromGoogle,andwestudiedhowitworksunderthehood,andwhyandhowtouseit.

Afterthischapter,youwillbeabletostartthedevelopmentofawebapplicationinJavaandwillunderstandthearchitectureofsuchaprogram.YouwillunderstandwhatisunderthehoodwhenyoustartlearninghowtoprogramwebapplicationsusingtheSpringframework,whichhidesmanyofthecomplexitiesofwebprogramming.

Page 542:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 543:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

BuildingaCommercialWebApplicationUsingRESTWewereplayingaroundtillnow,butJavaisnotatoy.WewanttouseJavaforsomethingrealandserious,commercialandprofessional.Inthischapter,wewilldothat.Theexampleisnotsomethingthatisonlyinterestingtoplaywith,suchasMastermindinthepreviousthreechapters,butratherarealcommercialapplication.Notareal-lifeapplicationactually.Youshouldnotexpectanythinglikethatinabook.Itwouldbetoolongandnoteducatingenough.However,theapplicationthatwewilldevelopinthischaptercanbeextendedandcanbeusedasacoreforareal-lifeapplicationincaseyoudecidedtodoso.

Inthepreviouschapter,wecreatedservlets.Todoso,weusedtheservletspecification,andwehand-implementedservlets.Thatissomethingyouwillrarelydothesedays.Instead,wewilluseareadilyavailableframework,thistime,Spring.ItisthemostwidelyusedframeworkforJavacommercialapplications,andIdaresayitisthedefactostandard.Itwilldoallthetediousworkthatwehadtodo(atleasttounderstandandlearnhowaservletworks)inthepreviouschapter.WewillalsouseSpringfordependencyinjection(whyusetwoframeworkswhenonedoesitall?),andwewilluseTomcat.

Inthepreviouschapter,weusedGuiceasaDIframeworkandJettyasaservletcontainer.Theycanbeaperfectlygoodchoiceforsomeprojects.Forotherprojects,otherframeworksdobetter.Tohavetheopportunitytolookatdifferenttoolsinthisbook,wewillusedifferentframeworkseventhoughalltheexamplescouldbecreatedbysimplyusingTomcatandSpring.

Thecommercialapplicationwewilldevelopwillbeanorderingsystemtargetingresellers.Theinterfacewewillprovidetotheuserswillnotbeawebbrowser;rather,itwillbeREST.Theuserswillthemselvesdevelopapplicationsthatcommunicatewithoursystemandplaceordersfordifferentproducts.Thestructureoftheapplicationwewilldevelopwillbemicroservicesarchitecture,andwewillusesoapUItotesttheapplication,inadditiontothestandardChromedevelopertoolfeatures.

Page 544:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 545:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheMyBusinesswebshop

Imaginethatwehaveahugetradingandlogisticscompany.Therearetensofthousandsofdifferentproductsontheshelves;hundredsoflorriescometoourwarehousebringingnewgoods,andhundredsoflorriesdelivergoodstoourcustomers.Tomanagetheinformation,wehaveaninventorysystemthatkeepstrackofthegoodseveryday,hour,andminutetoknowwhatweactuallyhaveinthewarehouse.Weserveourcustomerswithouthumansmanagingthewarehouseinformation.Formerly,therewerephones,faxmachines,andeventelex,buttoday,allweuseistheInternetandwebservices.Wedonotprovideawebsiteforourcustomers.Wehaveneverdirectlyservedtheendusersinourimaginedbusiness,butthesedays,wehaveasubsidiarythatwestartedoffasaseparatecompanytodojustthat.Theyhaveawebsite,anditistotallyindependentfromus.Theyarejustoneofourhundredsofregisteredpartnerswhoeachuseawebserviceinterfacetoseetheproductswehave,orderproducts,andtracktheorderstatus.

Page 546:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 547:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SamplebusinessarchitectureOurpartnersarealsolargecompanieswithautomatedadministration,withseveralprogramsrunningonseveralmachines.Wehavenointerestintheirarchitectureandthetechnologytheyuse,butwewanttointegratetheiroperations.Wewanttoservetheminawaythatdoesn'trequireanyhumaninteractionfortheadministrationtoordergoodsoneitherofoursides.Todoso,awebserviceinterfaceisprovidedthatcanbeutilizednomatterwhatITinfrastructuretheyuse.

Onourside,asweimaginetheexample,werecentlyreplacedourmonolithicapplicationwithmicroservicesarchitecture,andthoughtherearestillsomeSOAP-basedsolutionsinthesystem,mostofthebackendmodulescommunicateusingHTTPSandRESTprotocols.SomeofthemodulesstillrelyonasynchronousfiletransfersdoneonadailybasisusingFTPstartedfromaUNIXcronjob.TheGeneralLedgersystemwasprogrammedinCOBOL.Fortunately,wedonotneedtodealwiththesedinosaurs.

Allthisstructureisanimaginedsetupbutarealisticone.Imadeupanddescribedthesepartstogiveyouapictureofhowyoumayseemixedtechnologiesinalargeenterprise.WhatIdescribedhereisaverysimplesetup.Therearecompaniesthathavemorethanathousandsoftwaremodulesintheirsystemsusingdifferenttechnologiesandtotallydifferentinterfaces,allinterconnectedwitheachother.Thisisnotbecausetheylikethemess,butthatisthewayitbecomesafter30yearsofcontinuousITdevelopment.Newtechnologiescomeandoldtechnologiesfadeout.Thebusinesschangesandyoucannotsticktotheoldtechnologiesifyouwanttostaycompetitive.Atthesametime,youjustcannotreplacetheentireinfrastructureinstantaneously.Theresultisthatweseeinanenterprisefairlyoldtechnologiesstillrunningand,manytimes,newtechnologies.Oldtechnologiesgetrolledoutbytime.Theydonotstayforever,andstill,wearesurprisedsometimeswhenadinosaurcomesinfrontofus.

Whatwehavetodealwithisthetwofrontendcomponentsthatwewilldevelop.Theseareasfollows:

ProductInformationOrderPlacementandTracking

Inthefollowingimage,youcanseethearchitecturalUMLdiagramofthestructurethatwelookat.Thepartswewillhaveinteractionwithareonlythefrontendcomponents,butithelpsunderstandtheworkingandtheirroleifwehaveabiggerpicture:

Page 548:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ProductInformationdeliversinformationaboutasingleproduct,butitcanalsodeliveralistofproductsbasedonthequerycriteria.OrderPlacementandTrackingprovidesfunctionstoplaceanorderandalsoletstheclienttoquerythestateofpastorders.

Toprovideproductinformation,weneedaccesstotheProductCatalogmodulethatholdstheactualproductdetails.

TherecanbealotofothertasksthattheProductCatalogdoes,andthatisthereasonitisaseparatemodule.Itcanhave,forexample,aworkflowandapprovalenginethatletsproductadministratorstoenterproductdataandmanagerstocheckandapprovethedata.Approvalisusuallyacomplexprocess,consideringtyposandlegalquestions(wedonotwanttotradeunlicenseddrugs,explosives,andsoon),andcheckingthequalityandapprovalstateofthesourceofthegoods.Manycomplextasksareincludedthatmakeitabackendmodule.Inlargeenterpriseapplications,thefrontendsystemsrarelydoanythingelseotherthantheverybasicfunctionalityofservingtheoutsideparties.Butthisisgoodforus;wecanfocusontheservicethatwehavetodeliver.Andthisisalsogoodforthearchitecture.Itisthesameprincipleasinobject-orientedprogramming:singleresponsibility.

TheProductInformationmodulealsohastoconsultwiththeAccessControlmoduletoseeifacertainproductcanbedeliveredtotheactualcustomer,andwiththeinventorytoseeifthereisanyproductleft,sowedonotofferaproductthatisoutofstock.

TheOrderPlacementandTrackingalsoneedsaccesstoProductInventoryandAccessControlmodulestocheckwhethertheordercanbefulfilled.Atthesametime,italsoneedsservicesfromthePricingmodule,whichcancalculatethepricefortheorder,andfromtheLogisticsmodule,whichtriggersthecollectionofgoodsfromtheinventorylocationsandshipmenttothecustomer.Logisticsalsohasaconnectionto

Page 549:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

invoicing,whichhasaconnectiontotheGeneralLedger,buttheseareonthepictureonlytoshowthatthetravelofinformationdoesnotendthere.Therearemanyothermodulesthatrunthecompany,allofwhicharenoneofourinterestatthemoment.

Page 550:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 551:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MicroservicesThearchitecturedescribedinthepreviouschapterisnotacleanmicroservicearchitecture.Youwillnevermeetoneinitspureforminanyenterprise.Itismorelikesomethingthatwereallymeetinarealcompanymovingfrommonolithictomicroservices.

WetalkaboutthemicroservicearchitecturewhentheapplicationisdevelopedintheformofmanysmallservicesthatcommunicatewitheachotherusingsomesimpleAPI,usuallyoverHTTPandREST.Theservicesimplementbusinessfunctionalitiesandcanbedeployedindependently.Manytimes,itisdesirablethattheservicedeploymentisautomated.

Theindividualservicescanbedevelopedusingdifferentprogramminglanguages,canusedifferentdatastorage,andcanrunondifferentoperatingsystems;thus,theyarehighlyindependentofeachother.Theycanbe,andusuallyare,developedbydifferentteams.Theimportantrequirementisthattheycancooperate;thus,theAPIoneserviceimplementsisusablebytheotherservicesthatbuilduponit.

ThemicroservicearchitectureisnottheHolyGrailofallarchitectures.Itgivesdifferentanswerstosomeproblemsfrommonolithicarchitectures,andmanytimes,theseanswersworkbetterusingmoderntools.Theapplicationsstillhavetobetestedanddebugged,performancehastobemanaged,andbugsandissueshavetobeaddressed.Thedifferenceisthattestingcanbeseparatedalongdifferenttechnologies;debuggingmayneedmorenetwork-relatedwork.Thesemaybegood,bad,orbothatthesametime.Forthedevelopers,however,theadvantageisclear.Theycanworkonasmallerunitindependentlyandcanseetheresultoftheirworkfaster.Whendevelopingasinglemoduleofamonolithicapplication,theresultcanbeseenwhentheentireapplicationgetsdeployed.Inthecaseofalargeapplication,thatmayberare.Atypicaldeploymentcycleinalargecorporatedevelopingmonolithiciseveryfewmonths,say3,butitisnotraretoseethereleasedevelopmenttwiceorevenonceayear.Developingmicroservices,thenewmodulecanbedeployedassoonasitisreadyandtested.

Ifyouwanttoreadmoreonmicroservices,thefirstandthemostauthenticsourceisthearticlebyMartinFowler(http://www.martinfowler.com/articles/microservices.html).

Page 552:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 553:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ServiceinterfacedesignWedesignthetwointerfacesthatwewillimplement.Whenwedesigninterfaces,wefocusonthefunctionalityfirst.Formattingandprotocolcomelater.Interfacesgenerallyshouldbesimpleand,atthesametime,shouldaccommodatethefuturechange.Thisisahardproblembecausewecannotseethefuture.Business,logistics,andallotherexpertsmayseesomepartofthefuture:howtheworldwillchangeandwhatitwillimposeontheoperationofthecompanyand,especially,ontheinterfaceweprovideforourpartners.

Thestabilityofaninterfaceisofutmostimportancebecausethepartnersareoutsideentities.Wecannotrefactorthecodetheyuse.WhenwechangeaJavainterfaceinourcode,thecompilerwillcomplainatallthecodelocationswherethechangeshouldbefollowed.Incaseofaninterfacethatisusedoutsideofourrealm,thisisnotthecase.EvenifitisonlyaJavainterfacethatwepublishasopensourceonGitHub,weshouldbepreparedthatouruserswillfaceissuesifwechangethelibraryinanincompatibleway.Inthatcase,theirsoftwarewillnotcompileandworkwithourlibrary.Inthecaseofanorderingsystem,itmeansthattheywillnotorderfromusandwewillsoonbeoutofbusiness.

Thisisoneofthereasonswhyinterfacesshouldbesimple.Althoughthisisgenerallytrueformostofthethingsinlife,itisextremelyimportantforsuchinterfaces.Itistemptingtoprovideconveniencefeaturesforthepartnersbecausetheyareeasytoimplement.Inthelongrun,however,thesefeaturesmaybecomeveryexpensiveastheyneedmaintenance,shouldbekeptbackwardcompatible,and,inthelongrun,maynotgainasmuchastheycost.

Toaccessproductinformation,weneedtwofunctions.Oneofthemlistscertainproductsandanotherreturnsthedetailsofaspecificproduct.IfitwereaJavaAPI,itwouldlookasfollows:

List<ProductId>query(Stringquery);

ProductInformationbyId(ProductIdid);

Similarly,orderplacementmaylookasshowninthefollowing:

OrderIdplaceOrder(Orderorder);

Weprovidethesefunctionalitiesinourapplicationviaawebserviceinterfaceand,morespecifically,RESTusingJSON.WewilldiscussthesetechnologiesinabitmoredetailedmanneralongwiththeSpringframeworkandModelViewControllerdesignpattern,butfirstlet'slookattheproductinformationcontrollertogetsomefeelingofhowourprogramwilllook:

packagepackt.java9.by.example.mybusiness.productinformation;

import...

@RestController

publicclassProductInformationController{

@Autowired

ProductLookuplookup;

@RequestMapping("/pi/{productId}")

publicProductInformation

getProductInformation(@PathVariableStringproductId){

ProductInformationproductInformation=

lookup.byId(productId);

Page 554:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

returnproductInformation;

}

@RequestMapping("/query/{query}")

publicList<String>lookupProductByTitle(@PathVariableStringquery,HttpServletRequestrequest){

//tobedevelopedlater

}

}

Ifyoucomparethecodeoftheservletwiththeprecedingcode,youcanseethatthisismuchsimpler.WedonotneedtodealwiththeHttpServletRequestobject,callanAPItogetaparameter,orcreateanHTMLoutputandwriteittotheresponse.Theframeworkdoesthis.Weannotatethe@RestControllerclass,tellingSpringthatthisisacontrollerthatutilizestheRESTwebservices;thus,itwillbydefaultcreateaJSONresponsefromtheobjectwereturn.WedonotneedtocareabouttheconversionoftheobjecttoJSON,althoughwecanifthereisreallyaneed.TheobjectwillautomaticallybeconvertedtoJSONusingthefieldnamesusedintheclassandthefieldvaluesoftheinstancewereturn.IftheobjectcontainsmorecomplexstructuresthanjustplainString,int,anddoublevalues,thentheconverterispreparedfornestedstructuresandthemostcommondatatypes.

TohavedifferentcodehandlinganddifferentURLsontheservlet,allweneedtodoistoannotatethemethodwith@RequestMapping,providingthepathpartoftheURL.The{productId}notationinsidethemappingstringisreadableandeasytomaintain.SpringjustcutsthevaluefromthereandputsitforusintheproductIdvariable,asrequestedbythe@PathVariableannotation.

Theactuallookupoftheproductisnotimplementedinthecontroller.Thatisnotthefunctionofthecontroller.Thecontrolleronlydecideswhatbusinesslogictoinvokeandwhatviewtouse.Apartofitisimplementedintheframework,andtheverysmallpartyoucanseetheprecedingcode.Thebusinesslogicisimplementedinaserviceclass.Aninstanceofthisclassisinjectedtothelookupfield.ThisisalsodonebySpring.Theactualworkwehavetodoistoinvokethebusinesslogic,whichthistime,sincewehaveonlyone,isfairlyeasy.

Mostofthesethingsseemmagicwithoutsomemoredetailsaboutwhattheframeworkdoesforus.Therefore,beforegoingon,wewillhavealookatthebuildingblocks:JSON,REST,MVC,andabitoftheSpringframework.

Page 555:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 556:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JSONJSONstandsforJavaScriptObjectNotation.Itisdefinedonthesite,http://www.json.org/.ThisisatextualnotationinthesamewayastheobjectliteralsaredefinedinJavaScript.Anobjectrepresentationstartswiththe{characterandendswiththe}character.Thetextinbetweendefinesthefieldsoftheobjectsintheform,string:value.Thestringisthenameofthefield,andsinceJSONwantstobelanguageagnostic,itallowsanycharacterstobeapartofthenameofafield,andthusthisstring(aswellasanystringinJSON)shouldstartandendwiththe"characters.

Thismayseemstrangeand,manytimes,whenyoustartworkingwithJSON,itiseasytoforgetandwrite{myObject:"hasastring"}insteadofthecorrect{"myObject":"hasastring"}notation.

Commasseparatethefields.YoucanalsohavearraysinJSON.Theystartandendwith[and]characters,respectively,andtheycontaincomma-separatedvalues.Thevalueinanobjectfieldorinanarraycanbeastring,anumber,anobject,anarray,oroneoftheconstants,true,false,andnull.

Generallyspeaking,JSONisaverysimplenotationtodescribedatathatcanbestoredinanobject.Itiseasytowriteusingtexteditorsandeasytoread,andthusitiseasiertodebuganycommunicationthatusesJSONinsteadofmorecomplexformats.WaystoconvertJSONtoaJavaobjectandtheotherwayround,arereadilyavailableinlibrariesthatwewilluseinthischapter.AsampleJSONobjectthatdescribesaproductfromoursamplecodeisalsoavailableinthesourcecodeoftheprogram,asfollows:

{"id":"125","title":"BarStool","description":"anotherfurniture","size":[20.0,2.0,18.0],"weight":300.0}

NotethattheformattingofJSONdoesnotrequireanewline,butatthesametime,thisisalsopossible.Program-generatedJSONobjectsareusuallycompactandarenotformatted.Whenweeditsomeobjectusingatexteditor,wetendtoformattheindentationofthefieldsinthesamewayasweusuallydoinJavaprogramming.

Page 557:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 558:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RESTThereisnoexactdefinitionoftheRESTprotocol.ItstandsforRepresentationalstatetransfer,whichprobablydoesnotmeanathingtosomeonewhohasneverheardofit.WhenweprogramtheRESTAPI,weusetheHTTP(S)protocol.Wesendsimplerequeststotheserver,andwegetsimpleanswersthatweprogram.Thisway,theclientofthewebserverisalsoaprogram(bytheway,thebrowserisalsoaprogram)thatconsumestheresponsefromtheserver.Theformatoftheresponse,therefore,isnotHTMLformattedusingCSSandenrichedbyclient-sidefunctionalitiesbyJavaScript,butrathersomedatadescriptiveformatsuchasJSON.RESTdoesnotsetrestrictionsontheactualformat,butthesedays,JSONisthemostwidelyused.

ThewikipagethatdescribesRESTisavailableathttps://en.wikipedia.org/wiki/Representational_state_transfer.RESTinterfacesareusuallymadesimple.TheHTTPrequestsalmostalwaysusetheGETmethod.ItalsomakesthetestingofRESTservicessimplesincenothingiseasierthanissuingaGETrequestfromabrowser.POSTrequestsareonlyusedwhentheserviceperformssometransactionorchangeontheserver,andthatway,therequestissendingdatatotheserverratherthangettingsomedata.

Inourapplication,wewillusetheGETmethodtoqueryalistofproductsandgetinformationaboutaproduct,andwewillonlyusePOSTtoorderproducts.Theapplicationthatservestheserequestswillruninaservletcontainer.Youhavelearnthowtocreateanakedservletwithouttheuseofaframework.Inthischapter,wewillusetheSpringframework,whichoffloadsmanyofthetasksfromthedeveloper.Therearemanyprogramconstructsinservletprogrammingthatarejustthesamemostofthetime.Theyarecalledboilerplatecode.TheSpringframeworkutilizestheModelViewControllerdesignpatterntodevelopwebapplications;thus,wewilllookatitinbrief,beforediscussingSpringingeneral.

Page 559:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 560:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ModelViewControllerModelViewController(MVC)isadesignpattern.Designpatternsareprogrammingconstructs:simplestructuresthatgivesomehintonhowtosolvesomespecificproblems.Theterm,designpatternwascoinedandformallydescribedinthebook,DesignPatterns,ElementsofReusableObject-OrientedSoftware,writtenbyErichGamma,RichardHelm,RalphJohnson,andJohnVlissides.Thebookdefinesadesignpatternasastructurewithaname,aproblem,andasolution.Thenamedescribesthepatternandgivesthevocabularyforthedevelopercommunitytousewhentalkingaboutthesepatterns.Itisimportantthatdifferentdevelopersusethesamelanguageterminologyinordertounderstandeachother.Theproblemdescribesthesituation,thatis,thedesignproblemwherethepatterncanbeapplied.Thesolutiondescribesclassesandobjectsandtherelationsbetweenthem,whichcontributetoagooddesign.

OneofthemisMVC,whichissuitableforprogrammingwebapplicationsbutgenerallyforanyapplicationthathasauserinterface.Inourcase,wedonothaveaclassicaluserinterfacebecausetheclientisalsoaprogram;still,MVCcanbeandisagoodchoicetouse.

TheMVCpattern,asthenamealsoindicates,hasthreeparts:amodel,aview,andacontroller.Thisseparationfollowsthesingleresponsibilityprinciple,requiringonepartforeachdistinctresponsibility.Thecontrollerisresponsibleforhandlingtheinputsofthesystem,anditdecideswhatmodelandviewtouse.Itcontrolstheexecutionbutusuallydoesnotdoanybusinesslogic.Themodeldoesthebusinesslogicandcontainsthedata.Viewconvertsthemodeldatatoarepresentationthatisconsumablebytheclient.

MVCisawell-knownandwidelyuseddesignpattern,anditisdirectlysupportedbySpringinsucha

Page 561:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

waythatwhenyoucreateawebapplication,youprogramthecontrollerbuiltintotheframework,usingannotations;thus,youessentiallyconfigureit.Youcanprogramtheview,butitismorelikelythatyouwilluseonethatisbuiltintotheframework.YouwillwanttosenddatatotheclientinXML,JSON,orHTML.Ifyouareveryexotic,youmaywanttosendYAML,butgenerally,thatisit.Youdonotwanttoimplementanewformatthatneedstobeprogrammedontheserverand,sincethisisnew,alsoontheclient.

Wecreatethemodel,andthistime,wealsoprogramit.Afterall,thatisthebusinesslogic.Frameworkscandomanythingsforus,mainlythethingsthatarethesameformostoftheapplicationsbutforthebusinesslogic.Businesslogicisthecodethatdistinguishesourcodefromotherprograms.Thatiswhatwehavetoprogram.

Ontheotherhand,thatiswhatweliketodo.Focusonthebusinesscodeandavoidallboilerplateprovidedbytheframework.

NowthatweknowwhatJSON,REST,andthegeneralModelViewControllerdesignpatternare,let'slookathowthesearemanagedbySpringandhowwecanputthesetechnologiesintoaction.

Page 562:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 563:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Springframework

TheSpringframeworkisahugeonewithseveralmodules.Thefirstversionoftheframeworkwasreleasedin2003,andsincethen,therehavebeenfourmajorreleasesdeliveringnewandenhancedfeatures.Currently,Springisthedefactoenterpriseframeworkused,perhapsmorewidelythanthestandardEJB3.0

Springsupportsdependencyinjection,Aspect-OrientedProgramming(AOP),persistenceforSQLandNoSQLdatabasesinaconventionalandObjectRelationalMappingway,transactionalsupport,messaging,webprogramming,andmanyotherfeatures.YoucanconfigureitusingXMLconfigurationfiles,annotations,orJavaclasses.

Page 564:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 565:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ArchitectureofSpringSpringisnotmonolithic.Youcanuseapartofit,oronlysomeofthefeatures.YoucanincludesomeofthemodulesofSpringthatyouneedandleaveoutothers.Somemodulesdependonsomeothers,butGradle,Maven,orsomeotherbuildtoolhandlesthat.

ThefollowingimageshowsyouthemodulesoftheSpringframeworkforversion4:

Springisconstantlydevelopingsinceitsfirstrelease,anditisstillconsideredasamodernframework.Thecoreoftheframeworkisadependencyinjectioncontainersimilartotheonewesawinthepreviouschapter.Astheframeworkdeveloped,italsosupportedAOPandmanyotherenterprisefunctionalities,suchasmessageorientedpatternsandwebprogrammingwithanimplementationofModelViewController,supportingnotonlyservletsbutalsoportletsandWebSockets.SinceSpringtargetstheenterpriseapplicationarena,italsosupportsdatabasehandlinginmanydifferentways.ItsupportsJDBCusingtemplates,ObjectRelationalMapping(ORM),andtransactionmanagement.

Inthesampleprogram,weuseafairlyrecentmodule:Springboot.Thismodulemakesitextremelyeasytostartwritingandrunningapplications,assumingalotofconfigurationsthatareusuallythesameformanyprograms.ItcontainsanembeddedservletcontainerthatitconfiguresfordefaultsettingsandconfiguresSpringwhereveritispossible,sowecanfocusontheprogrammingaspectratherthanontheSpringconfiguration.

Page 566:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 567:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SpringcoreThecentralelementofthecoremoduleisthecontext.WhenaSpringapplicationstarts,thecontainerneedsacontextinwhichthecontainercancreatedifferentbeans.Thisisverygeneralandtrueforanydependencyinjectioncontainer.Ifweprogrammaticallycreatetwodifferentcontexts,theymayliveindependentofeachotherinthesameJVM.Ifthereisabeandeclaredasasingletonsothatthereshouldbeonlyonesingleinstanceofit,thenthecontainerwillcreateasingleinstanceofitforacontextwhenweneedoneinstance.Theobjectsrepresentingthecontexthaveareferencetotheobjectthatwehavealreadycreated.Iftherearemultiplecontexts,however,theywillnotknowthatthereisanothercontextintheJVMthatalreadyhasaninstance,andthecontainerwillcreateanewinstanceofthesingletonbeanfortheothercontext.

Usually,wedonotusemorethanonecontextinaprogram,buttherearenumerousexamplesoftherebeingmanycontextsinasingleJVM.Whendifferentservletsruninthesameservletcontainer,theyruninthesameJVMseparatedbytheclassloaderandtheymayeachuseSpring.Inthiscase,thecontextwillbelongtotheservletandeachwillhaveanewcontext.

Inthepreviouschapter,weusedGuice.TheSpringcontextissimilartotheGuiceinjector.Inthepreviouschapter,IwascheatingabitbecauseIwasprogrammingGuicetocreateanewinjectorforeachrequest.Thisisfarfromoptimal,andGuiceprovidesaninjectorimplementationthatcanhandleservletenvironments.ThereasonforcheatingwasthatIwantedtofocusmoreontheDIarchitectureessentials,andIdidnotwanttocomplicatethecodebyintroducingacomplex(well,morecomplex)implementationoftheinjector.

IntheSpringcontextbehavior,whatitdoes,isdefinedbytheinterfaceApplicationContext.Therearetwoextensionsofthisinterfaceandmanyimplementations.ConfigurableApplicationContextextendsApplicationContext,definingsetters,andConfigurableWebApplicationContextdefinesmethodsneededinthewebenvironment.Whenweprogramwebapplications,weusuallydonotneedtointerferedirectlywiththecontext.Theframeworkconfigurestheservletcontainerprogrammatically,anditcontainsservletsthatcreatethecontextandinvokeourmethods.Thisisallboilerplatecodecreatedforus.

Thecontextkeepstrackofthebeanscreated,butitdoesnotcreatethem.Tocreatebeans,weneedbeanfactories(atleastone).ThetopmostinterfaceofbeanfactoriesinSpringisBeanFactory.Thedifferencebetweenanobjectandabeanisthatabeanfactorycreatesthebean,itisregisteredinthecontext,andithasaStringname.Thisway,theprogramcanrefertothebeanbythename.

DifferentbeanscanbeconfiguredinseveraldifferentwaysinSpring.TheoldestapproachistocreateanXMLfilethatdescribesthedifferentbeans,specifyingthenames,theclassthathastobeinstantiatedtocreatethebean,andfieldsincasethebeanneedsotherbeanstobeinjectedforitscreation.

Themotivationbehindthisapproachisthatthisway,thebeanwiringandconfigurationcanbetotallyindependentoftheapplicationcode.Itbecomesaconfigurationfilethatcanbemaintainedseparately.Ifwehavealargeapplicationthatmayworkinseveraldifferentenvironments,theaccesstoinventorydatamaybeavailableinmultitudeways.Inoneenvironment,theinventoryisavailablebycallingSOAP

Page 568:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

services.Inanotherenvironment,thedataisaccessibleinanSQLdatabase.Inthethirdenvironment,itcanbeavailableinsomeNoSQLstore.Eachoftheseaccessesisimplementedasaseparateclass,implementingacommoninventoryaccessinterface.Theapplicationcodedependsonlyontheinterface,anditisthecontainerthathastoprovideoneortheotherimplementation.

WhentheconfigurationofthebeanwiringisinXML,thenonlythisXMLfileistobeedited,andthecodecanbestartedwiththeimplementationoftheinterfacethatissuitableforthatenvironment.

Thenextpossibilityistoconfigurethebeansusingannotations.Manytimes,weusebeansandSpringnotbecausetherearemanyimplementationsforabeanfunctionality,butbecausewewanttoseparatethecreationoftheobjectinstancefromthefunctionality.Thisisagoodstyle:separationoftheconcernseveniftheimplementationissinglewithoutalternatives.However,inthiscase,creatingtheXMLconfigurationisredundant.Ifthereisaninterfaceandasingleimplementationofitinourcode,thenwhyshouldIspecifyinanXMLthatbycreatinganobjectwithaclassthatimplementsthatinterface,Ishouldusetheclassthatimplementsthatinterface?Quiteobvious,isn'tit?Wedonotlikeprogrammingthingsthatcanbeautomated.

Tosignalthataclasscanbeusedasabean,andtopossiblyprovideaname,wecanusethe@Componentannotation.Wedonotneedtoprovideanameasanargument.Inthatcase,thenamewillbeanemptystring,butwhyhaveanameifwedonotrefertoit?Springscansalltheclassesthatareontheclasspathandrecognizestheclassesannotated,anditknowsthattheyarethecandidatestobeusedforbeancreation.Whenacomponentneedsanotherbeantobeinjected,thefieldcanbeannotatedwith@[email protected]@AutowiredannotationisaSpringannotationandexistedbeforethe@Injectannotationwasstandardized.IfyouintendtouseyourcodeoutsideoftheSpringcontainer,itisrecommendedtousestandardannotations.Functionally,theyareequivalent.

Inourcode,whenSpringcreatesaninstanceoftheProductInformationControllercomponent,itseesthatitneedsaninstanceofProductLookup.Thisisaninterface,andthus,Springstartstolookforsomeclassthatimplementsthisinterface,createsaninstanceofit,possiblyfirstcreatingotherbeans,andtheninjectsit,settingthefield.Youcandecidetoannotatethesetterofthefieldinsteadofthefielditself.Insuchacase,Springwillinvokethesetterevenifthesetterisprivate.Youcaninjectdependenciesthroughconstructorarguments.Themajordifferencebetweenthesetter,fieldinjection,andconstructorinjectionisthatyoucannotcreateabeanwithoutdependencyincaseyouuseconstructorinjection.Whenthebeanisinstantiated,itshouldandwillhaveallotherbeansinjectedsothatitdependsonusingtheconstructorinjection.Atthesametime,thedependenciesthatneedtobeinjectedthroughthesetterinjection,ordirectlyintoafield,couldbeinstantiatedlaterbythecontainersometimebetweeninstantiatingtheclassandreadyingthebean.

Thisslightdifferencemaynotseeminterestingorimportantuntilyourconstructorcodemaybecomemorecomplexthanthesimpledependencysettingsoruntilthedependenciesbecomecomplex.Inthecaseofacomplexconstructor,thecodeshouldpayattentiontothefactthattheobjectisnotfullycreated.Thisisgenerallytrueforanyconstructorcode,butinthecaseofbeanscreatedbyadependencyinjectioncontainer,itisevenmoreimportant.Thus,itmaybeadvisabletouseconstructorinjection.Inthatcase,thedependenciesarethere;ifaprogrammermakesamistake,forgettingthattheobjectisnotfullyinitialized,andusesitintheconstructororamethodthatiscalledfromaconstructor,thedependencyisthere.Also,itiscleanandwell-structuredtousetheconstructortoinitializethedependenciesandhave

Page 569:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

thosefieldsdeclaredfinal.

Ontheotherhand,constructorinjectionhasitsdownsides.

Ifdifferentobjectsdependoneachotherandthereisaringinthedependencygraph,thenSpringwillfaceahardtimeifyouuseconstructordependencies.WhenclassAneedsclassBandtheotherwayround,asthesimplestcircle,thenneitherAnorBcanbecreatedwithouttheotherifthedependencyinjectionisconstructordependency.Insituationslikethis,theconstructorinjectioncannotbeused,andthecircleshouldbebrokenatleastasasingledependency.Insituationslikethis,setterinjectionisinevitable.

Setterinjectionmayalsobebetterwhenthereareoptionaldependencies.Manytimes,someclassmaynotneedallitsdependenciesatthesametime.SomeclassmayuseadatabaseconnectionoraNoSQLdatabasehandlebutnotbothatthesametime.AlthoughitmayalsobeacodesmellandprobablyasignofpoorOOdesign,itmayhappen.ItmaybeadeliberatedecisiontodothatbecausethepureOOdesignwouldresultintoodeepobjecthierarchiesandtoomanyclasses,beyondthemaintainablelimit.Ifsuchisthesituation,theoptionaldependenciesmaybebetterhandledusingsetterinjection.Someareconfiguredandset;someareleftwithdefaultvalues,usuallynull.

Lastbutnotleast,wecanconfigurethecontainerusingJavaclassesincasetheannotationsarenotenough.Forexample,therearemultipleimplementationsoftheProductLookupinterface,asitis,inourcodebase.(Don'tworryifyoudidnotrecognizethat;Ihavenottoldyouaboutthatyet.)ThereisaResourceBasedProductLookupclassthatreadspropertiesfilesfromthepackageandismainlytotesttheapplication,andthereisRestClientProductLookup,whichisaproduction-likeimplementationoftheinterface.IfIhavenootherconfigurationthanannotatingthelookupfieldwith@Autowired,Springwillnotknowwhichimplementationtouseandwillrewardtheuseduringstartupwiththefollowingerrormessage:

ErrorstartingApplicationContext.Todisplaytheauto-configurationreportre-runyourapplicationwith'debug'enabled.

2016-11-0307:25:01.217ERROR51907---[restartedMain]o.s.b.d.LoggingFailureAnalysisReporter:

***************************

APPLICATIONFAILEDTOSTART

***************************

Description:

Parameter0ofconstructorinpackt.java9.by.example.mybusiness.productinformation.ProductInformationControllerrequiredasinglebean,but2werefound:

-resourceBasedProductLookup:definedinfile[/.../sources/ch07/productinformation/build/classes/main/packt/java9/by/example/mybusiness/productinformation/lookup/ResourceBasedProductLookup.class]

-restClientProductLookup:definedinfile[/.../sources/ch07/productinformation/build/classes/main/packt/java9/by/example/mybusiness/productinformation/lookup/RestClientProductLookup.class]

Action:

Considermarkingoneofthebeansas@Primary,updatingtheconsumertoacceptmultiplebeans,orusing@Qualifiertoidentifythebeanthatshouldbeconsumed

Thisisafairlyself-explanatoryerrormessage;ittellsalot.NowisthetimewhenwecanconfigurethebeaninXML,butatthesametime,wecanalsoconfigureitusingJava.

Manydevelopersdonotgetthepointthefirsttime.Ididnotgetiteither.ThewholeXMLconfigurationwastoseparatetheconfigurationfromthecode.Itwastocreatethepossibilitythatasystemadministratorchangestheconfigurationandisfreetoselectoneortheotherimplementationofsomeinterface,wiringtheapplicationtogether.NowSpringtellsmethatitisbettertoreturntotheprogrammaticway?

Atthesametime,IcouldhearconcernsformanyyearsthatXMLisnotreallyanybetterthanJavacode.XMLwritingisessentiallyprogramming,exceptthatthetoolingandIDEsupportisnotasgoodforXML

Page 570:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

asitisforJavacode(thelatterdevelopedalotinrecentyears,althoughforSpringXMLconfiguration).

TounderstandtheconceptofreturningtoJavacodefromXML,wehavetogetbacktothepurereasonandaimoftheXMLwayofconfiguration.ThemainadvantageofXMLSpringconfigurationisnotthattheformatisnotprogrammaticbutratherthattheconfigurationcodeisseparatedfromapplicationcode.IfwewritetheconfigurationinJavaandkeepthoseconfigurationclassestothebareminimum,andtheystayastheyshould,thentheseparationofapplicationversusconfigurationcodestillstands.ItisonlytheformatoftheconfigurationthatwechangefromXMLtoJava.Theadvantagesarenumerous.OneisthatthenamesoftheclassesarerecognizedbytheIDEasweeditandwecanhaveautocompleteinJava(notethatthisalsoworksusingXMLinsomeoftheIDEsutilizingsomeoftheextensionsofplugins).InthecaseofJava,IDEsupportisubiquitous.JavaismorereadablethanXML.Well,thisisamatteroftaste,butmostofuslikeJavamorethanXML.

SystemadministratorscanalsoeditJavacode.WhentheyedittheXMLconfiguration,theyusuallyhavetoextractitfromaJARorWARfile,editit,andthenpackagethearchiveagain.InthecaseofJavaediting,theyalsohavetoissueagradlewarcommandorsomethingsimilar.ThisshouldnotbeashowstopperforasystemmanagerwhorunsJavaapplicationsonaserver.Andagain,itisnotJavaprogramming.ItisonlyeditingsomeJavacodefilesandreplacingsomeclassnameliteralsandstringconstants.

Wefollowthisapproachinoursampleapplicationcode.Wehavetwoconfigurationfilesintheapplication:oneforlocaldeploymentandtestingandanotherforproduction.The@Profileannotationspecifieswhichprofiletheconfigurationshoulduse.Theprofile,whenthecodeisexecuted,canbespecifiedonthecommandlineasasystemproperty,asfollows:

$gradle-Dspring.profiles.active=localbootRun

Theconfigurationclassisannotatedwith@Configuration.Themethodsthatarebeanfactoriesareannotatedwith@Bean:

packagepackt.java9.by.example.mybusiness.productinformation;

import...

@Configuration

@Profile("local")

publicclassSpringConfigurationLocal{

@Bean

@Primary

publicProductLookupproductLookup(){

returnnewResourceBasedProductLookup();

}

@Bean

publicProductInformationServiceUrlBuilderurlBuilder(){

returnnull;

}

}

ThebeanfactorysimplyreturnsanewinstanceoftheResourceBasedProductLookupclassthatimplementstheProductLookupinterface.Thisimplementationcanbeusedtoruntheapplicationforlocaltestingwhentherearenoexternalservicestorelyon.ThisimplementationreadstheproductdatafromlocalresourcefilespackagedintotheJARapplication.

Theproductionversionoftheconfigurationisnotmuchdifferent,butasitmaybeexpected,thereareafewmorethingstoconfigure:

Page 571:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

@Configuration

@Profile("production")

publicclassSpringConfiguration{

@Bean

@Primary

publicProductLookupproductLookup(){

returnnewRestClientProductLookup(urlBuilder());

}

@Bean

publicProductInformationServiceUrlBuilderurlBuilder(){

returnnewProductInformationServiceUrlBuilder(

"http://localhost");

}

}

ThisversionoftheProductLookupserviceclassusesanexternalRESTservicetoretrievethedatathatitwillpresenttotheclients.Todoso,itneedstheURLsoftheseservices.SuchURLsshouldusuallybeconfigured.Inourexample,weimplementasolutionwheretheseURLscanbecomputedonthefly.Itriedtomakeupasituationwhereitmaybeneededinreallife,butallreasoningwascontortedandIgaveup.Therealreasonisthat,thisway,wecanseecodethatcontainsabeanthatneedsanotherbeantobeinjected.Fornow,notethattheProductInformationServiceUrlBuilderinstancebeanisdefinedinthesamewayastheProductLookupbean,andwhenithastobeinjectedintotheconstructoroftheProductLookupbean,itsdefiningbeanmethodisusedandnotthefollowingexpressiondirectly:

newProductInformationServiceUrlBuilder("http://localhost");

Thelattermaywork,butnotinallsituationsandweshouldnotuseit.Forthereasons,wewillreturnwhenwediscussAOPwithSpringinasubsequentsection.

Alsonotethatthereisnoneedtodefineaninterfacetodefineabean.Thetypethatthebeanmethodreturnscanalsobeaclass.Thecontextwillusethemethodthatfitstheneededtype,andiftherearemorethanonesuitabletypesandtheconfigurationisnotpreciseenough,aswesaw,thecontainerwillloganerrorandwillnotwork.

Intheconfigurationthatservesthelocalprofile,wecreateanullvalueforProductInformationServiceBuilder.Thisisbecausewedonotneeditwhenweuselocaltesting.Also,ifanymethodfromthisclassisinvoked,itwillbeanerror.Errorsshouldbedetectedassoonaspossible;thus,anullvalueisagoodchoice.

TheProductInformationServiceUrlBuilderclassisverysimple:

packagepackt.java9.by.example.mybusiness.productinformation;

publicclassProductInformationServiceUrlBuilder{

privatefinalStringbaseUrl;

publicProductInformationServiceUrlBuilder(StringbaseUrl){

this.baseUrl=baseUrl;

}

publicStringurl(Stringservice,Stringparameter){

finalStringserviceUrl;

switch(service){

case"pi":

serviceUrl=

baseUrl+":8081/product/{id}";

break;

case"query":

serviceUrl=

Page 572:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

baseUrl+":8081/query/{query}";

break;

case"inventory":

serviceUrl=

baseUrl+":8083/inventory/{id}";

break;

default:

serviceUrl=null;

break;

}

returnserviceUrl;

}

}

Thisbeanalsoneedsaconstructorparameter,andweusedastringconstantintheconfiguration.Thisclearlyshowsthatitispossibletouseasimpleobjecttoinitializesomeofthedependencies(whatwouldstopus,itispureJavaafterall),butitmayhindertheworkingofsomeSpringfeatures.

Page 573:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 574:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ServiceclassesWehavetwoserviceclasses.Theseclassesservethecontrollerswithdataandimplementthebusinesslogic,nomatterhowsimpletheyare.OneoftheserviceclassimplementationscallsREST-basedservices,whiletheotheronereadsdatafrompropertiesfiles.Thelattercanbeusedtotesttheapplicationoffline.TheonethatcallsRESTservicesisusedintheproductionenvironment.BothofthemimplementtheProductLookupinterface:

packagepackt.java9.by.example.mybusiness.productinformation;

importjava.util.List;

publicinterfaceProductLookup{

ProductInformationbyId(Stringid);

List<String>byQuery(Stringquery);

}

ResourceBasedProductLookupstoresthewholedatabaseinamapcalledproducts.Itisfilledfromthepropertiesfileswhenoneoftheservicemethodsisinvoked.TheprivatemethodloadProductsisinvokedfromeachoftheservicemethodswhentheystart,butitloadsthedataonlyifitisnotloadedyet:

packagepackt.java9.by.example.mybusiness.productinformation.lookup;

import...

@Service

publicclassResourceBasedProductLookupimplementsProductLookup{

privatestaticLoggerlog=LoggerFactory.getLogger(ResourceBasedProductLookup.class);

Theclassisannotatedusing@Service.Thisannotationispracticallyequivalenttothe@Componentannotation.Thisisonlyanalternativenametothesameannotation.Springalsohandlesthe@Componentannotationsuchthatifanannotationinterfaceisannotatedusingthe@Componentannotation,theannotationcanalsobeusedtosignalthataclassisaSpringcomponent.Youcanwriteyourownannotationinterfacesifyouwanttosignalforbetterreadabilitythataclassisnotasimplecomponentbutsomeotherspecialtype.

Forexample,startupyourIDEandnavigatetothesourcecodeoftheorg.springframework.stereotype.Serviceinterface:

privateProductInformation

fromProperties(Propertiesproperties){

finalProductInformationpi=newProductInformation();

pi.setTitle(properties.getProperty("title"));

pi.setDescription(properties.getProperty("description"));

pi.setWeight(

Double.parseDouble(properties.getProperty("weight")));

pi.getSize()[0]=

Double.parseDouble(properties.getProperty("width"));

pi.getSize()[1]=

Double.parseDouble(properties.getProperty("height"));

pi.getSize()[2]=

Double.parseDouble(properties.getProperty("depth"));

returnpi;

}

ThefromPropertiesmethodcreatesaninstanceofProductInformationandfillsitfromtheparametersgiveninthePropertiesobject.ThePropertiesclassisanoldandwidelyusedtype.Althoughtherearemoremodernformatsandclasses,thisisstillwidelyusedanditislikelythatyouwillmeetthisclass.Thisistheveryreasonweuseithere.

Page 575:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ProductInformationisasimpleDataTransferObject(DTO)thatcontainsnologic,onlyfields,setters,andgetters.Italsocontainsaconstant,emptyProductInformation,holdingareferencetoaninstanceoftheclasswithemptyvalues.

APropertiesobjectissimilartoaMapobject.ItcontainsStringvaluesassignedtoStringkeys.Therearemethods,aswewillseeinourexamples,thathelptheprogrammertoloadaPropertiesobjectfromaso-calledpropertiesfile.Suchafileusuallyhasthe.propertiesextension,anditcontainskeyvaluepairsinthefollowingformat:

key=value

Forexample,the123.propertiesfilecontainsthefollowing:

id=123

title=BookJava9byExample

description=anewbooktolearnJava9

weight=300

width=20

height=2

depth=18

Thepropertiesfilesareusedtostoresimpleconfigurationvaluesandarealmostexclusivelyusedtocontainlanguage-specificconstants.ThisisaverycontortedusebecausepropertiesfilesareISOLatin-1encodedfiles,andincaseyouneedtousesomespecialUTF-8characters,youhavetotypethemusingthe\uXXXXformatorusingthenative2asciiconverterprogram.YoucannotsavethemsimplyasUTF-8.Nevertheless,thisisthefileformatusedforlanguage-specificstringsusedforprograminternationalization(alsoabbreviatedasi18nbecausethereare18charactersbetweenthestartingiandthelastn).TogetthePropertiesobject,wehavetoreadthefilesintheprojectandgetthempackagedintoaJARfile.TheSpringclass,PathMatchingResourcePatternResolver,helpsusindoingso.

Gosh,yes,Iknow!WehavetogetusedtotheselongnameswhenweuseSpring.Anyway,suchlonganddescriptivenamesarewidelyusedinanenterpriseenvironmentandtheyareneededtoexplainthefunctionalityoftheclasses.

Wedeclareamapthatwillcontainalltheproductsduringthetesting:

finalprivateMap<String,ProductInformation>

products=newHashMap<>();

ThekeyistheproductID,whichisastringinourexample.ThevaluesaretheProductInformationobjectsthatwefillupusingthefromPropertiesmethod:

privatebooleanproductsAreNotLoaded=true;

Thenextfieldsignalsthattheproductsarenotloaded:

NoviceprogrammersusuallyusetheoppositevaluewiththenameproductsAreLoadedandsettofalsebydefault.Inthatcase,theonlyplacewherewewillreadavaluewillnegatethevalue,orthemainbranchoftheifcommandbecomesthedonothingpart.Neitherisabestpractice.

Page 576:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privatevoidloadProducts(){

if(productsAreNotLoaded){

try{

Resource[]resources=

newPathMatchingResourcePatternResolver()

.getResources(

"classpath:products/*.properties");

for(Resourceresource:resources){

loadResource(resource);

}

}

productsAreNotLoaded=false;

}catch(IOExceptionex){

log.error("Testresourcescannotberead",ex);

}

}

}

ThegetResourcesmethodreturnsalltheresources(files)thatareontheclasspathundertheproductsdirectoryandthathavea.propertiesextension:

privatevoidloadResource(Resourceresource)throwsIOException{

finalintdotPos=resource.getFilename().lastIndexOf('.');

finalStringid=resource.getFilename().substring(0,dotPos);

Propertiesproperties=newProperties();

properties.load(resource.getInputStream());

finalProductInformationpi=fromProperties(properties);

pi.setId(id);

products.put(id,pi);

}

TheproductIDisgivenbythenameofthefile.Thisiscalculatedusingsimplestringmanipulation,cuttingofftheextension.TheResourcecanalsoprovideaninputstreamthatthePropertiesclass'sloadmethodcanusetoloadallthepropertiesatoncefromthefile.Finally,wesavethenewProductInformationobjectinthemap.

WealsohaveaspecialnoProductlistthatisempty.Thisisreturnedifthereisnoproductforthequerywhenwewanttosearchforproducts:

privatestaticfinalList<String>noProducts=

newLinkedList<>();

TheproductlookupservicejusttakesaproductfromtheMapandreturnsit,orifitdoesnotexist,itreturnsanemptyproduct:

@Override

publicProductInformationbyId(Stringid){

loadProducts();

if(products.containsKey(id)){

returnproducts.get(id);

}else{

returnProductInformation.emptyProductInformation;

}

}

Thequeryisabitmorecomplex.Itimplementssearchingforaproductbytitle.Real-lifeimplementationsmayimplementamorecomplexlogic,butthisversionisforlocaltestingonly;thus,thesearchbytitleisenough,perhapsevenmorecomplexthanwouldbereallynecessary:

@Override

publicList<String>byQuery(Stringquery){

loadProducts();

List<String>pis=newLinkedList<>();

StringTokenizerst=newStringTokenizer(query,"&=");

Page 577:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

while(st.hasMoreTokens()){

finalStringkey=st.nextToken();

if(st.hasMoreTokens()){

finalStringvalue=st.nextToken();

log.debug("processing{}={}query",key,value);

if(!"title".equals(key)){

returnnoProducts;

}

for(Stringid:products.keySet()){

ProductInformationpi=products.get(id);

if(pi.getTitle().startsWith(value)){

pis.add(id);

}

}

}

}

returnpis;

}

Theserviceclassthatimplementstheproductionfunctionalityismuchsimpler.Strange,butmanytimesthetestcodeismorecomplexthantheproductioncode:

packagepackt.java9.by.example.mybusiness.productinformation.lookup;

import...

@Component

publicclassRestClientProductLookupimplementsProductLookup{

privatestaticLoggerlog=LoggerFactory.getLogger(RestClientProductLookup.class);

finalprivateProductInformationServiceUrlBuilderpiSUBuilder;

publicRestClientProductLookup(

ProductInformationServiceUrlBuilderpiSUBuilder){

this.piSUBuilder=piSUBuilder;

}

TheconstructorisusedtoinjecttheURLbuilderbeanandthisisalltheauxiliarycodetheclasshas.Therestarethetwoservicemethods:

@Override

publicProductInformationbyId(Stringid){

Map<String,String>uriParameters=newHashMap<>();

uriParameters.put("id",id);

RestTemplaterest=newRestTemplate();

InventoryItemAmountamount=rest.getForObject(

piSUBuilder.url("inventory"),

InventoryItemAmount.class,

uriParameters);

if(amount.getAmount()>0){

returnrest.getForObject(piSUBuilder.url("pi"),

ProductInformation.class,

uriParameters);

}else{

returnProductInformation.emptyProductInformation;

}

}

ThebyIdmethodfirstcallstheinventoryservicetoseeifthereareanyproductsontheinventory.ThisRESTservicereturnsaJSONthathastheformat,{amount:nnn};thus,weneedaclass(sosimplethatwedonotlisthere)thathastheintamountfield,thesetter,andthegetter.

TheSpringRestTemplateprovidesaneasywaytoaccessaRESTservice.AllitneedsistheURLtemplate,atypethatisusedtoconverttheresult,andaMapobjectwiththeparameters.TheURLtemplatestringmaycontainparametersinthesamewayastherequestmappingintheSpringcontrollers,thenameoftheparameterbeingbetweenthe{and}characters.Thetemplateclassprovidessimplemethodstoaccess

Page 578:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RESTservices.Itautomaticallydoesmarshaling,sendingparameters,andun-marshaling,receivingtheresponse.InthecaseofaGETrequest,themarshalingisnotneeded.ThedataisintherequestURL,andthe{xxx}placeholdersarereplacedwiththevaluesfromthemapsuppliedasathirdargument.Theun-marshalingisreadilyavailableformostoftheformats.Inourapplication,theRESTservicesendsJSONdata,anditisindicatedintheresponseContent-TypeHTTPheader.RestTemplateconvertstheJSONtothetypeprovidedasargument.IfevertheserverdecidestosendtheresponseinXML,anditwillalsobeindicatedintheHTTPheader,RestTemplatewillhandlethesituationautomatically.Asamatteroffact,lookingatthecode,wecannottellhowtheresponseisencoded.Thisisalsonicebecauseitmakestheclientflexibleandatthesametime,wedonotneedtodealwithsuchtechnicaldetails.Wecanfocusonthebusinesslogic.

Atthesametime,theclassalsoprovidesconfigurationparametersinthecaseofmarshalingorsomeotherfunctionalitysothatitautomaticallyneedsthat.Youcan,forexample,providemarshalingmethods,thoughIrecommendthatyouusewhateverisavailablebydefault.Inmostcases,whenadeveloperthinksthatthereisaneedforaspecialversionofanyofthesefunctions,theoriginaldesignoftheircodeisflawed.

Thebusinesslogicisverysimple.Wefirstasktheinventoryifthereisanyproductinstock.Ifthereis(morethanzero),thenwequerytheproductinformationserviceandreturnthedetails.Ifthereisnone,thenwereturnanemptyrecord.

Theotherserviceisevensimpler.Itsimplycallstheunderpinningserviceandreturnstheresult:

@Override

publicList<String>byQuery(Stringquery){

Map<String,String>uriParameters=newHashMap<>();

uriParameters.put("query",query);

RestTemplaterest=newRestTemplate();

returnrest.getForObject(

piSUBuilder.url("query"),

List.class,

uriParameters);

}

}

Page 579:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 580:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CompilingandrunningtheapplicationWeusegradletocompileandruntheapplication.Sincetheapplicationdoesnothaveanyspecificconfigurationthatwouldnotappearinmostsimilarapplications,itiswisetousetheSpringboot.TheSpringbootmakesitextremelysimpletocreateandrunawebapplication.WeneedaJavastandardpublicstaticvoidmainmethodthatstartsuptheapplicationviaSpring:packagepackt.java9.by.example.mybusiness.productinformation;import...@SpringBootApplication(scanBasePackageClasses=packt.java9.by.example.mybusiness.SpringScanBase.class)publicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}

ThemethoddoesnothingbutstarttheStringApplicationclass'srunmethod.Itpassestheoriginalargumentsandalsotheclassthattheapplicationisin.Springusesthisclasstoreadtheannotation.The@SpringBootApplicationannotationsignalsthatthisclassisaSpringbootapplicationandprovidesargumentstoconfigurethepackagesthatcontaintheapplication.Todoso,youcanprovidethenameofthepackagethatcontainstheclasses,butyoucanalsoprovideaclassinthebasepackagethatcontainsalltheclassesthatSpringhastobeawareof.Youmaynotbeabletousetheclassversionoftheannotationparameterbecausetherootpackagemaynotcontainanyclass,onlysub-packages.Atthesametime,providingthenameoftherootpackageasString,willnotrevealanytypoormisalignmentduringcompiletime.SomeIDEmayrecognizethattheparameterissupposedtobeapackagename,oritmayscanthestringsoftheprogramforpackagenameswhenyourefactororrenameapackageandgiveyousupportforthat,butthisismoreheuristicsonly.Itisacommonpracticetocreateaplaceholderclassthatdoesnothingintherootpackageincasethereisnoclassthere.ThisclasscanbeusedtospecifyscanBasePackageClassesasanannotationparameterinsteadofscanBasePackagesthatneedsString.Inourexample,wehaveanemptyinterface,SpringScanBase,asaplaceholder.

Springscansalltheclassesthatareontheclasspath,recognizesthecomponentsandfieldannotationsthatitcaninterpret,andusesthisknowledgetocreatebeanswithoutconfigurationwhenneeded.

Notethattheabstractclass,ClassLoader,includedintheJDKdoesnotprovideanyclassscanningmethod.SinceJavaenvironmentsandframeworkscanimplementtheirownClassLoaders,itispossible(butveryunlikely)thatsomeimplementationdoesnotprovidethescanningfunctionalityprovidedbytheURLClassLoader.URLClassLoaderisanon-abstractimplementationoftheclassloadingfunctionalityandisapartoftheJDKjustaswellasClassLoader.Wewilldiscusstheintricaciesoftheclassloadingmechanisminthesubsequentchapters.

Thegradlebuildfilecontainstheusualthings.Itspecifiestherepositories,thepluginsforJava,theIDEs,

Page 581:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

andalsoforSpringboot.ItalsospecifiesthenameoftheJARfilethatitgeneratesduringbuild.Themostimportantpartisthedependencylist:buildscript{repositories{mavenCentral()}dependencies{classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.1.RELEASE")}}

applyplugin:'java'applyplugin:'eclipse'applyplugin:'idea'applyplugin:'spring-boot'

jar{baseName='packt-ch07-microservice'version='1.0.0'}

repositories{mavenCentral()}

bootRun{systemPropertiesSystem.properties}

sourceCompatibility=1.9targetCompatibility=1.9

dependencies{compile("org.springframework.boot:spring-boot-starter-web")compile("org.springframework.boot:spring-boot-devtools")compile("org.springframework:spring-aop")compile("org.springframework:spring-aspects")testCompile("org.springframework.boot:spring-boot-starter-test")}

WedependonSpringbootpackages,sometestpackages,AOPsupport(whichwewilllookatsoon),andalsoonSpringbootdevtools.

Springbootdevtoolsmakeitpossibletorestartawebapplicationwheneveritisrecompiled,withoutrestartingthebuilt-inTomcatserver.Suppose,westarttheapplicationusingthefollowingcommandline:gradle-Dspring.profiles.active=productionbootRun

Page 582:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheGradlestartsuptheapplicationandwheneveritseesthattheclassesitrunsaremodified,itreloadsthem,andwecantestthemodifiedapplicationwithinafewseconds.

The-Dspring.profiles.active=productionargumentspecifiesthattheproductionprofileshouldbeactive.Tobeabletousethiscommandlineparameter,wewillalsoneedthebootRun{}configurationclosureinthebuildfile.

Page 583:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 584:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Testingtheapplication

Theapplicationshouldhaveunittestsforeachandeveryclassithasexcept,perhaps,fortheDTOclassesthatcontainnofunctionality.ThesettersandgettersarecreatedbytheIDEandarenottypedinbytheprogrammer,soitisunlikelythattherewillbeanyerrorsinthose.Ifthereissomeerrorrelatedtothoseclasses,itismorelikelythatitissomeintegrationproblemthatcannotbediscoveredusingunittests.Sincewediscussedunittestsinthepreviouschaptersindetail,wewillfocusmoreonintegrationtestsandapplicationtestshere.

Page 585:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 586:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IntegrationtestIntegrationtestsareverysimilartounittests,andmanytimes,noviceprogrammersclaimtheydounittestingwhentheyactuallydointegrationtesting.

Integrationtestsdrivethecodebutdonottesttheindividualclasses(units)inisolation,mockingeverythingthattheclassmayuse.Rather,theytestthefunctionalityofmostoftheclassesthatareneededtoperformatest.Thisway,theintegrationtestdoestestthattheclassesareabletoworktogetherandnotonlysatisfytheirownspecificationsbutalsoensurethatthesespecificationsworktogether.

Inintegrationtest,theexternalworld(likeexternalservices)andaccesstodatabasearemockedonly.Thatisbecausetheintegrationtestsaresupposedtorunonintegrationservers,inthesameenvironmentwheretheunittestsareexecuted,andtheretheseexternalinterfacesmaynotbeavailable.Manytimes,databasesaremockedusingin-memorySQL,andexternalservicesaremockedusingsomemockclasses.

Springprovidesaniceenvironmenttoexecutesuchintegrationtests.Inourproject,wehaveasampleintegrationtest:

packagepackt.java9.by.example.mybusiness.productinformation;

import...

@RunWith(SpringRunner.class)

@SpringBootTest(classes=Application.class)

@AutoConfigureMockMvc

@ActiveProfiles("local")

publicclassProductInformationControllerTest{

@Autowired

privateMockMvcmockMvc;

@Test

publicvoidnoParamGreetingShouldReturnDefaultMessage()

throwsException{

this.mockMvc.perform(get("/pi")).andDo(print())

.andExpect(status().isNotFound());

}

@Test

publicvoidparamGreetingShouldReturnTailoredMessage()

throwsException{

this.mockMvc.perform(get("/pi/123"))

.andDo(print()).andExpect(status().isOk())

.andExpect(jsonPath("$.title")

.value("BookJava9byExample"));

}

}

Thisisfarfrombeingacompleteandfull-fledgedintegrationtest.Therearemanysituationsthatarenottested,buthereitisgoodasanexample.TohaveallthesupportfortheSpringenvironment,wehavetousetheSpringRunnerclass.The@RunWithannotationishandledbytheJUnitframework,allotherannotationsareforSpring.WhentheJUnitframeworkseesthatthereisa@RunWithannotationandarunnerclassspecified,itstartsthatclassinsteadofthestandardrunner.SpringRunnersetsupaSpringcontextforthetestandhandlestheannotations.

@SpringBootTestspecifiestheapplicationsthatweneedtotest.ThishelpsSpringtoreadthatclassandtheannotationonthatclass,identifyingthepackagestobescanned.

@AutoConfigureMockMvctellsSpringtoconfigureamockversionoftheModelViewControllerframework,

Page 587:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

whichcanbeexecutedwithoutaservletcontainerandwebprotocol.Usingthat,wecantestourRESTserviceswithoutreallygoingtothenetwork.

@ActiveProfilestellsSpringthattheactiveprofileislocalandthatSpringhastousetheconfigurationthatisdenotedbytheannotation,@Profile("local").Thisisaversionthatusesthe.propertiesfilesinsteadofexternalHTTPservices;thus,thisisappropriateforintegrationtesting.

ThetestperformsGETrequestsinsidethemockingframework,executesthecodeinthecontroller,andteststhereturnedvalueusingthemockingframeworkandfluentAPIinaveryreadableway.

Notethatusingthepropertiesfilesandhavingtheserviceimplementationbasedonpropertiesfileisabitofanoverkill.Icreatedthissothatitispossibletostartuptheapplicationinteractivelywithoutanyrealbackingservice.Considerthefollowingcommand:gradle-Dspring.profiles.active=localbootRun.Ifweissuetheprecedingcommand,thentheserverstartsupusingthislocalimplementation.Ifweonlyaimforintegrationtesting,thenthelocalimplementationoftheserviceclassesshouldbeunderthetestdirectoryandshouldbemuchsimpler,mainlyonlyreturningconstantresponsesforanyexpectedrequestandthrowingerrorsifanynon-expectedrequestcomes.

Page 588:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 589:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ApplicationtestConsiderthefollowingcommand:

gradle-Dspring.profiles.active=productionbootRun

IfwestartuptheapplicationissuingtheprecedingcommandandfireupthebrowsertotheURL,http://localhost:8080/pi/123,wewillgetafaterrormessageonthebrowserscreen.Ouch...

ItsaysInternalServerError,status=500orsomethingsimilar.Thatisbecauseourcodewantstoconnecttothebackingservices,butwedonothaveanyyet.Tohavesometotesttheapplicationonthislevel,weshouldcreatethebackingservicesoratleastsomethingthatmocksthem.TheeasiestwayistousethesoapUIprogram.

ThesoapUIisaJavaprogramavailablefromhttps://www.soapui.org/.Thereisanopensourceandfreeversionofit,andthereisacommercialversion.Forourpurposes,thefreeversionisenough.Wecaninstallitinthesimplestclick-forwardwayasithasasetupwizard.Afterthat,wecanstartitupandusethegraphicaluserinterface.

Wecreateanewtestproject,Catalogandinventory,andsetuptwoRESTmockservicesinit:CatalogandInventory,asshowninthefollowingscreenshot:

Wesetup,foreachofthemockservices,requeststobematchedandresponses.Thecontentoftheresponseistextandcanbetypedintothetextfieldontheuserinterface.Itisimportantthatwedonotforgettosetthemediatypeoftheresponsetoapplication/json(thedefaultisXML).

Page 590:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Beforestartingtheservices,wehavetosettheportnumbersbyclickingonthecogwheeltosomethingthatisavailableontheserver.Since8080isusedbytheTomcatserverexecutedbyGradle,and8082isusedbysoapUItolistthemockservicesthatarecurrentlyrunning,Isetthecatalogtolistenon8081andinventoryon8083.YoucanalsoseetheseportnumbersinthelistingoftheProductInformationServiceUrlBuilderclass.

ThesoapUIsavestheprojectinanXMLfile,anditisavailableforyouonGitHubintheprojectdirectory.

Afterstartingthemockservices,theerrormessagedisappearsfromthebrowserscreenwhenwepressrefresh:

WhatweseeisexactlywhatwetypedintosoapUI.

IfnowIchangetheinventorymockservicetoreturn0insteadof100,asintheoriginalversion,whatIgetisthefollowingemptyrecord:

{"id":"","title":"","description":"","size":[0.0,0.0,0.0],"weight":0.0}

Thetestingevenonthislevelcanbeautomated.Now,wewereplayingaroundusingthebrowserandthisissomethingnice.Somehow,IfeelIamproducingsomethingwhenthereisaprogramthatisreallydoingsomething,whenIcanseethatthereissomeresponseinthebrowserwindow.However,afterawhile,thisbecomesboringandtestingmanuallythattheapplicationisstillworkingiscumbersome.Itisespeciallyboringforthosefunctionsthatwerenotchanged.Thefactisthattheydochangemiraculouslymanytimesevenwhenwedonottouchthecodethatinfluencesthem.Wetouchthecodethatdoesinfluencethefunctionexceptthatwearenotawareofit.Poordesign,poorcoding,ormaybewejustforgot,butithappens.Regressiontestisinevitable.

Page 591:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Althoughbrowsertestinguserinterfacescanalsobeautomated,thistime,wearehavingaRESTservicethatwecantestandthatiswhatsoapUIisfor.Wehavealreadyinstalledthetool,wehavealreadystartedit,andwehavesomemockservicesrunninginit.ThenextthingistoaddaNewRESTservicefromURItotheprojectandspecifytheURL,http://localhost:8080/pi/{id},exactlythesamewayaswedidforSpring:

WhenwehaveaRESTservicedefinedintheproject,wecancreateanewTestSuiteandaTestCaseinsidethesuite.WecanthenaddasteptotheTestCasethatwillcalltheRESTserviceusingtheparameter123ifwemodifythedefaultvalue,whichisthesameasthenameoftheparameter,inthiscase,id.Wecanruntheteststepusingthegreentriangleontheupper-leftcornerofthewindow,andsincewehavethetestedapplicationandthesoapUImockservicesrunning,weshouldgetananswerinJSON.WehavetoselectJSONontheresponseside;otherwise,soapUItriestointerprettheresponseasXML,andsincewehaveaJSONresponse,itisnottoofruitful.Whatweseeisthefollowingwindow:

Page 592:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Itisthesameresponsethatwesawinthebrowser.Therearenomiracleswhenweprogramcomputers.Sometimes,wedonotunderstandwhathappens,andsomethingsaresocomplexthattheyseemtobeamiracle,buttheyareactuallynot.Thereisanexplanationforeverything,itmayjustnotbeknowntous.Inthiscase,wecertainlyknowwhatishappening,butwhyisitanybettertoseetheJSONonthescreenofsoapUIthanitisonthebrowser?ThereasonisthatsoapUIcanexecuteassertionsandinsomecases,furtherteststepsbasedontheresultoftheRESTinvocation,andthefinalresultisasimpleYESorNO.ThetestisOK,oritFAILS.

Toaddanassertion,clickontheAssertionstextonthelower-leftcornerofthewindow.Asyoucanseeintheprecedingscreenshot,Ihavealreadyaddedonethatcomparesthe"title"fieldofthereturnedJSONwiththetext"BarStool".Whenweaddtheassertion,thedefaultvalueitsuggestsistheonethatwasactuallyreturned,whichisjustaveryhandyfeature.

Afterthis,runningthewholetestsuiteagainwillrunallthetestcases(wehaveonlyone),andalltheteststeps,oneaftertheother(weagainhaveonlyone),andfinallyitwilldisplayagreenFINISHEDbarontheUI,asshowninthefollowingscreenshot:

ThisisnotallthatsoapUIcando.Thisisawell-developedtesttoolthathasbeeninthemarketformanyyears.soapUIcantestSOAPservicesandRESTservices,anditcanhandleJMSmessages.Youcancreatetestsofmanystepswiththesecalls,loops,andassertionsincallsorinseparatetests,andincaseallelsefails,youcandojustanythingbycreatingprogrammedstepsintheGroovylanguageorcreatingextensionsinJava.

Page 593:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 594:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ServletfiltersTheservicesworkfinebynowandanyonecanquerythedetailsofourproducts.Thatmaybeaproblem.Thedetailsoftheproductsarenotnecessarilypublicinformation.Wehavetoensurethatweservethedataonlytopartnerswhoareeligibletoseeit.

Toensurethat,weneedsomethingintherequestthatprovesthattherequestcomesfromapartner.Thisinformationistypicallyapasswordorsomeothersecret.ItcouldbeplacedintotheGETrequestparametersorintotheHTTPrequestheader.Itisbettertoputitintotheheaderbecausetheinformationissecretandnottobeseenbyanybody.

TheGETparametersareapartoftheURL,andthebrowserhistoryremembersthat.Itisalsoveryeasytoenterthisinformationintothebrowserlocationwindow,copypasteit,andsenditoverachatchannelorovere-mail.Thisway,auseroftheapplication,whoisnotsoeducatedandconcernedaboutsecurity,maydisclosesecretinformation.AlthoughitisnotimpossibletodothesamewithinformationthatissentinanHTTPheader,itisnotlikelytohappen.Iftheinformationisintheheaderandsomebodysendstheinformationinane-mail,theyprobablyknowwhattheyaredoing;theycrossasecurityborderwillinglyandnotbysimplenegligence.

TosendauthenticationinformationalongtheHTTPrequest,SpringprovidesasecuritymodulethatcaneasilybeconfiguredwithannotationsandconfigurationXMLsand/orclasses.Thistime,wewilldoitabitdifferentlytointroduceservletfilters.

WewillrequirethatthevendorsinserttheX-PartnerSecretheaderintotherequest.Thisisanon-standardheader,andthusitmusthavetheX-prefix.Followingthisapproachisalsosomeextrasecurityfeature.Thisway,wecanpreventtheuserfromreachingtheserviceusingasimplebrowser.Thereis,atleast,aneedforsomeextrapluginthatcaninsertacustomheaderorsomeotherprogramsuchassoapUI.Thisway,itwillensurethatourpartnerswillusetheinterfaceprogrammatically,orifevertheyneedtotesttheinterfaceadhoc,onlyuserswithacertainleveloftechnologycandoso.Thisisimportanttokeepthesupportcostscontrolled.

Sincethissecrethastobecheckedinthecaseofeachandeveryservice,webetternotinsertthecheckingcodeintoeachandeveryservicecontroller.Evenifwecreatethecodeproperlyandfactorthecheckforthesecretintoaseparateclass,theinvocationofthemethodassertingthatthesecretisthereandiscorrectwillhavetobeinsertedineachandeverycontroller.Thecontrollerdoestheservice;checkingtheclientauthenticityisaninfrastructureissue.Theyaredifferentconcerns,andthus,theyhavetobeseparated.

Thebestwaythattheservletstandardprovidesforusisaservletfilter.Aservletfilterisaclassinvokedbytheservletcontainerbeforetheservletitselfifthefilterisconfigured.Thefiltercanbeconfiguredintheweb.xmlconfigurationfileoftheservletcontainerorbyusinganannotationwhenweusetheSpringboot.ThefilterdoesnotonlygettherequestandresponseasparametersbutalsoathirdargumentoftheFilterChaintypethatitshouldusetocalltheservletorthenextfilterinthechain.

Therecanbemorethanonefilterdefinedandtheygetchainedup.Thefiltermay,atitsdiscretion,decide

Page 595:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

tocallornottocallthenextinthechain.

Weputourservletfilterintotheauthsub-packageofourapplication:

packagepackt.java9.by.example.mybusiness.productinformation.auth;

import...

@Component

publicclassAuthFilterimplementsFilter{

privatestaticLoggerlog=

LoggerFactory.getLogger(AuthFilter.class);

publicstaticfinalintNOT_AUTHORIZED=401;

@Override

publicvoidinit(FilterConfigfilterConfig)

throwsServletException{

}

@Override

publicvoiddoFilter(ServletRequestrequest,

ServletResponseresponse,

FilterChainchain)

throwsIOException,ServletException{

HttpServletRequesthttpRequest=

(HttpServletRequest)request;

finalStringsecret=

httpRequest.getHeader("X-PartnerSecret");

log.info("Partnersecretis{}",secret);

if("packt".equals(secret)){

chain.doFilter(request,response);

}else{

HttpServletResponsehttpResponse=

Page 596:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

(HttpServletResponse)response;

httpResponse.sendError(NOT_AUTHORIZED);

}

}

@Override

publicvoiddestroy(){

}

}

ThefilterimplementstheFilterinterfacethatdefinesthreemethods.Inourcase,wedonothaveanyparameterstoconsiderinthefilter,andwedonotallocateanyresourcestorelease;thus,bothinitanddestroymethodsareempty.ThemainworkofthefilteristhedoFiltermethod.Ithasthreeparameters,twoofthemarethesameastheparametersofaservletandthethirdisFilterChain.

TherequestisconvertedtoHttpServletRequest,sowecangetaccesstotheX-PartnerSecretheaderthroughthegetHeadermethod.Ifthevaluesentinthisheaderfieldisgood,wecallthenextinthechain.Inourapplication,therearenomorefiltersconfigured;therefore,thenextinthechainistheservlet.Ifthesecretisnotacceptable,thenwedonotcallthenextinthechain.Instead,wereturnthe401NotAuthorizedHTTPerrortotheclient.

Inthisapplication,thesecretisverysimple.Thisistheconstantstringpackt.Thisisnotreallyabigsecret,especiallynowthatitispublishedinthisbook.Areal-lifeapplicationwouldrequiresomethingmorecrypticandlessknown.Itisveryprobablethateachpartnerwouldusedifferentsecretsandthatthesecrethastochangefromtimetotime.

Whenthereisanerrorconditioninaservletthatourprogramhandles,itisagoodpracticetousetheHTTPerrorhandlingmechanism.Insteadofsendingbackamessagewiththestatuscode200OKandexplaining,forexample,inaJSONformatthattheauthenticationwasnotsuccessful,wehavetosendbackthe401code.Thisisdefinedbythestandardanddoesnotneedanyfurtherexplanationordocumentation.

Thereisonethingleftinourprogram,andthatisauditlogging.

Page 597:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 598:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AuditloggingandAOPWehavelogginginoursamplecodeandforthatweuseslf4j,whichwecoveredinthepreviouschapter.Loggingismoreorlessthedecisionofthedeveloperandsupportstechnicallevelsofoperation.There,wealsotouchedonafewsentenceauditloggings.Thistypeofloggingisusuallyexplicitlyrequiredinafunctionalrequirement.

Generally,AOPisseparatingthedifferentaspectsofcodefunctionalityintoseparatecodefragments,andimplementingthemindependentofeachother.Thisisverymuchthesingleresponsibilityprinciple.Thistime,itisimplementedinawaythatnotonlythedifferentfunctionalitiesareimplementedseparatelybutalsohowweconnectthemtogetherisdefinedseparately.WhatisexecutedbeforeandafterwhatotherpartsareencodedseparatelygetstotheSpringconfiguration.Wehaveseensomethingsimilaralready.Thedependenciesthataclassneedstoproperlyoperatearedefinedinaseparatesegment(XMLorJavacode).ItisnotasurprisethatinthecaseofAOP,thesameisdoneusingSpring.Aspectsareconfiguredintheconfigurationfileorclass.

Atypicalaspectisauditlogging,andwewillusethisasanexample.Therearemanytopicsthatcanbeimplementedusingaspects,andsomeofthemareevenworthimplementingthatway.

Wedonotwanttoimplementtheauditloggingcodeineachbusinessmethodorclassthatneedsit.Instead,weimplementageneralaspectandconfigurethewiringsuchthatwheneverabeanmethodthatneedsauditloggingisinvoked,Springinvokestheauditlogging.

ThereareotherimportantterminologiesthatweshouldunderstandforAOPandespeciallyhowAOPcanbeconfiguredinSpring.

Thefirstandmostimportantistheaspect.Thisisthefunctionalitythatwewanttoimplement,inourexample,theauditlogging.

Joinpointisthepointinexecutionwhenanaspectisinvoked.Whenusingafull-scaleaspectsolutioninJavathatmodifiesthebytecodeofthegeneratedclass,ajoinpointcanbealmostanything.Itcanbeaccesstoafield,readorwrite;itcanbetheinvocationofamethodorexceptionthrowing.InthecaseofSpring,theclassbytecodeisnotmodified;thus,Springisnotabletoidentifytheaccessofafieldoranexceptionthrowing.UsingSpring,ajoinpointisalwaysusedwhenamethodisinvoked.

Anadviceishowtheaspectisinvokedatthejoinpoint.Itcanbebeforeadvice,afteradvice,oraroundadvice.Whentheadviceisbefore,theaspectisinvokedbeforethemethodiscalled.Whentheadviceisafter,theaspectisinvokedafterthemethodisinvoked.Aroundmeansthattheaspectisinvokedbeforethemethodcall,andtheaspectalsohasanargumenttocallthemethodandstillperformsomeactionsafterthemethodiscalled.Thisway,thearoundadviceisverysimilartoservletfilters.

Thebeforeadviceiscalledbeforethemethodcall,andafteritreturns,theframeworkwillinvokethemethod.Thereisnowayfortheaspecttopreventtheinvocationoftheoriginalmethod.Theonlyexceptioniswhentheaspect,well,throwsanexception.

Page 599:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Theafteradviceisalsoaffectedbyexceptions.Therecanbeanafterreturningadvicethatisinvokedwhenthemethodisreturning.Theafterthrowingisinvokedonlyifthemethodwerethrowinganexception.Afterfinallyisinvokedinthecaseofanexceptionorreturn.

Pointcutisaspecialstringexpressionthatidentifiesjoinpoints.Apointcutexpressionmaymatchzero,one,ormorejoinpoints.Whentheaspectisassociatedwithapointcutexpression,theframeworkwillknowthejoinpointsandwhenandwheretoinvoketheaspect.Inotherwords,pointcutisthestringthattellswhenandforwhichmethodtoinvoketheaspect.

EventhoughSpringimplementationofAOPdoesnotuseAspectJanddoesnotmodifythebytecodethatwascreatedfortheclasses,itsupportsthepointcutexpressionlanguage.AlthoughthisexpressionlanguageprovidesmorefeaturesthanwhatSpringimplements,itisawell-establishedandwidelyusedandacceptedexpressionlanguagetodescribepointcuts,anditjustwouldnotmakesensetoinventsomethingnew.

Introductionisaddingmethodsorfieldstoatypethatalreadyexistsanddoingitduringruntime.SpringallowsthisAOPfunctionalitytoaddaninterfacetoanexistingtypeandaddanimplementationoftheinterfaceintheformofanadviceclass.Inourexample,wedonotusethisfunctionality.

Targetobjectistheobjectthatisbeingadvisedbytheaspect.Thisisthebeanthatcontainsthemethodaroundtheaspect,thatis,beforeoraftertheaspectisinvoked.

Thatwasjustacondensedsetofdefinitions,almostlikeinamathbook.Ifyoudidnotgetthepointjustreadingit,don'tworry.Ididnotunderstanditeither.Thatiswhywehavethefollowingexample,afterwhichallwejustcoveredwillmakemoresense:

packagepackt.java9.by.example.mybusiness.productinformation;

import...

@Configuration

@Aspect

publicclassSpringConfigurationAspect{

privatestaticLoggerlog=

LoggerFactory.getLogger("AUDIT_LOG");

@Around("execution(*byId(..))")

publicProductInformationbyIdQueryLogging(

ProceedingJoinPointjp)

throwsThrowable{

log.info("byIdqueryisabouttorun");

ProductInformationpi=

(ProductInformation)jp.proceed(jp.getArgs());

log.info("byIdquerywasexecuted");

returnpi;

}

@Around("execution(*url(..))")

publicStringurlCreationLogging(ProceedingJoinPointjp)

throwsThrowable{

log.info("urlistobecreated");

Stringurl=(String)jp.proceed(jp.getArgs());

log.info("urlcreatedwas"+url);

returnurl;

}

}

Theclassisannotatedwiththe@ConfigurationannotationsothatSpringknowsthatthisclasscontainstheconfiguration.The@Aspectannotationdenotesthatthisconfigurationmayalsocontainaspectdefinitions.

Page 600:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

The@Aroundannotationonthemethodsgivesthetypeofadvice,andtheargumentstringfortheannotationisthepointcutexpression.Ifthetypeofadviceisdifferent,oneoftheannotations,@Before,@After,@AfterReturning,or@AfterThrowing,shouldbeused.

Inourexample,weusethe@Aroundaspecttodemonstratethemostcomplexscenario.Welogtheexecutionofthetargetmethodbeforeandaftertheexecutionofthemethod,andwealsocalltheoriginalmethodthroughtheProceedingJoinPointobject.Becausethetwoobjectsreturndifferenttypesandwewanttologdifferently,wedefinetwoaspectmethods.

Theargumentoftheadviceannotationisthepointcutstring.Inthiscase,itisasimpleone.Thefirstone,execution(*byId(..)),saysthattheaspectshouldbeinvokedforanyexecutionofanymethodthathasthenamebyIdandhasanyarguments.Thesecondisverysimilar,exceptthenameofthemethodisdifferent.Thesearesimplepointcutexpressions,butinalargeapplicationthatheavilyusesAOP,theycanbeverycomplex.

ThepointcutexpressionsyntaxinSpringmainlyfollowsthesyntaxusedbyAspectJ.Theexpressionusesthenotionofpointcutdesignator(PCD)thatisusuallyexecution.Itisfollowedbythepatternthatdefineswhichmethodtointercept.Thegeneralformatisasfollows:

execution(modifiers-pattern?ret-type-patterndeclaring-type-pattern?name-pattern(param-pattern)throws-pattern?)

Exceptforthereturntypepart,allotherpartsareoptional.Forexample,wecanwritethefollowing:

execution(public**(..))

Thiswillinterceptallpublicmethods.Thefollowingexpressioninterceptsallmethodsthathaveanamestartingwithset:

execution(*set*(..))

Wecanusethe*characterasajokerinthesamewayaswecanuseitonthecommandlineinWindowsorUnixshell.Theargumentmatchingdefinitionisabitmorecomplex.(..)meansanyarguments,()meansnoarguments,and(*)meansexactlyoneargumentofanytype.Thelastonecanalsobeusedwhentherearemorearguments;forexample,(*,Integer)meansthattherearetwoarguments,thesecondbeinganInteger,andwejustdonotcarewhatthetypeofthefirstoneis.

Pointcutexpressionscanbemorecomplex,joiningtogethermatchexpressionswiththe&&(and)and||(or)logicaloperators,orusingthe!(negation)unaryoperator.

Usingthe@Pointcut()annotation,theconfigurationcandefinepointcutsputtingtheannotationsonmethods.Forexample,considerthefollowing:

@Pointcut("execution(*packt.java.9.by.example.service.*.*(..))")

publicvoidbusinessService(){}

Itwilldefineajoinpointforanymethodthatisimplementedinanyclassinthepackt.java.9.by.example.servicepackage.ThismerelydefinesthepointcutexpressionandassignsittothenamebusinessService,whichisgivenbythenameofthemethod.Later,wecanrefertothisexpressioninaspectannotations,forexample:

Page 601:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

@After("businessService()")

Notethattheuseofthemethodispurelyforitsname.ThismethodisnotinvokedbySpring.Itisonlyusedtoborrowitsnametotheexpressionthatisdefinedonitusingthe@Pointcutannotation.Thereisaneedforsomething,suchasamethod,toputthisannotationon,andsincemethodshavenames,whynotuseit:Springdoesit.Whenitscanstheconfigurationclassesandseestheannotation,itassignsitinitsinternalstructurestothenameofthemethod,andwhenthatname(alongwiththeparenthesis,toconfusethenoviceprogrammermimickingamethodcall)isused,itlooksuptheexpressionforthatname.

AspectJdefinesotherdesignators.SpringAOPrecognizessomeofthem,butitthrowsIllegalArgumentExceptionbecauseSpringimplementsonlymethodexecutionpointcuts.AspectJ,ontheotherhand,canalsointerceptobjectcreationforwhichthePCDisinitialization,asanexample.SomeotherPCDs,inadditiontoexecution,canlimitanexecutionPCD.Forexample,thePCD,within,canbeusedtolimittheaspecttojoinpointsbelongingtoclasseswithincertainpackages,orthe@targetPCDcanbeusedtolimitthematchingtomethodsinobjectsthathavetheannotationgivenbetween(and)afterthekeyword@targetinthepointcutexpression.

ThereisaPCDthatSpringusesthatdoesnotexistinAspectJ.Thisisabean.Youcandefineapointcutexpressionthatcontainsbean(namepattern)tolimitthejoinpointtomethodexecutionsthatareinthenamedbean.Thepatterncanbetheentirenameoritcanbe,asalmostanyPCDexpressionmatching,*asajokercharacter.

Page 602:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 603:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Dynamicproxy-basedAOPSpringAOP,whenfirstpresentedtoJavaprogrammers,seemslikemagic.HowdoesithappenthatwehaveavariableofclassXandwecallsomemethodonthatobject,butinstead,itexecutessomeaspectbeforeorafterthemethodexecution,orevenaroundit,interceptingthecall

ThetechniquethatSpringdoesiscalleddynamicproxy.Whenwehaveanobject,whichimplementsaninterface,wecancreateanotherobject—theproxyobject—thatalsoimplementsthatinterface,buteachandeverymethodimplementationinvokesadifferentobjectcalledhandler,implementingtheJDKinterface,InvocationHandler.Whenamethodoftheinterfaceisinvokedontheproxyobject,itwillcallthefollowingmethodonthehandlerobject:

publicObjectinvoke(Objecttarget,Methodm,Object[]args)

Thismethodisfreetodoanything,evencallingtheoriginalmethodonthetargetobjectwiththeoriginalormodifiedargument.

Whenwedonothaveaninterfaceathandthattheclasstobeproxiedimplements,wecannotuseJDKmethods.Luckily,therearewidelyusedlibraries,suchascglib,whicharealsousedbySpringandthatcandosomethingsimilar.Cglibcancreateaproxyobjectthatextendstheoriginalclassandimplementsitsmethods,invokingthehandlerobject'sinvokemethodinawaysimilartohowtheJDKversiondoesfortheinterfacemethods.

ThesetechnologiescreateandloadclassesintotheJavamemoryduringruntime,andtheyareverydeeptechnicaltools.Theyareadvancedtopics.IdonotsaynottoplaywiththemwhilebeinganoviceJavaprogrammer.Afterall,whatcanhappen?Javaisnotaloadedgun.Itis,however,importantthatyoudonotloseyourinterestwhenyoudonotunderstandsomeofthedetailsorsomethingdoesnotworkfirst.Orsecond.Orthird...Keepswimming.

AOPimplementationinSpringworksbygeneratingproxyobjectsforthetargetobjects,andthehandlersinvoketheaspectsthatwedefineintheSpringconfiguration.Thisisthereasonyoucannotputaspectsonfinalclassesoronfinalmethods.Also,youcannotconfigureaspectsonprivateorprotectedmethods.Theprotectedmethodscouldbeproxiedinprinciple,butthisisnotagoodpractice,andthusSpringAOPdoesnotsupportit.Similarly,youcannotputaspectsonclassesthatarenotSpringbeans.Theyarecreatedby

Page 604:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

thecodedirectlyandnotthroughSpringandhavenochancetoreturnaproxyinsteadoftheoriginalobjectwhentheobjectiscreated.Simplyput,ifSpringisnotaskedtocreatetheobject,itcannotcreateacustomone.Thelastthingwewanttodoistoexecutetheprogramandseehowtheaspectsperform.Theimplementationofourauditloggingisextremelysimple.Weusethestandardlogging,whichisnotreallysufficientforareal-lifeapplicationofauditlogging.Theonlyspecialthingwedoisthatweusealoggeridentifiedbythename,AUDIT_LOGandnotbythenameofaclass.Thisisalegitimateuseoftheloggersinmostoftheloggingframeworks.Inspiteofthefactthatweusuallyusetheclasstoidentifythelogger,itisabsolutelypossibletouseastringtoidentifyalogger.Inthecaseofourlogging,thisstringwillalsobeprintedontheconsoleintheloglines,anditwillvisuallystandout.

Considerthefollowingcommand:

gradle-Dspring.profiles.active=productionbootRun

Ifweagainstarttheapplicationwiththeprecedingcommand,startsoapUIfortheproject,startthemockservices,andexecutethetest,wewillseeontheconsolethefollowingloglinesthattheaspectsprint:

2016-11-1019:14:09.559INFO74643---[nio-8080-exec-1]o.a.c.c.C.[Tomcat].[localhost].[/]:InitializingSpringFrameworkServlet'dispatcherServlet'

2016-11-1019:14:09.567INFO74643---[nio-8080-exec-1]o.s.web.servlet.DispatcherServlet:FrameworkServlet'dispatcherServlet':initializationstarted

2016-11-1019:14:09.626INFO74643---[nio-8080-exec-1]o.s.web.servlet.DispatcherServlet:FrameworkServlet'dispatcherServlet':initializationcompletedin59ms

2016-11-1019:14:09.629INFO74643---[nio-8080-exec-1]p.j.b.e.m.p.auth.AuthFilter:Partnersecretispackt

2016-11-1019:14:09.655INFO74643---[nio-8080-exec-1]AUDIT_LOG:byIdqueryisabouttorun

2016-11-1019:14:09.666INFO74643---[nio-8080-exec-1]AUDIT_LOG:urlistobecreated

2016-11-1019:14:09.691INFO74643---[nio-8080-exec-1]AUDIT_LOG:urlcreatedwashttp://localhost:8083/inventory/{id}

2016-11-1019:14:09.715INFO74643---[nio-8080-exec-1]p.j.b.e.m.p.l.RestClientProductLookup:amount{id:123,amount:100}.

2016-11-1019:14:09.716INFO74643---[nio-8080-exec-1]p.j.b.e.m.p.l.RestClientProductLookup:Thereitemsfrom123.Weareoffering

2016-11-1019:14:09.716INFO74643---[nio-8080-exec-1]AUDIT_LOG:urlistobecreated

2016-11-1019:14:09.716INFO74643---[nio-8080-exec-1]AUDIT_LOG:urlcreatedwashttp://localhost:8081/product/{id}

2016-11-1019:14:09.725INFO74643---[nio-8080-exec-1]AUDIT_LOG:byIdquerywasexecuted

Page 605:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 606:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SummaryInthischapter,webuiltasimplebusinessapplicationthatsupportsbusiness-to-businesstransactions.WeimplementedaRESTserviceinamicroservices(almost)architectureusingthefeaturesthatareprovidedbythedefactostandardenterpriseframework:Spring.Lookingbackatthechapter,itisamazinghowfewlinesofcodewewrotetoachieveallthefunctionality,andthatisgood.Thelesscodeweneedtodevelopwhatwewant,thebetter.Thisprovesthepoweroftheframework.

Wediscussedmicroservices,HTTP,REST,JSON,andhowtousethemusingtheMVCdesignpattern.WelearnedhowSpringisbuiltup,whatmodulesarethere,howdependencyinjectionworksinSpring,andweeventouchedabitofAOP.ThiswasveryimportantbecausealongwithAOP,wediscoveredhowSpringworksusingdynamicproxyobjects,andthisissomethingthatisveryvaluablewhenyouneedtodebugSpringorsomeotherframeworkthatusesasimilarsolution(andthereareafewfrequentlyused).

Westartedtotestourcodeusingasimplebrowser,butafterthatwerealizedthatRESTservicesarebettertestedusingsomeprofessionaltestingtool,andforthatweusedsoapUIandbuiltupasimpleRESTtestsuitewithRESTteststepsandmockservices.

Havinglearntallthat,nothingwillstopusfromextendingthisapplicationusingverymodernandadvancedJavatechnologies,suchasreflection(whichwehavealreadytouchedonabitwhenwediscussedtheJDKdynamicproxy),Javastreams,lambdaexpressions,andscriptingontheserverside.

Page 607:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 608:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ExtendingOurE-CommerceApplication

Inthelastchapter,westarteddevelopingane-commerceapplicationandwecreatedthefunctionalitytolookupproductsbasedontheirIDand,also,bysomeparameters.Inthischapter,wewillextendthefunctionalitysothatwecanalsoordertheproductsweselected.Whiledoingso,wewilllearnnewtechnologies,focusingonfunctionalprogramminginJavaandonsomeotherlanguagefeatures,suchasreflectionandannotationhandlingduringruntime,andscriptinginterface.

Aswedidinthepreviouschapters,wewilldeveloptheapplicationstepbystep.Aswediscoverthenewlylearnttechnologies,wewillrefactorthecodetoenrollthenewtoolsandmethodstoproducemorereadableandeffectivecode.Wewillalsomimicthedevelopmentofreal-lifeprojectsinthesensethatatthestart,wewillhavesimplerequirements,andlater,newrequirementswillbesetasourimaginedbusinessdevelopsandsellsmoreandmoreproducts.Wewillbecomeimaginedmillionaires.

Wewillusethecodebaseofthepreviouschapter,andwewilldevelopitfurther,though,inanewproject.WewilluseSpring,Gradle,Tomcat,andsoapUI,whicharenotnewafterwegotacquaintedwiththeseinthepreviouschapter.Inthischapter,youwilllearnthefollowingtopics:

AnnotationprocessingUsingreflectionFunctionalprogramminginJavausing:

LambdaexpressionsStreamsInvokingscriptsfromJava

Page 609:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 610:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TheMyBusinessorderingTheorderingprocessisalittlebitmorecomplicatedthanjustlookingupproducts.Theorderformitselflistsproductsandamounts,andidentifieswhothecustomerforthatorderis.Identifiersgivetheproducts.Allthatwehavetodoischeckthattheproductsareavailableinourstore,andwecandeliverthemtothegivencustomer.Thisisthesimplestapproach;however,withsomeproducts,therearemorerestrictions.Forexample,whensomebodyordersadesk-sidelamp,wedeliverthepowercordseparately.Thereasonforthisisthatthepowercordisspecifictothecountry.WedeliverdifferentpowercordstotheUnitedKingdomandtoGermany.Onepossibleapproachcouldbetoidentifythecountryofthecustomer.Butthisapproachdoesnottakeintoaccountthatourcustomersareresellers.AllcustomerscouldbelocatedintheUnitedKingdom,andatthesametimetheymaywanttodeliverthelampwiththepowercabletoGermany.Toavoidsuchsituationsandambiguity,itwouldbeaptthatourcustomersorderthedesk-sidelampandthepowercordasseparateitemsinthesameorder.Insomecases,wedeliverthedesk-sidelampwithoutthepowercord,butthisisaspecialcase.Weneedsomelogictoidentifythesespecialcases.Therefore,wehavetoimplementlogictoseeifthereisapowercordforadesk-sidelampandifthereisnoautomatichandlingoftheorder,itisrefused.Itdoesnotmeanthatwewillnotdelivertheproduct.Wewillonlyputtheorderinaqueueandsomeoperatorwillhavetolookatit.

Theproblemwiththisapproachisthatthedesk-sidelampisonlyoneproductthatneedsconfigurationsupport.Themoreproductswehave,themorespecialitiestheymayhave,andthepieceofcodethatcheckstheconsistencyofanorderbecomesmoreandmorecomplexuntilitreachesalevelofcomplexitythatisnotmanageable.Whenaclassormethodbecomestoocomplex,theprogrammersrefactorit,splittingupthemethodorclassintosmallerpieces.Wehavetodothesamewiththeproductchecking.Weshouldn'ttrytocreateonehugeclassthatchecksfortheproductandallthepossibleorderconstellations,butratherweshouldhavemanysmallercheckssothateachchecksonlyonesmallset.

Checkingforconsistencyissimplerinsomecases.Checkingwhetherthelamphasapowercordhasacomplexityanynoviceprogrammercanprogram.Weusethisexampleinourcodebecausewewanttofocusontheactualstructureofthecode,andnotonthecomplexnatureofthecheckitself.Inreallife,however,thecheckscanbefairlycomplex.Imagineashopthatsellscomputers.Itputsaconfigurationtogether:powersupply,graphiccards,andmotherboard,theappropriateCPU,andthememory.Therearemanychoicesandsomeofthemmaynotworktogether.Inareal-lifesituation,weneedtocheckthatthemotherboardiscompatiblewiththememoryselected,thatithasasmanybanksasareintheorder,thattheyareappropriatelypaired(somememoriescanonlybeinstalledinpairs),thatthereisacompatibleslotforthegraphicscard,andthatthepowerhasenoughwattstoreliablyrunthewholeconfiguration.Thisisverycomplexandisbetternotmixedupwiththecodethatchecksifthereisapowercordforalamp.

Page 611:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 612:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Settinguptheproject

SincewearestillusingSpringboot,thebuildfiledoesnotneedanymodification;wewilluseitaswewillusethesamefileasinthelastchapter.Thepackagestructure,however,isabitdifferent.Thistime,wedosomethingmorecomplicatedthangettingarequestandrespondingtowhateverthebackendservicesdelivertous.Now,wehavetoimplementcomplexbusinesslogicthat,aswewillsee,needsmanyclasses.Whenwehavemorethan10classes,giveortake,inacertainpackage,itistimetothinkaboutputtingthemintoseparatepackages.Theclassesthatarerelatedtoeachotherandhaveasimilarfunctionalityshouldbeputintoonepackage.Thisway,wewillhaveapackageforthefollowing:

Thecontrollers(thoughwehaveonlyoneinthisexample,butusuallytherearemore)Datastoringbeansthathavenomorefunctionalitythanstoringdata,thus,fields,setters,andgettersCheckersthatwillhelpuscheckpowercordswhenadesk-sidelampisorderedServicesthatperformdifferentservicesforthecontrollerThemainpackageforourprogramthatcontainstheApplicationclass,SpringConfiguration,andsomeinterfaces

Page 613:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 614:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

OrdercontrollerandDTOsWhenarequestcomestotheservertoorderabunchofproducts,itcomesinanHTTPSPOSTrequest.ThebodyoftherequestisencodedinJSON.Tillnow,wehadcontrollersthatwerehandlingGETparameters,buthandlingPOSTrequestsisnotmuchmoredifficultwhenwecanrelyonthedatamarshallingofSpring.Thecontrollercodeitselfissimple:

packagepackt.java9.by.example.mybusiness.bulkorder.controllers;

import...

@RestController

publicclassOrderController{

privateLoggerlog=

LoggerFactory.getLogger(OrderController.class);

privatefinalCheckerchecker;

publicOrderController(@AutowiredCheckerchecker){

this.checker=checker;

}

@RequestMapping("/order")

publicConfirmationgetProductInformation(@RequestBodyOrderorder){

if(checker.isConsistent(order)){

returnConfirmation.accepted(order);

}else{

returnConfirmation.refused(order);

}

}

}

Thereisonlyonerequestthatwehandleinthiscontroller:order.ThisismappedtotheURL,/order.TheorderisautomaticallyconvertedfromJSONtoanorderobjectfromtherequestbody.Thisiswhatthe@RequestBodyannotationasksSpringtodoforus.Thefunctionalityofthecontrollersimplycheckstheconsistencyoftheorder.Iftheorderisconsistent,thenweaccepttheorder;otherwise,werefuseit.Thereal-lifeexamplewillalsocheckthattheorderisnotonlyconsistentbutalsocomesfromacustomerwhoiseligibleforbuyingthoseproductsandthattheproductsareavailableinthewarehouseor,atleast,canbedelivered,basedonthepromisesandleadtimefromtheproducers.

Tochecktheconsistencyoftheorder,weneedsomethingthatdoesthisjobforus.Asweknowthatwehavetomodularizethecodeandnotimplementtoomanythingsinasingleclass,weneedacheckerobject.Thisisprovidedautomaticallybasedontheannotationontheclassandalsoontheconstructorofthecontrollerby@Autowired.

TheOrderclassisasimplebean,simplylistingtheitems:

packagepackt.java9.by.example.mybusiness.bulkorder.dtos;

import...;

publicclassOrder{

privateStringorderId;

privateList<OrderItem>items;

privateStringcustomerId;

...settersandgetters...

}

Thenameofthepackageisdtos,whichstandsforthepluralofDataTransferObject(DTO).DTOsareobjectsthatareusedtotransferdatabetweendifferentcomponents,

Page 615:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

usuallyoverthenetwork.Sincetheothersidecanbeimplementedinanylanguage,themarshalingcanbeJSON,XML,orsomeotherformatthatiscapableofdeliveringnothingbutdata.Theseclassesdonothaverealmethods.DTOsusuallyhaveonlyfields,setters,andgetters.

Thefollowingistheclassthatcontainsoneiteminanorder:

packagepackt.java9.by.example.mybusiness.bulkorder.dtos;

publicclassOrderItem{

privatedoubleamount;

privateStringunit;

privateStringproductId;

...settersandgetters...

}

Theorderconfirmationisalsointhispackage,andthoughthisisalsoatrueDTO,ithassomesimpleauxiliarymethods:

packagepackt.java9.by.example.mybusiness.bulkorder.dtos;

publicclassConfirmation{

privatefinalOrderorder;

privatefinalbooleanaccepted;

privateConfirmation(Orderorder,booleanaccepted){

this.order=order;

this.accepted=accepted;

}

publicstaticConfirmationaccepted(Orderorder){

returnnewConfirmation(order,true);

}

publicstaticConfirmationrefused(Orderorder){

returnnewConfirmation(order,false);

}

publicOrdergetOrder(){

returnorder;

}

publicbooleanisAccepted(){

returnaccepted;

}

}

Weprovidetwofactorymethodsfortheclass.Thisisalittleviolationofthesingleresponsibilityprinciplethatpuristshate.Mostofthetime,whenthecodebecomesmorecomplex,suchshortcutsbiteback,andthecodehastoberefactoredtobecleaner.Thepuristsolutionwouldbetocreateaseparatefactoryclass.Theuseofthefactorymethodseitherfromthisclassorfromaseparatedclassmakesthecodeofthecontrollermorereadable.

Themajortaskwehaveistheconsistencycheck.Thecode,tillthispoint,isalmosttrivial.

Page 616:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 617:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ConsistencycheckerWehaveaconsistencycheckerclass,andaninstanceofitisinjectedintothecontroller.Thisclassisusedtochecktheconsistency,butitdoesnotactuallyperformthecheckitself.Itonlycontrolsthedifferentcheckersthatweprovideandinvokesthemonebyonetodotherealwork.

Werequirethataconsistencychecker,suchastheonethatcheckswhethertheordercontainsapowercordwhenadesk-sidelampisordered,implementstheConsistencyCheckerinterface:

packagepackt.java9.by.example.mybusiness.bulkorder;

import...

publicinterfaceConsistencyChecker{

booleanisInconsistent(Orderorder);

}

ThemethodisInconsistentshouldreturntrueiftheorderisinconsistent.Itreturnsfalseifitdoesnotknowwhethertheorderisinconsistentornot,butfromtheaspectthattheactualcheckerexaminestheorder,thereisnoinconsistency.HavingseveralConsistencyCheckerclasses,wehavetoinvokeoneaftertheotheruntilonereturnstrueorweareoutofthem.Ifnoneofthemreturnstrue,thenwecansafelyassume,atleastfromtheautomatedcheckers'pointofview,thattheorderisconsistent.

Weknowatthestartofthedevelopmentthatwewillreallyhavealotofconsistencycheckersandnotallarerelevantforalloftheorders.Wewanttoavoidtheinvocationofeachcheckerforeachorder.Todoso,weimplementsomefiltering.Weletproductsspecifywhattypeofcheckstheyneed.Thisisapieceofproductinformation,suchasthesizeorthedescription.Toaccommodatethis,weneedtoextendtheProductInformationclass.

WewillcreateeachConsistencyCheckerinterface,implementingtheclasstobeaSpringbean(annotatedwiththe@Componentannotation),andatthesametime,wewillannotatethemwithanannotationthatspecifieswhattypeofcheckstheyimplement.Atthesametime,ProductInformationisextended,containingasetofAnnotationclassobjectsthatspecifywhichcheckerstoinvoke.Wecouldsimplylistthecheckerclassesinsteadoftheannotations,butthisgivesussomeextrafreedominconfiguringthemappingbetweentheproductsandtheannotations.Theannotationspecifiesthetypeoftheproducts,andthecheckerclassesareannotated.Thedesk-sidelamphasthePoweredDevicetype,andthecheckerclass,NeedPowercord,isannotatedwiththe@PoweredDeviceannotation.Ifthereisanyothertypeofproductsthatalsoneedsapowercord,thentheannotationofthattypeshouldbeaddedtotheNeedPowercordclass,andourcodewillwork.Sincewestartdivingdeepintoannotationsandannotationhandling,wehavetofirstlearnwhatannotationsreallyare.WehavealreadyusedannotationssinceChapter3,OptimizingtheSort,MakingCodeProfessionalbutallweknewwashowtousethem,andthatisusuallydangerouswithoutunderstandingwhatwedid.

Page 618:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 619:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AnnotationsAnnotationsareusedwiththe@characterinfrontofthemandcanbeattachedtopackages,classes,interfaces,fields,methods,methodparameters,generictypedeclarationanduse,and,finally,toannotations.Annotationscanbeusedalmosteverywhereandtheyareusedtodescribesomeprogrammetainformation.Forexample,the@RestControllerannotationdoesnotdirectlyalterthebehavioroftheOrderControllerclass.ThebehavioroftheclassisdescribedbytheJavacodethatisinside.TheannotationhelpsSpringtounderstandwhattheclassisandhowitcanandshouldbeused.WhenSpringscansallthepackagesandclassestodiscoverthedifferentSpringbeans,itseestheannotationontheclassandtakesitintoaccount.TherecanbeotherannotationsontheclassthatSpringdoesnotunderstand.Theymaybeusedbysomeotherframeworkorprogramcode.Springignoresthemasanywell-behavingframework.Forexample,aswewillseelater,wehaveinourcodebase,theNeedPowercordclass,whichisaSpringbeanand,assuch,[email protected],itisalsoannotatedwiththe@PoweredDeviceannotation.Springhasnoideaaboutwhatapowereddeviceis.Thisissomethingthatwedefineanduse.Springignoresthis.

Packages,classes,interfaces,fields,andsoon,canhavemanyannotationsattachedtothem.Theseannotationsshouldsimplybewritteninfrontofthedeclarationofthesyntacticalunittheyareattachedto.

Inthecaseofpackages,theannotationhastobewritteninfrontofthepackagenameinthepackage-info.javafile.ThisfilecanbeplacedinthedirectoryofthepackageandcanbeusedtoedittheJavaDocforthepackageandalsotoaddanannotationtothepackage.ThisfilecannotcontainanyJavaclasssincethename,package-info,isnotavalididentifier.

Wecannotjustwriteanythinginfrontofanythingasanannotation.Annotationsshouldbedeclared.TheyareintheruntimeofJavaspecialinterfaces.TheJavafilethatdeclaresthe@PoweredDeviceannotation,forexample,lookslikethis:

packagepackt.java9.by.example.mybusiness.bulkorder.checkers;

importjava.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

public@interfacePoweredDevice{

}

The@characterinfrontoftheinterfacekeywordshowsusthatthisisaspecialone:anannotationtype.Therearesomespecialrules;forexample,anannotationinterfaceshouldnotextendanyotherinterface,notevenanannotationone.Ontheotherhand,thecompilerautomaticallymakestheannotationinterfacesothatitextendstheJDKinterface,java.lang.annotation.Annotation.

Annotationsareinthesourcecode,andthus,theyareavailableduringthecompilationprocess.Theycanalsoberetainedbythecompilerandputintothegeneratedclassfiles,andwhentheclassloaderloadstheclassfile,theymayalsobeavailableduringruntime.Thedefaultbehavioristhatthecompilerstorestheannotationalongwiththeannotatedelementintheclassfile,buttheclassloaderdoesnotkeepitavailableforruntime.

Page 620:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Tohandleannotationsduringthecompilationprocess,theJavacompilerhastobeextendedusingannotationprocessors.ThisisafairlyadvancedtopicandthereareonlyafewexamplesyoucanmeetwhileworkingwithJava.AnannotationprocessorisaJavaclassthatimplementsaspecialinterfaceandisinvokedbythecompilerwhenitprocessesanannotationinthesourcefilethattheprocessorisdeclaredtohaveaninterestin.

Page 621:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 622:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AnnotationretentionSpringandotherframeworksusuallyhandleannotationsduringruntime.Thecompilerandtheclassloaderhavetobeinstructedthattheannotationistobekeptavailableduringruntime.Todoso,theannotationinterfaceitselfhastobeannotatedusingthe@Retentionannotation.ThisannotationhasoneparameteroftheRetentionPolicytype,whichisanenum.Wewillsoondiscusshowannotationparametersshouldbedefined.

Itisinterestingtonotethatthe@Retentionannotationontheannotationinterfacehastobeavailableintheclassfile;otherwise,theclassloaderswouldnotknowhowtotreatanannotation.Howdowesignalthatanannotationistobekeptbythecompilerafterthecompilationprocess?Weannotatetheannotationinterfacedeclaration.Thus,thedeclarationof@Retentionisannotatedbyitselfanditisdeclaredtobeavailableinruntime.

Theannotationdeclarationcanbeannotatedusing@Retention(RetentionPolicy.SOURCE),@Retention(RetentionPolicy.CLASS),or@Retention(RetentionPolicy.RUNTIME).

Page 623:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 624:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Annotationtarget

Thelastretentiontypewillbethemostfrequentused.Therearealsootherannotationsthatcanbeusedonannotationdeclarations.The@Targetannotationcanbeusedtorestricttheuseoftheannotationtocertainlocations.Theargumenttothisannotationiseitherasinglejava.lang.annotation.ElementTypevalueoranarrayofthesevalues.Thereisagoodreasontorestricttheuseofannotations.Itismuchbettertogetacompilationtimeerrorwhenweplaceanannotationinthewrongplacethanhuntingduringruntimewhytheframeworkignoresourannotation.

Page 625:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 626:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AnnotationparametersAnnotations,aswesaw,canhaveparameters.Todeclaretheseparametersinthe@interfacedeclarationoftheannotation,weusemethods.Thesemethodshaveanameandareturnvalue,buttheyshouldnothaveanargument.Youmaytrytodeclaresomeparameters,buttheJavacompilerwillbestrictandwillnotcompileyourcode.

Thevaluescanbedefinedattheplacewheretheannotationisused,usingthenameofthemethodandwiththe=character,assigningtothemsomevaluethatiscompatiblewiththetypeofthemethod.Forexample,let'ssupposethatwemodifythedeclarationoftheannotationPoweredDevicetothefollowing:

public@interfaceParameteredPoweredDevice{

StringmyParameter();

}

Insuchacase,attheuseoftheannotation,weshouldspecifysomevaluefortheparameter,suchasthefollowing:

@Component

@ParameteredPoweredDevice(myParameter="1966")

publicclassNeedPowercordimplementsConsistencyChecker{

...

Ifthenameoftheparameterisavalueandattheplaceofuseoftheannotationthereisnootherparameterdefined,thenthename,"value",maybeskipped.Forexample,modifyingthecodeasfollowsisahandyshorthandwhenwehaveonlyoneparameter:

public@interfaceParameteredPoweredDevice{

Stringvalue();

}

...

@Component

@ParameteredPoweredDevice("1966")

publicclassNeedPowercordimplementsConsistencyChecker{

...

Wecandefineoptionalparametersalsousingthedefaultkeywordfollowingthemethoddeclaration.Inthiscase,wehavetodefineadefaultvaluefortheparameter.Modifyingthesampleannotationwehavefurther,westillcan,butneednot,specifythevalue.Inthelattercase,itwillbeanemptystring:

public@interfaceParameteredPoweredDevice{

Stringvalue()default"";

}

Sincethevaluewespecifyshouldbeconstantandcalculableduringcompiletime,thereisnotmuchuseofcomplextypes.Annotationparametersareusuallystrings,integers,andsometimes,doubles,orotherprimitivetypes.Theexactlistofthetypesgivenbythelanguagespecificationisasfollows:

Primitive(double,int,andsoon)StringClassAnenumAnotherannotation

Page 627:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Anarrayofanyoftheaforementionedtypes

WehaveseenexamplesofStringandalsothatenum:RetentionandTargetbothhaveenumparameters.Theinterestingpartwewanttofocusonisthelasttwoitemsoftheprecedinglist.

Whenthevalueoftheparameterisanarray,thevaluecanbespecifiedascomma-separatedvaluesbetweenthe{and}characters.Forexample:

String[]value();

Thiscanthenbeaddedtothe@interfaceannotationwecanwrite:

@ParameteredPoweredDevice({"1966","1967","1991"})

However,incasethereisonlyonevaluewewanttopassastheparametervalue,wecanstillusetheformat:

@ParameteredPoweredDevice("1966")

Inthiscase,thevalueoftheattributewillbeanarrayoflength1.Whenthevalueofanannotationisanarrayofannotationtypes,thingsgetabitmorecomplex.Wecreatean@interfaceannotation(notethepluralinthename):

@Retention(RetentionPolicy.RUNTIME)

public@interfacePoweredDevices{

ParameteredPoweredDevice[]value()default{};

}

Theuseofthisannotationcouldbeasfollows:

@PoweredDevices(

{@ParameteredPoweredDevice("1956"),@ParameteredPoweredDevice({"1968","2018"})}

)

NotethatthisisnotthesameashavingtheParameteredPoweredDeviceannotationwiththreeparameters.Thisisanannotationthathastwoparameters.Eachparameterisanannotation.Thefirsthasonestringparameterandthesecondhastwo.

Asyoucansee,annotationscanbefairlycomplex,andsomeoftheframeworks(orrathertheprogrammerswhocreatedthem)ranamokusingthem.Beforeyoustartwritingaframework,researchtoseewhetherthereisalreadyaframeworkthatyoucanuse.Also,checkwhetherthereissomeotherwaytosolveyourproblem.99%ofannotationhandlingcodecouldbeavoidedandmadesimpler.Thelesscodewewriteforthesamefunctionality,thehappierweare.Weprogrammersarethelazytypesandthisisthewayithastobe.

Thelastexample,wheretheparameteroftheannotationisanarrayofannotations,isimportanttounderstandhowwecancreaterepeatableannotations.

Page 628:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 629:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

RepeatableannotationsAnnotatethedeclarationoftheannotationwith@Repeatabletodenotethattheannotationcanbeappliedmultipletimesatoneplace.Theparametertothisannotationisanannotationtypethatshouldhaveaparameteroftype,whichisanarrayofthisannotation.Don'ttrytounderstand!I'llgiveanexampleinstead.Ialreadyhave,infact:[email protected]@ParameteredPoweredDevice.Considerthatwenowannotatethis@interfaceasthefollowing:

...

@Repeatable(PoweredDevices.class)

public@interfaceParameteredPoweredDevice{

...

Then,wecansimplifytheuseof@ParameteredPoweredDevice.WecanrepeattheannotationmultipletimesandtheJavaruntimewillautomaticallyencloseitinthewrappingclass,which,inthiscase,[email protected],thefollowingtwowillbeequivalent:

...

@ParameteredPoweredDevice("1956")

@ParameteredPoweredDevice({"1968","2018"})

publicclassNeedPowercordimplementsConsistencyChecker{

...

@PoweredDevices(

{@ParameteredPoweredDevice("1956"),@ParameteredPoweredDevice({"1968","2018"})}

)

publicclassNeedPowercordimplementsConsistencyChecker{

...

ThereasonforthiscomplexapproachisagainanexampleofbackwardcompatibilitythatJavastrictlyfollows.AnnotationswereintroducedinJava1.5andrepeatableannotationshavebeenavailableonlysinceversion1.8.WewillsoontalkaboutthereflectionAPIthatweusetohandletheannotationsduringruntime.ThisAPIinthejava.lang.reflect.AnnotatedElementinterfacehasagetAnnotation(annotationClass)method,whichreturnsanannotation.Ifasingleannotationcanappearmorethanonceonaclass,method,andsoon,thenthereisnowayofcallingthismethodtogetallthedifferentinstanceswithallthedifferentparameters.Backwardcompatibilitywasensuredbyintroducingthecontainingtypethatwrapsthemultipleannotations.

Page 630:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 631:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Annotationinheritance

Annotations,justlikemethodsorfields,canbeinheritedbetweenclasshierarchies.Ifanannotationdeclarationismarkedwith@Inherited,thenaclassthatextendsanotherclasswiththisannotationcaninheritit.Theannotationcanbeoverriddenincasethechildclasshastheannotation.BecausethereisnomultipleinheritanceinJava,annotationsoninterfacescannotbeinherited.Evenwhentheannotationisinherited,theapplicationcodethatretrievestheannotationofacertainelementcandistinguishbetweentheannotationsthatareinheritedandthosethataredeclaredontheentityitself.Therearemethodstogettheannotationsandseparatemethodstogetthedeclaredannotationsthataredeclaredontheactualelement,andnotinherited.

Page 632:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 633:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

@Documentedannotations

The@Documentedannotationexpressestheintentthattheannotationispartofthecontractoftheentityand,thisway,ithastogetintothedocumentation.ThisisanannotationthattheJavaDocgeneratorlooksatwhencreatingthedocumentationforanelementthatreferencesthe@Documentedannotation.

Page 634:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 635:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JDKannotationsThereareotherannotationsdefinedintheJDKinadditiontothosethataretobeusedtodefineannotations.Wehavealreadyseensomeofthese.Themostfrequentlyusedisthe@Overrideannotation.Whenthecompilerseesthisannotation,itchecksthatthemethodreallyoverridessomeinheritedmethod.Failingtodosowillresultinanerror,savingusfrommiserableruntimedebugging.

The@Deprecatedannotationsignalsinthedocumentationofamethod,class,orsomeotherelementthattheelementisnottobeused.Itisstillthereinthecode,becausesomeusersmaystilluseit,butinthecaseofanewdevelopmentthatdependsonthelibrarycontainingtheelement,thenewlydevelopedcodeshouldnotuseit.Theannotationhastwoparameters.Oneparameterissince,whichcanhaveastringvalueandmaydeliverversioninformationabouthowlongorsincewhichversionofthemethod,orclassisdeprecated.TheotherparameterisforRemoval,whichshouldbetrueiftheelementwillnotappearinthefutureversionsofthelibrary.Somemethodsmaybedeprecatedbecausetherearebetteralternativesbutthedevelopersdonotintendtoremovethemethodfromthelibrary.Insuchacase,theforRemovalcanbesettofalse.

The@SuppressWarningannotationisalsoafrequentlyusedone,thoughitsuseisquestionable.Itcanbeusedtosuppresssomeofthewarningsofthecompiler.Itisrecommendedtowritecode,ifpossible,whichcanbecompiledwithoutanywarning.

The@FunctionalInterfaceannotationdeclaresthataninterfaceintendstohaveonlyonemethod.Suchinterfacescanbeimplementedaslambdaexpressions.Youwilllearnaboutlambdaexpressionslaterinthischapter.Whenthisannotationisappliedonaninterfaceandthereismorethanonemethoddeclaredintheinterface,thecompilerwillsignalcompilationerror.Thiswillpreventanydeveloperearlyonfromaddinganothermethodtoaninterfaceintendedtobeusedtogetherwithfunctionalprogrammingandlambdaexpressions.

Page 636:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 637:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Usingreflection

Nowthatyouhavelearnthowtodeclareannotationsandhowtoattachthemtoclassesandmethods,wecanreturntoourProductInformationclass.Recallthatwewantedtospecifythetypeofproductsinthisclassandthateachproducttypeisrepresentedbyan@interfaceannotation.Wehavealreadylisteditinthepreviousfewpages,theonewewillimplementinour@PoweredDeviceexample.Wewilldevelopthecodeassumingthatlatertherewillbemanysuchannotations,producttypes,andconsistencycheckersthatareannotatedwith@Componentandwithoneormoreofourannotations.

Page 638:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 639:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

GettingannotationsWewillextendtheProductInformationclasswiththefollowingfield:

privateList<Class<?extendsAnnotation>>check;

SincethisisaDTO,andSpringneedsthesettersandgetters,wewillalsoaddanewgetterandsettertoit.Thisfieldwillcontainthelistofclassesthateachclassimplementoneofourannotationsandalsothebuilt-inJDKinterface,Annotation,becausethatisthewaytheJavacompilergeneratesthem.Atthispoint,thismaybeabitmurkybutIpromisethatthedawnwillbreakandtherewillbelightaswegoon.

Togettheproductinformation,wehavetolookitupbyID.Thisistheinterfaceandservicethatwedevelopedinthelastchapter,except,thistime,wehaveanothernewfield.Thisis,infact,asignificantdifferencealthoughtheProductLookupinterfacedidnotchangeatall.Inthelastchapter,wedevelopedtwoversions.Oneoftheversionswasreadingthedatafromapropertiesfile,theotheronewasconnectingtoaRESTservice.

PropertiesfilesareuglyandoldtechnologybutamustifeveryouintendtopassaJavaintervieworworkonenterpriseapplicationsdevelopedatthestartofthe21stcentury.Ihadtoincludeitinthelastchapter.Itwasmyownurgetoincludeitinthebook.Atthesametime,whilecodingforthischapter,Ididnothavethestomachtokeepusingit.IalsowantedtoshowyouthatthesamecontentcouldbemanagedinaJSONformat.

Now,wewillextendtheimplementationofResourceBasedProductLookuptoreadtheproductinformationfromJSONformattedresourcefiles.Mostofthecoderemainsthesameintheclass;therefore,weonlylistthedifferencehere:

packagepackt.java9.by.example.mybusiness.bulkorder.services;

import...

@Service

publicclassResourceBasedProductLookupimplementsProductLookup{

privatestaticfinalLoggerlog=LoggerFactory.getLogger(ResourceBasedProductLookup.class);

privateProductInformationfromJSON(InputStreamjsonStream)

throwsIOException{

ObjectMappermapper=newObjectMapper();

returnmapper.readValue(jsonStream,

ProductInformation.class);

}

...

privatevoidloadProducts(){

if(productsAreNotLoaded){

try{

Resource[]resources=

newPathMatchingResourcePatternResolver().

getResources("classpath:products/*.json");

for(Resourceresource:resources){

loadResource(resource);

}

productsAreNotLoaded=false;

}catch(IOExceptionex){

log.error("Testresourcescannotberead",ex);

}

}

}

Page 640:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privatevoidloadResource(Resourceresource)

throwsIOException{

finalintdotPos=

resource.getFilename().lastIndexOf('.');

finalStringid=

resource.getFilename().substring(0,dotPos);

finalProductInformationpi=

fromJSON(resource.getInputStream());

pi.setId(id);

products.put(id,pi);

}

...

Intheprojectresources/productsdirectorywehaveafewJSONfiles.Oneofthemcontainsthedesklampproductinformation:

{

"id":"124",

"title":"DeskLamp",

"check":[

"packt.java9.by.example.mybusiness.bulkorder.checkers.PoweredDevice"

],

"description":"thisisalampthatstandsonmydesk",

"weight":"600",

"size":["300","20","2"]

}

ThetypeofproductisspecifiedinaJSONarray.Inthisexample,thisarrayhasonlyoneelementandthatelementisthefullyqualifiednameoftheannotationinterfacethatrepresentsthetypeofproduct.WhentheJSONmarshallerconvertstheJSONtoaJavaobject,itrecognizesthatthefieldthatneedsthisinformationisaList,soitconvertsthearraytoalistand,also,theelementsfromStringtoClassobjectsrepresentingtheannotationinterface.

NowthatwehavetheresourcesloadedfromJSONformattedresourcesandwesawhoweasyitistoreadJSONdatawhenusingSpring,wecangetbacktotheorderconsistencycheck.TheCheckerclassimplementsthelogictocollectthepluggablecheckersandtoinvokethem.Italsoimplementstheannotation-basedscreeningsoasnottoinvokethecheckerswedon'treallyneedfortheactualproductsintheactualorder:

packagepackt.java9.by.example.mybusiness.bulkorder.services;

import...

@Component()

@RequestScope

publicclassChecker{

privatestaticfinalLoggerlog=

LoggerFactory.getLogger(Checker.class);

privatefinalCollection<ConsistencyChecker>checkers;

privatefinalProductInformationCollectorpiCollector;

privatefinalProductsCheckerCollectorpcCollector;

publicChecker(

@AutowiredCollection<ConsistencyChecker>checkers,

@AutowiredProductInformationCollectorpiCollector,

@AutowiredProductsCheckerCollectorpcCollector){

this.checkers=checkers;

this.piCollector=piCollector;

this.pcCollector=pcCollector;

}

publicbooleanisConsistent(Orderorder){

Map<OrderItem,ProductInformation>map=

piCollector.collectProductInformation(order);

if(map==null){

Page 641:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

returnfalse;

}

Set<Class<?extendsAnnotation>>annotations=

pcCollector.getProductAnnotations(order);

for(ConsistencyCheckerchecker:

checkers){

for(Annotationannotation:

checker.getClass().getAnnotations()){

if(annotations.contains(

annotation.annotationType())){

if(checker.isInconsistent(order)){

returnfalse;

}

break;

}

}

}

returntrue;

}

}

OneoftheinterestingthingstomentionisthattheSpringauto-wiringisveryclever.WehaveafieldwiththeCollection<ConsistencyChecker>type.Usually,auto-wiringworksifthereisexactlyoneclassthathasthesametypeastheresourcestowire.Inourcase,wedonothaveanysuchcandidatesincethisisacollection,butwehavemanyConsistencyCheckerclasses.AllourcheckersimplementthisinterfaceandSpringrecognizesit,instantiatesthemall,magicallycreatesacollectionofthem,andinjectsthecollectionintothisfield.

Usuallyagoodframeworkworkslogically.IwasnotawareofthisfeatureofSpring,butIthoughtthatthiswouldbelogicaland,magically,itworked.Ifthingsarelogicalandjustwork,youdonotneedtoreadandrememberthedocumentation.Abitofcautiondoesnotharmhowever.AfterIexperiencedthatthisfunctionalityworksthisway,IlookeditupinthedocumentationtoseethatthisisreallyaguaranteedfeatureofSpringandnotsomethingthatjusthappenstoworkbutmaychangeinfutureversionswithoutnotice.Usingonlyguaranteedfeaturesisextremelyimportantbutisneglectedmanytimesinourindustry.

WhentheisConsistentmethodisinvoked,itfirstcollectstheproductinformationintoHashMap,assigningaProductInformationinstancetoeachOrderItem.Thisisdoneinaseparateclass.Afterthis,ProductsCheckerCollectorcollectstheConsistencyCheckerinstancesneededbyoneormoreproductitems.Whenwehavethisset,weneedtoinvokeonlythosecheckersthatareannotatedwithoneoftheannotationsthatareinthisset.Wedothatinaloop.

Inthiscode,weusereflection.Weloopovertheannotationsthateachcheckerhas.Togetthecollectionofannotations,weinvokechecker.getClass().getAnnotations().Thisinvocationreturnsacollectionofobjects.EachobjectisaninstanceofsomeJDKruntimegeneratedclassthatimplementstheinterfacewedeclaredasanannotationinitsownsourcefile.Thereisnoguarantee,though,thatthedynamicallycreatedclassimplementsonlyour@interfaceandnotsomeotherinterfaces.Therefore,togettheactualannotationclass,wehavetoinvoketheannotationTypemethod.

TheProductCheckerCollectorandProductInformationCollectorclassesareverysimple,andwewilldiscussthemlaterwhenwelearnaboutstreams.Theywillserveasagoodexampleatthatplace,whenweimplementthemusingloopsand,rightafterthat,usingstreams.

Page 642:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Havingthemall,wecanfinallycreateouractualcheckerclasses.Theonethathelpsusseethatthereisapowercordorderedforourlampisthefollowing:

packagepackt.java9.by.example.mybusiness.bulkorder.checkers;

import...

@Component

@PoweredDevice

publicclassNeedPowercordimplementsConsistencyChecker{

privatestaticfinalLoggerlog=

LoggerFactory.getLogger(NeedPowercord.class);

@Override

publicbooleanisInconsistent(Orderorder){

log.info("checkingorder{}",order);

CheckHelperhelper=newCheckHelper(order);

return!helper.containsOneOf("126","127","128");

}

}

Thehelperclasscontainssimplemethodsthatwillbeneededbymanyofthecheckers,forexample:

publicbooleancontainsOneOf(String...ids){

for(finalOrderItemitem:order.getItems()){

for(finalStringid:ids){

if(item.getProductId().equals(id)){

returntrue;

}

}

}

returnfalse;

}

Page 643:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 644:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

InvokingmethodsInthisexample,weusedonlyonesinglereflectioncalltogettheannotationsattachedtoaclass.Reflectioncandomanymorethings.Handlingannotationsisthemostimportantuseforthesecallssinceannotationsdonothavetheirownfunctionalityandcannotbehandledinanyotherwayduringruntime.Reflection,however,doesnotstoptellinguswhatannotationsaclassoranyotherannotableelementhas.Reflectioncanbeusedtogetalistofthemethodsofaclass,thenameofthemethodsasstrings,theimplementedinterfacesofaclass,theparentclassitextends,thefields,thetypesoffields,andsoon.Reflectiongenerallyprovidesmethodsandclassestowalkthroughtheactualcodestructuredowntothemethodlevel,programmatically.

Thiswalkthroughdoesnotonlyallowreadingtypesandcodestructurebutalsomakesitpossibletosetfieldvaluesandcallmethodswithoutknowingthemethods'nameatcompiletime.Wecanevensetfieldsthatareprivateandarenotgenerallyaccessiblebytheoutsideworld.Itisalsotonotethataccessingthemethodsandfieldsthroughreflectionisusuallyslowerthanthroughcompiledcodebecauseitalwaysinvolveslookupbythenameoftheelementinthecode.

Theruleofthumbisthatifyouseethatyouhavetocreatecodeusingreflection,thenrealizethatyouareprobablycreatingaframework(orwritingabookaboutJavathatdetailsreflection).Doesitsoundfamiliar?

Springalsousesreflectiontodiscovertheclasses,methods,andfields,andalsotoinjectanobject.ItusestheURLclassloadertolistalltheJARfilesanddirectoriesthatareontheclasspath,loadsthem,andexaminestheclasses.

Foracontrivedexample,forthesakeofdemonstration,let'sassumethattheConsistencyCheckerimplementationswerewrittenbymanyexternalsoftwarevendors,andthearchitectwhooriginallydesignedtheprogramstructurejustforgottoincludetheisConsistentmethodintheinterface.(Atthesametime,tosaveourmentalhealth,wecanalsoimaginethatthispersonisnotworkinganymoreinthecompanyfordoingso.)Asaconsequence,thedifferentvendorsdeliveredJavaclassesthat"implement"thisinterfacebutwecannotinvokethemethod,notonlybecausewedonothaveacommonparentinterfacethathasthismethodbutalsobecausethevendorsjusthappenedtousedifferentnamesfortheirmethods.

Whatcanwedointhissituation?Business-wise,askingallthevendorstorewritetheircheckersisruledoutbecausethemknowingweareintroubleattachesaheftypricetagtothetask.Ourmanagerswanttoavoidthatcostandwedevelopersalsowanttoshowthatwecanmendthesituationanddomiracles.(Later,Iwillhaveacommentonthat.)

Wecouldjusthaveaclassthatknowseverycheckerandhowtoinvokeeachoftheminmanydifferentways.Thiswouldrequireustomaintainthesaidclasswheneveranewcheckerisintroducedtothesystem,andwewanttoavoidthat.Thewholepluginarchitectureweareusingwasinventedforthisverypurposeinthefirstplace.

Howcanweinvokeamethodonanobjectthatweknowhasonlyonedeclaredmethod,whichacceptsan

Page 645:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

orderasaparameter?Thatiswherereflectioncomesintothepicture.Insteadofcallingchecker.isInconsistent(order),weimplementasmallprivatemethod,isInconsistent,whichcallsthemethod,whateveritsnameis,viareflection:

privatebooleanisInconsistent(ConsistencyCheckerchecker,Orderorder){

Method[]methods=checker.getClass().getDeclaredMethods();

if(methods.length!=1){

log.error(

"Thechecker{}haszeroormorethanonemethods",

checker.getClass());

returnfalse;

}

finalMethodmethod=methods[0];

finalbooleaninconsistent;

try{

inconsistent=(boolean)method.invoke(checker,order);

}catch(InvocationTargetException|

IllegalAccessException|

ClassCastExceptione){

log.error("Callingthemethod{}onclass{}threwexception",

method,checker.getClass());

log.error("Theexceptionis",e);

returnfalse;

}

returninconsistent;

}

WecangettheclassoftheobjectbycallingthegetClassmethod,andontheobjectthatrepresentstheclassitself,wecancallgetDeclaredMethods.Fortunately,thecheckerclassesarenotlitteredbymanymethods,sowecheckthatthereisonlyonemethoddeclaredinthecheckerclass.NotethatthereisalsoagetMethodsmethodinthereflectionlibrarybutitalwayswillreturnmorethanonemethod.Itreturnsthedeclaredandtheinheritedmethods.Becauseeachandeveryclassinheritsfromjava.lang.Object,atleastthemethodsoftheObjectclasswillbethere.

Afterthis,wetrytoinvoketheclassusingtheMethodobjectthatrepresentsthemethodinthereflectionclass.NotethatthisMethodobjectisnotdirectlyattachedtoaninstance.Weretrievedthemethodfromtheclass,andthus,whenweinvokeit,weshouldpasstheobjectitshouldworkonasafirstparameter.Thisway,x.y(z),becomesmethod.invoke(x,z).ThelastparameterofinvokeisavariablenumberofargumentsthatarepassedasanObjectarray.Inmostcases,whenweinvokeamethod,weknowtheargumentsinourcodeevenifwedonotknowthenameofthemethodandhavetousereflection.Wheneventheargumentsarenotknownbutareavailableasamatterofcalculation,thenwehavetopassthemasanObjectarray.

Invokingamethodviareflectionisariskycall.Ifwetrytocallamethodthenormalway,whichisprivate,thenthecompilerwillsignalanerror.Ifthenumberofargumentsortypesarenotappropriate,thecompilerwillagainwillgiveusanerror.Ifthereturnedvalueisnotboolean,orthereisnoreturnvalueatall,thenweagaingetacompilererror.Inthecaseofreflection,thecompilerisclueless.Itdoesnotknowwhatmethodwewillinvokewhenthecodeisexecuting.Theinvokemethod,ontheotherhand,canandwillnoticeallthesefailureswhenitisinvoked.Ifanyoftheaforementionedproblemsoccur,thenwewillgetexceptions.Iftheinvokemethoditselfseesthatitcannotperformwhatweaskofit,thenitwillthrowInvocationTargetExceptionorIllegalAccessException.Iftheconversionfromtheactualreturnvaluetobooleanisnotpossible,thenwewillgetClassCastException.

Aboutdoingmagic,itisanaturalurgethatwefeellikemakingsomethingextraordinary,somethingoutstanding.Thisisokaywhenweareexperimentingwithsomething,doingahobbyjob.Ontheotherhand,thisisstronglynotokaywhenweareworkingonaprofessionaljob.Averageprogrammers,whodo

Page 646:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

notunderstandyourbrilliantsolution,willmaintainthecodeinanenterpriseenvironment.Theywillturnyournicelycombedcodeintohaystackwhilefixingsomebugsorimplementingsomeminornewfeatures.EvenifyouaretheMozartofprogramming,theywillbe,atbest,no-namesingers.Abrilliantcodeinanenterpriseenvironmentcanbearequiem,withalltheimplicationsofthatmetaphor.

Lastbutnotleast,thesadrealityisthatweareusuallynottheMozartsofprogramming.

Notethatincasethereturnvalueoftheoriginalvalueisprimitive,thenitwillbeconvertedtoanobjectbyreflection,andthenwewillconvertitbacktotheprimitivevalue.Ifthemethoddoesnothaveareturnvalue,inotherwords,ifitisvoid,thenthereflectionwillreturnajava.lang.Voidobject.TheVoidobjectisonlyaplaceholder.Wecannotconvertittoanyprimitivevalueoranyothertypeofobjects.ItisneededbecauseJavaisstrictandinvokehastoreturnanObject,sotheruntimeneedssomethingthatitcanreturn.AllwecandoischeckthatthereturnedvalueclassisreallyVoid.

Let'sgoonwiththestorylineandoursolution.Wesubmittedthecodeanditworksinproductionforawhiletillanewupdatefromasoftwarevendorbreaksit.Wedebugthecodeinthetestenvironmentandseethattheclassnowcontainsmorethanonemethod.Ourdocumentationclearlystatesthattheyshouldonlyhaveonepublicmethod,andtheyprovidedacodethathas...hmm...werealizethattheothermethodsareprivate.Theyareright;theycanhaveprivatemethodsaccordingtothecontract,sowehavetoamendthecode.Wereplacethelinesthatlookuptheoneandonlymethod:

Method[]methods=checker.getClass().getDeclaredMethods();

if(methods.length!=1){

...

}

finalMethodmethod=methods[0];

Thenewcodewillbeasfollows:

finalMethodmethod=getSingleDeclaredPublicMethod(checker);

if(method==null){

log.error(

"Thechecker{}haszeroormorethanonemethods",

checker.getClass());

returnfalse;

}

Thenewmethodwewritetolookuptheoneandonlypublicmethodisasfollows:

privateMethodgetSingleDeclaredPublicMethod(

ConsistencyCheckerchecker){

finalMethod[]methods=

checker.getClass().getDeclaredMethods();

MethodsingleMethod=null;

for(Methodmethod:methods){

if(Modifier.isPublic(method.getModifiers())){

if(singleMethod!=null){

returnnull;

}

singleMethod=method;

}

}

returnsingleMethod;

}

Tocheckwhetherthemethodispublicornot,weuseastaticmethodfromtheModifierclass.Therearemethodstocheckallpossiblemodifiers.ThevaluethatthegetModifiersmethodreturnsisanintbitfield.

Page 647:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Differentbitshavedifferentmodifiersandthereareconstantsthatdefinethese.Thissimplificationleadstoinconsistency,whichyoucancheckifamethodisaninterfaceorvolatile,thatis,actuallynonsense.Thefactisthatbitsthatcanonlybeusedforothertypesofreflectionobjectswillneverbeset.

Thereisoneexception,whichisvolatile.Thisbitisreusedtosignalbridgemethods.Bridgemethodsarecreatedbythecompilerautomaticallyandcanhavedeepandcomplexissuesthatwedonotdiscussinthisbook.Thereuseofthesamebitdoesnotcauseconfusionbecauseafieldcanbevolatile,butasafield,itcannotbeabridgemethod.Obviously,afieldisafieldandnotamethod.Inthesameway,amethodcannotbeavolatilefield.Thegeneralruleis:donotusemethodsonreflectionobjectswheretheydonothaveameaning;orelse,knowwhatyoudo.

Makingthestorylineevenmoreintricate,anewversionofacheckeraccidentallyimplementsthecheckingmethodasapackageprivate.Theprogrammersimplyforgottousethepublickeyword.Forthesakeofsimplicity,let'sassumethattheclassesdeclareonlyonemethodagain,butitisnotpublic.Howdowesolvethisproblemusingreflection?

Obviously,thesimplestsolutionistoaskthevendorstofixtheproblem:itistheirfault.Insomecases,however,wemustcreateaworkaroundoversomeproblems.Thereisanothersolution:creatingaclasswithapublicmethodinthesamepackage,invokingthepackageprivatemethodsfromtheotherclass,thusrelayingtheotherclass.Asamatteroffact,thissolution,asaworkaroundforsuchabug,seemstobemorelogicalandcleaner,butthistime,wewanttousereflection.

Toavoidjava.lang.IllegalAccessException,wehavetosetthemethodobjectasaccessible.Todoso,wehavetoinsertthefollowinglineinfrontoftheinvocation:

method.setAccessible(true);

Notethatthiswillnotchangethemethodtopublic.Itwillonlymakethemethodaccessibleforinvocationthroughtheveryinstanceofthemethodobjectthatwesetasaccessible.

IhaveseencodethatcheckswhetheramethodisaccessibleornotbycallingtheisAccessiblemethodandsavesthisinformation;itsetsthemethodasaccessibleifitwasnotaccessibleandrestorestheoriginalaccessibilityaftertheinvocation.Thisistotallyuseless.Assoonasthemethodvariablegoesoutofscope,andthereisnoreferencetotheobjectwesettheaccessibilityflagto,theeffectofthesettingwearsoff.Also,thereisnopenaltyforsettingtheaccessibilityofapublicoranotherwisecallablemethod.

Page 648:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 649:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SettingfieldsWecanalsocallsetAccessibleonFieldobjectsandthenwecanevensetthevalueofprivatefieldsusingreflection.Withoutfurtherfakestories,justforthesakeoftheexample,let'smakeaConsistencyCheckernamedSettableChecker:

@Component

@PoweredDevice

publicclassSettableCheckerimplementsConsistencyChecker{

privatestaticfinalLoggerlog=LoggerFactory.getLogger(SettableChecker.class);

privatebooleansetValue=false;

publicbooleanisInconsistent(Orderorder){

returnsetValue;

}

}

Thischeckerwillreturnfalse,unlesswesetthefieldtotrueusingreflection.Wedosetitassuch.WecreateamethodintheCheckerclassandinvokeitfromthecheckingprocessforeachchecker:

privatevoidsetValueInChecker(ConsistencyCheckerchecker){

Field[]fields=checker.getClass().getDeclaredFields();

for(finalFieldfield:fields){

if(field.getName().equals("setValue")&&

field.getType().equals(boolean.class)){

field.setAccessible(true);

try{

log.info("Settingfieldtotrue");

field.set(checker,true);

}catch(IllegalAccessExceptione){

log.error("SNAFU",e);

}

}

}

}

ThemethodgoesthroughallthedeclaredfieldsandifthenameissetValueandthetypeisboolean,thenitsetsittotrue.Thiswillessentiallyrenderallordersthatcontainapowereddeviceasrejected.

Notethatalthoughbooleanisabuilt-inlanguageprimitive,whichisnotaclassbyanymeans,itstillhasaclasssothatreflectioncancomparethetypeofthefieldgainstheclassthatbooleanartificiallyhas.Nowboolean.classisaclassliteralinthelanguage,andforeachprimitive,asimilarconstantcanbeused.Thecompileridentifiestheseasclassliteralsandcreatestheappropriatepseudoclassreferencesinthebytecodesothatprimitivescanalsobecheckedinthisway,asdemonstratedinthesamplecodeofthesetValueInCheckermethod.

Wecheckedthatthefieldhastheappropriatetype,andwealsocalledthesetAccessiblemethodonthefield.EventhoughthecompilerdoesnotknowthatwereallydideverythingtoavoidIllegalAccessException,itstillbelievesthatcallingsetonfieldcanthrowsuchanexception,asitisdeclared.However,weknowthatitshouldnothappen.(Famouslastwordsofaprogrammer?)Tohandlethissituation,wesurroundthemethodcallwithatryblock,andinthecatchbranch,welogtheexception.

Page 650:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 651:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

FunctionalprogramminginJavaSincewehavecreatedalotofcodeinourexampleforthischapter,wewilllookatthefunctionalprogrammingfeaturesofJava,whichwillhelpusdeletemanylinesfromourcode.Thelesscodewehave,theeasieritistomaintaintheapplication;thus,programmerslovefunctionalprogramming.Butthisisnottheonlyreasonwhyfunctionalprogrammingissopopular.Itisalsoanexcellentwaytodescribecertainalgorithmsinamorereadableandlesserrorpronemannerthanconventionalloops.

Functionalprogrammingisnotanewthing.Themathematicalbackgroundwasdevelopedforitinthe1930s.Oneofthefirst(ifnotthefirst)functionalprogramminglanguagesisLISP.Itwasdevelopedinthe1950sanditisstillinuse,somuchthatthereisaversionofthelanguageimplementedontheJVM(Clojure).

Functionalprogramming,inshort,meansthatweexpresstheprogramstructureintermsoffunctions.Inthismeaning,weshouldthinkoffunctionsasinmathematicsandnotasthetermisusedinprogramminglanguagessuchasC.InJava,wehavemethods,andwhenwearefollowingthefunctionalprogrammingparadigm,wecreateandusemethodsthatbehavelikemathematicalfunctions.Amethodisfunctionalifitgivesthesameresultnomatterhowmanytimesweinvokeit,justassin(0)isalwayszero.Functionalprogrammingavoidschangingthestateofobjects,andbecausethestateisnotchanging,theresultsarealwaysthesame.Thisalsoeasesdebugging.

Ifafunctionhasoncereturnedacertainvalueforthegivenarguments,itwillalwaysreturnthesamevalue.Wecanalsoreadthecodeasadeclarationofthecalculationmorethanascommandsthatareexecutedoneaftertheother.Iftheexecutionorderisnotimportant,thenthereadabilityofthecodemayalsoincrease.

Javahelpsfunctionalprogrammingstylewithlambdaexpressionsandstreams.NotethatthesestreamsarenotI/Ostreamsanddonotreallyhaveanyrelationtothose.

Wewillfirsttakeashortlookatlambdaexpressionsandwhatstreamsare,andthen,wewillconvertsomepartsofourprogramtousetheseprogrammingconstructs.Wewillalsoseehowmuchmorereadablethesecodesbecome.

Readabilityisadebatabletopic.Acodemaybereadabletoonedeveloperandmaybelessreadabletoanother.Itverymuchdependsonwhattheygotusedto.Iexperiencemanytimesthatdevelopersgetdistractedwithstreams.Whendevelopersfirstmeetstreams,thewaytothinkaboutthemandhowtheylookisjuststrange.Butthisisthesameasstartingtolearnusingabicycle.Whileyouarestilllearningitsuseandyoufallmorethanyouroll,itisdefinitelyslowerthanwalking.Ontheotherhand,onceyouhavelearnthowtorideabike...

Page 652:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 653:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LambdaWehavealreadyusedlambdaexpressionsinChapter3,OptimizingtheSort-MakingCodeProfessionalwhenwewrotetheexception-throwingtest.Inthatcode,wesetthecomparatortoaspecialvaluethatwasthrowingRuntimeExceptionateachinvocation:

sort.setComparator((Stringa,Stringb)->{

thrownewRuntimeException();

});

TheargumenttypeisComparator;therefore,whatwehavetosetthereshouldbeaninstanceofaclassthatimplementsthejava.util.Comparatorinterface.Thatinterfacedefinesonlyonemethodthatimplementationshavetodefine:compare.Thus,wecandefineitasalambdaexpression.Withoutlambda,ifweneedaninstance,wehavetotypealot.Wehavetocreateaclass,nameit,declarethecomparemethodinit,andwritethebodyofthemethod,asshowninthefollowingcodesegment:

publicclassExceptionThrowingComparatorimplementsComparator{

publicintcompare(To1,To2){

thrownewRuntimeException();

}

}

Atthelocationofuse,weshouldinstantiatetheclassandpassitasanargument:

sort.setComparator(newExceptionThrowingComparator());

Wemaysaveafewcharactersifwedefinetheclassasananonymousclassbuttheoverheadisstillthere.Whatwereallyneedisthebodyoftheoneandsinglemethodthatwehavetodefine.Thisiswherelambdacomesintothepicture.

Wecanusealambdaexpressioninanyplacewherewewouldotherwiseneedaninstanceofaclassthathastodefineonlyonemethod.ThemethodsthataredefinedandinheritedfromObjectdonotcount,andwealsodonotcareaboutthemethodsthataredefinedasdefaultmethodsintheinterface.Theyarethere.Lambdadefinestheonethatisnotyetdefined.Inotherwords,lambdaclearlydepicts,withmuchlessoverheadasananonymousclass,thatthevalueisafunctionalitythatwepassasaparameter.

Thesimpleformofalambdaexpressionisasfollows:

parameters->body

Theparameterscanbeenclosedbetweenparenthesesorcanonlystandwithout.Thebodysimilarlycanbeenclosedbetweenthe{and}charactersoritcanbeasimpleexpression.Thiswayalambdaexpressioncanreducetheoverheadtoaminimum,usingtheparenthesesonlywheretheyarereallyneeded.

Itisalsoanextremelyusefulfeatureoflambdaexpressionsthatwedonotneedtospecifythetypesoftheparametersincaseitisobviousfromthecontextwhereweusetheexpression.Thus,theprecedingcodesegmentcanevenbeshorter,asfollows:

sort.setComparator((a,b)->{

thrownewRuntimeException();

Page 654:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

});

Theparameters,aandb,willhavethetypeasneeded.Tomakeitevensimpler,wecanalsoomitthe(and)charactersaroundtheparametersincasethereisonlyone.

Theparenthesesarenotoptionalifthereismorethanoneparameter.Thisistoavoidambiguityinsomesituations.Forexample,themethodcall,f(x,y->x+y)couldhavebeenamethodwithtwoarguments:xandalambdaexpressionthathasoneparameter,y.Atthesametime,itcouldalsobeamethodcallwithalambdaexpressionthathastwoparameters,xandy.

Lambdaexpressionsareveryhandywhenwewanttopassfunctionalityasanargument.Thedeclarationofthetypeofargumentattheplaceofthemethoddeclarationshouldbeafunctionalinterfacetype.Theseinterfacescanoptionallybeannotatedusing@FunctionalInterface.TheJavaruntimehasmanysuchinterfacesdefinedinthejava.util.functionpackage.Wewilldiscusssomeoftheminthenextsectionalongwiththeiruseinstreams.Fortherest,thestandardJavadocumentationisavailablefromOracle.

Page 655:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 656:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

StreamsStreamswerealsonewinJava8,justlikelambdaexpressions.Theyworktogetherverystrongly,sotheirappearanceatthesametimeisnotasurprise.Lambdaexpressionsaswellasstreamssupportthefunctionalprogrammingstyle.

Theveryfirstthingtoclarifyisthatstreamsdonothaveanythingtodowithinputandoutputstreams,exceptthename.Theyaretotallydifferentthings.Streamsaremorelikecollectionswithsomesignificantdifferences.(Iftherewerenodifferences,theywouldjusthavebeencollections.)Streamsareessentiallypipelinesofoperationsthatcanrunsequentiallyorinparallel.Theyobtaintheirdatafromcollectionsorothersources,includingdatathatismanufacturedon-the-fly.

Streamssupporttheexecutionofthesamecalculationonmultipledata.ThisstructureisreferredtoasSingleInstructionMultipleData(SIMD).Don'tbeafraidoftheexpression.Thisisaverysimplething.Wehavealreadydonethatmanytimesinthisbook.LoopsarealsokindofSIMDstructures.Whenweloopthroughthecheckerclassestoseewhetheranyofthoseopposestheorder,weperformthesameinstructionforeachandeverychecker.Multiplecheckersaremultipledata.

Oneproblemwithloopsisthatwedefinetheorderofexecutionwhenitisnotneeded.Inthecaseofcheckers,wedonotreallycarewhatorderthecheckersareexecutedin.Allwecareaboutisthatallareokaywiththeorder.Westillspecifysomeorderwhenweprogramtheloop.Thiscomesfromthenatureofloops,andthereisnowaywecouldchangethat.Thatishowtheywork.However,itwouldbeniceifwecouldjust,somehow,say"dothisandthatforeachandeverychecker".Thisisonepointwherestreamscomeintothepicture.

Anotherpointisthatcodethatusesloopsismoreimperativeratherthandescriptive.Whenwereadtheprogramofaloopconstruct,wefocusontheindividualsteps.Wefirstseewhatthecommandsintheloopdo.Thesecommandsworkontheindividualelementsofthedataandnotonthewholecollectionorarray.

Laterputtingtheindividualstepstogetherinourbrainwerealizewhatthebigpictureis,whattheloopisfor.Inthecaseofstreams,thedescriptionofoperationsisalevelhigher.Oncewelearnthestreammethods,itiseasiertoreadthem.Streammethodsworkonthewholestreamandnotontheindividualelements,andthusaremoredescriptive.

java.lang.Streamisaninterface.Anobjectwithatypeimplementingthisinterfacerepresentsmanyobjectsandprovidesmethodsthatcanbeusedtoperforminstructionsontheseobjects.Theobjectsmayormaynotbeavailablewhenwestarttheoperationononeofthem,ormayjustbecreatedwhenneeded.ThisisuptotheactualimplementationoftheStreaminterface.Forexample,supposewegenerateastreamthatcontainsintvaluesusingthefollowingcode:

IntStream.iterate(0,(s)->s+1)

Intheprecedingcodesnippet,alltheelementscannotbegeneratedbecausethestreamcontainsaninfinitenumberofelements.Thisexamplewillreturnthenumbers0,1,2,andsoonuntilfurtherstreamoperations,whicharenotlistedhere,terminatethecalculation.

Page 657:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WhenweprogramStream,weusuallycreateastreamfromaCollection—notalways,butmanytimes.TheCollectioninterfacewasextendedinJava8toprovidethestreamandparallelStreammethods.Bothofthemreturnstreamobjectsthatrepresenttheelementsofthecollection.Whilestreamreturnstheelementsinthesameorderastheyareinthecollectionincasethereisanaturalorder,theparallelStreamcreatesastreamthatmaybeworkedoninaparallelmanner.Inthiscase,ifsomeofthemethodsthatweuseonthestreamareimplementedinthatway,thecodecanusethemultipleprocessorsavailableinthecomputer.

Assoonaswehaveastream,wecanusethemethodsthattheStreaminterfacedefines.TheonetostartwithisforEach.Thismethodhasoneargument,whichisusuallyprovidedasalambdaexpressionandwillexecutethelambdaexpressionforeachelementofthestream.

IntheCheckerclass,wehavetheisConsistentmethod.Inthismethod,thereisaloopthatgoesthroughtheannotationsofthecheckerclass.Ifwewantedtologtheinterfacesthattheannotationintheloopimplements,wecouldaddthefollowing:

for(ConsistencyCheckerchecker:checkers){

for(Annotationannotation:

checker.getClass().getAnnotations()){

Arrays.stream(annotation.getClass().getInterfaces())

.forEach(

t->log.info("annotationimplementedinterfaces{}",t)

);

...

Inthisexample,wecreateastreamfromanarrayusingthefactorymethodfromtheArraysclass.Thearraycontainstheinterfacesreturnedbythereflectionmethod,getInterfaces.Thelambdaexpressionhasonlyoneparameter;thus,wedonotneedtouseparenthesesaroundit.Thebodyoftheexpressionisamethodcallthatreturnsnovalue;thus,wealsoomitthe{and}characters.

Whyallthishassle?Whatisthegain?Whycouldn'twejustwriteasimpleloopthatlogstheelementsofthearray?Thegainsarereadabilityandmaintainability.Whenwecreateaprogram,wehavetofocusonwhattheprogramshoulddoandnotonhowitshoulddoit.Inanidealworld,aspecificationwouldjustbeexecutable.Wemayactuallygetthereinthefuturewhenprogrammingworkwillbereplacedbyartificialintelligence.(Nottheprogrammers,though.)Wearenotthere,yet.Wehavetotellthecomputershowtodowhatwewanttoachieve.WeusedtohavetoenterbinarycodesontheconsoleofPDP-11togetmachinecodedeployedintothememorytohaveitexecuted.Later,wehadassemblers;stilllater,wehadFORTRANandotherhigh-levelprogramminglanguagesthathavereplacedmuchoftheprogrammingworkasitwas40yearsago.Allthesedevelopmentsinprogrammingshiftthedirectionfromhowtowardswhat.Today,weprograminJava9,andtheroadstillhasmilestogo.Themorewecanexpresswhattodoinsteadofhowtodo,theshorterandmoreunderstandableourprogramswillbe.Itwillcontaintheessenceandnotsomeartificiallitterthatisneededbythemachinestojustdowhatwewant.WhenIseealoopinacodeIhavetomaintain,Iassumethatthereissomeimportanceoftheorderinwhichtheloopisexecuted.Theremaybenoimportanceatall.Itmaybeobviousafterafewseconds.Itmayneedminutesormoretorealizethattheorderingisnotimportant.Thistimeiswastedandcanbesavedwithprogrammingconstructsthat

Page 658:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

betterexpressthewhattodopartinsteadofthehowtodo.

Page 659:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 660:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

FunctionalinterfacesTheargumenttothemethodshouldbejava.util.function.Consumer.Thisisaninterfacethatrequirestheacceptmethodtobedefined,andthismethodisvoid.Thelambdaexpressionoraclassthatimplementsthisinterfacewillconsumetheargumentoftheacceptmethodanddoesnotproduceanything.

Thereareseveralotherinterfacesdefinedinthatpackage,eachservingasafunctionalinterfaceusedtodescribesomemethodargumentsthatcanbegivenaslambdaexpressionsintheactualparameters.

Forexample,theoppositeofConsumerisSupplier.ThisinterfacehasamethodnamedgetthatdoesnotneedanyargumentbutgivessomeObjectasareturnvalue.

Ifthereisanargumentandalsoareturnedvalue,theinterfaceiscalledFunction.Ifthereturnedvaluehastobethesametypeastheargument,thentheUnaryOperatorinterfaceisourfriend.Similarly,thereisaBinaryOperatorinterface,whichreturnsanobjectofthesametypeasthearguments.JustaswegotfromFunctiontoUnaryOperator,wecanseethatintheotherdirection,thereisalsoBiFunctionincasetheargumentsandthereturnvaluesdonotsharethetype.

Theseinterfacesarenotdefinedindependentlyofeachother.IfamethodrequiresFunctionandwehaveUnaryOperatortopass,itshouldnotbeaproblem.UnaryOperatorisnothingelsebutFunctionthathasthesametypeofarguments.AmethodthatcanworkwithFunction,whichacceptsanobjectandreturnsanobject,shouldnothaveaproblemiftheyhavethesametype.Thosecanbe,butneednotbe,different.Toletthathappen,theUnaryOperatorinterfaceextendsFunctionandthuscanbeusedintheplaceofFunction.

Theinterfacesinthisclasswemetsofararedefinedusinggenerics.Becausegenerictypescannotbeprimitives,theinterfacesthatoperateonprimitivevaluesshouldbedefinedseparately.Predicate,forexample,isaninterfacethatdefinesbooleantest(Tt).Itisafunctionthatreturnsabooleanvalueandisusedmanytimesinstreammethods.

Therearealsointerfaces,suchasBooleanSupplier,DoubleConsumer,DoubleToIntFunction,andmore,thatworkwithprimitiveboolean,double,andint.Thenumberofpossiblecombinationsofthedifferentargumenttypesandreturnvaluesisinfinite...almost.

Funfact:Tobeveryprecise,itisnotinfinite.Amethodcanhaveatmost254arguments.ThislimitisspecifiedintheJVMandnotintheJavalanguagespecification.Ofcourse,oneisuselesswithouttheother.Thereare8primitivetypes(plusObject,plusthepossibilitythattherearelessthan254arguments),whichmeansthatthetotalnumberofpossiblefunctionalinterfacesis10254,giveortake,afewmagnitudes.Practically,infinite!

WeshouldnotexpecttohaveallthepossibleinterfacesdefinedintheJDKinthispackage.Theseareonlythoseinterfacesthatarethemostuseful.Thereisnointerface,forexample,thatusesshortorchar.Ifweneedanythinglikethat,thenwecandefinetheinterfaceinourcode.Orjustthinkhardandfindouthow

Page 661:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

touseanalreadydefinedone.(Ihaveneverusedtheshorttypeduringmyprofessionalcarrier.Itwasneverneeded.)

Howarethesefunctionalinterfacesusedinstreams?TheStreaminterfacedefinesthemethodsthathavesomefunctionalinterfacetypesasarguments.Forexample,theallMatchmethodhasaPredicateargumentandreturnsaBooleanvalue,whichistrueifalltheelementsinthestreammatchPredicate.Inotherwords,thismethodreturnstrueifandonlyifPredicate,suppliedasanargument,returnstrueforeachandeveryelementofthestream.

Inthefollowingcode,wewillrewritesomeofthemethodsthatweimplementedinoursamplecodeusingloopstousestreams,andthroughtheseexamples,wewilldiscussthemostimportantmethodsthatstreamsprovide.Wesaveduptwoclasses,ProductsCheckerCollectorandProductInformationCollector,todemonstratethestreamusage.Wecanstartwiththese.ProductsCheckerCollectorgoesthroughalltheproductsthatarecontainedintheOrderandcollectstheannotationsthatarelistedintheproducts.Eachproductmaycontainzero,one,ormanyannotations.Theseareavailableinalist.Thesameannotationmaybereferencedmultipletimes.Toavoidduplicates,weuseHashSet,whichwillcontainonlyoneinstanceoftheelementseveniftherearemultipleinstancesintheproducts:

publicclassProductsCheckerCollector{

privatefinalProductInformationCollectorpic;

publicProductsCheckerCollector(@Autowired

ProductInformationCollectorpic){this.pic=pic;}

publicSet<Class<?extendsAnnotation>>

getProductAnnotations(Orderorder){

Map<OrderItem,ProductInformation>piMap=

pic.collectProductInformation(order);

finalSet<Class<?extendsAnnotation>>

annotations=newHashSet<>();

for(OrderItemitem:order.getItems()){

finalProductInformationpi=piMap.get(item);

if(pi!=null&&pi.getCheck()!=null){

for(Class<?extendsAnnotation>check:

pi.getCheck()){

annotations.addAll(pi.getCheck());

}

}

returnannotations;

}

}

Now,let'sseehowthismethodlookswhenwerecodeitusingstreams:

publicSet<Class<?extendsAnnotation>>

getProductAnnotations(Orderorder){

Map<OrderItem,ProductInformation>piMap=

pic.collectProductInformation(order);

returnorder.getItems().stream()

.map(piMap::get)

.filter(Objects::nonNull)

.peek(pi->{

if(pi.getCheck()==null){

log.info("Product{}hasnoannotation",

pi.getId());

}

})

.filter(pi->pi.getCheck()!=null)

.peek(pi->log.info("Product{}isannotatedwithclass{}",pi.getId(),pi.getCheck()))

.flatMap(pi->pi.getCheck().stream())

.collect(Collectors.toSet());

}

Page 662:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Themajorworkofthemethodgetsintoasingle,thoughhuge,streamexpression.Wewillcovertheelementsoftheexpressioninthecomingpages.Listreturnedbyorder.getItemsisconvertedcallingthestreammethod:

returnorder.getItems().stream()

Aswehavealreadymentioneditbriefly,thestreammethodispartoftheCollectioninterface.AnyclassthatimplementstheCollectioninterfacewillhavethismethod,eventhosethatwereimplementedbeforestreamswereintroducedinJava8.Thisisbecausethestreammethodisimplementedintheinterfaceasadefaultmethod.Thisway,ifwehappentoimplementaclassimplementingthisinterface,evenifwedonotneedstreams,wegetitforfreeasanextra.

ThedefaultmethodsinJava8wereintroducedtosupportbackwardcompatibilityofinterfaces.SomeoftheinterfacesoftheJDKweretobemodifiedtosupportlambdaandfunctionalprogramming.Oneexampleisthestreammethod.Withthepre-Java8featureset,theclassesimplementingsomeofthemodifiedinterfacesshouldhavebeenmodified.Theywouldhavebeenrequiredtoimplementthenewmethod.Suchachangeisnotbackwardcompatible,andJavaasalanguageandJDKwaspayingkeenattentiontobebackwardcompatible.Thus,defaultmethodswereintroduced.Theseletadeveloperextendaninterfaceandstillkeepitbackwardcompatible,providingadefaultimplementationforthemethods,whicharenew.Contrarytothisphilosophy,brandnewfunctionalinterfacesofJava8JDKalsohavedefaultmethods,though,havingnopriorversionintheJDK,theyhavenothingtobecompatiblewith.InJava9,interfaceswerealsoextendedandnowtheycancontainnotonlydefaultandstaticmethodsbutalsoprivatemethods.Thisway,interfacesbecamekindofequivalenttoabstractclasses,thoughtherearenofieldsinaninterfaceexceptconstantstaticfields.Thisinterfacefunctionalityopenupisamuchcriticizedfeature,whichjustposestheprogrammingstyleandstructuralissuesthatotherlanguagesallowingmultipleclassinheritanceface.JavawasavoidingthistillJava8andJava9.Whatisthetake-awayfromthis?Becarefulwithdefaultmethodsandalsowithprivatemethodsininterfaces.Usethemwiselyifatall.

TheelementsofthisstreamareOrderItemobjects.WeneedProductInformationforeachOrderItem.

Page 663:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 664:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MethodreferencesLuckythatwehaveMap,whichpairsorderitemswithproductinformation,sowecaninvokegetonMap:

.map(piMap::get)

ThemapmethodisagainsomethingthathasthesamenameassomethingelseinJavaandshouldnotbeconfused.WhiletheMapclassisadatastructure,themapmethodintheStreaminterfaceperformsmappingofthestreamelements.TheargumentofthemethodisaFunction(recallthatthisisafunctionalinterfacewerecentlydiscussed).Thisfunctionconvertsavalue,T,whichisavailableastheelementoftheoriginalstream(Stream<T>)toavalue,R,andthereturnvalueofthemapmethodisStream<R>.ThemapmethodconvertsStream<T>toStream<R>usingthegivenFunction<T,R>,callingitforeachelementoftheoriginalstreamandcreatinganewstreamfromtheconvertedelements.

WecansaythattheMapinterfacemapskeystovaluesinadatastructureinastaticway,andtheStreammethod,map,mapsonetypeofvaluestoanother(orthesame)typeofvaluesdynamically.

Wehavealreadyseenthatwecanprovideaninstanceofafunctionalinterfaceintheformofalambdaexpression.Thisargumentisnotalambdaexpression.Thisisamethodreference.ItsaysthatthemapmethodshouldinvokethegetmethodonMappiMapusingtheactualstreamelementasanargument.Weareluckythatgetalsoneedsoneargument,aren'twe?Wecouldalsowriteasfollows:

.map(orderItem->piMap.get(orderItem))

However,thiswouldhavebeenexactlythesameaspiMap::get.

Thisway,wecanreferenceaninstancemethodthatworksonacertaininstance.Inourexample,theinstanceistheonereferencedbythepiMapvariable.Itisalsopossibletoreferencestaticmethods.Inthiscase,thenameoftheclassshouldbewritteninfrontofthe::characters.Wewillsoonseeanexampleofthiswhenwewillusethestaticmethod,nonNull,fromtheObjectsclass(notethattheclassnameisinplural,anditisinthejava.utilpackageandnotjava.lang).

Itisalsopossibletoreferenceaninstancemethodwithoutgivingthereferenceonwhichitshouldbeinvoked.Thiscanbeusedinplaceswherethefunctionalinterfacemethodhasanextrafirstparameter,whichwillbeusedastheinstance.WehavealreadyusedthisinChapter3,OptimizingtheSort-MakingCodeProfessional,whenwepassedString::compareTo,whentheexpectedargumentwasaComparator.ThecompareTomethodexpectsoneargument,butthecomparemethodintheComparatorinterfaceneedstwo.Insuchasituation,thefirstargumentwillbeusedastheinstanceonwhichcomparehastobeinvokedandthesecondargumentispassedtocompare.Inthiscase,String::compareToisthesameaswritingthelambdaexpression(Stringa,Stringb)->a.compareTo(b).

Lastbutnotleast,wecanusemethodreferencestoconstructors.WhenweneedaSupplierof(let'sbesimple)Object,wecanwriteObject::new.

Thenextstepistofilteroutthenullelementsfromthestream.Notethat,atthispoint,thestreamhasProductInformationelements:

Page 665:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

.filter(Objects::nonNull)

ThefiltermethodusesPredicateandcreatesastreamthatcontainsonlytheelementsthatmatchthepredicate.Inthiscase,weusedthereferencetoastaticmethod.Thefiltermethoddoesnotchangethetypeofstream.Itonlyfiltersouttheelements.

Thenextmethodweapplyisabitanti-functional.Purefunctionalstreammethodsdonotalterthestateofanyobject.Theycreatenewobjectsthattheyreturnbut,otherthanthat,thereisnosideeffect.peekitselfisnodifferentbecauseitonlyreturnsastreamofthesameelementsastheoneitisappliedon.However,thisno-operationfeatureluresthenoviceprogrammertodosomethingnon-functionalandwritecodewithside-effects.Afterall,whyuseitifthereisno(side)effectincallingit?

.peek(pi->{

if(pi.getCheck()==null){

log.info("Product{}hasnoannotation",pi.getId());

}

})

Whilethepeekmethoditselfdoesnothaveanysideeffects,theexecutionofthelambdaexpressionmayhave.However,thisisalsotrueforanyoftheothermethods.Itisjustthefactthat,inthiscase,itismoretemptingtodosomethinginadequate.Don't.Wearedisciplinedadults.Asthenameofthemethodsuggests,wemaypeekintothestreambutwearenotsupposedtodoanythingelse.Withprogrammingbeingaparticularactivity,inthiscase,peeking,isadequate.Andthatiswhatweactuallydoinourcode:welogsomething.

Afterthis,wegetridoftheelementsthathavenoProductInformation;wealsowanttogetridoftheelementsthathave,butthereisnocheckerdefined:

.filter(pi->pi.getCheck()!=null)

Inthiscase,wecannotusemethodreferences.Instead,weusealambdaexpression.Asanalternativesolution,wemaycreateabooleanhasCheckmethodinProductInformation,whichreturnstrueiftheprivatefieldcheckisnotnull.Thiswouldthenreadasfollows:

.filter(ProductInformation::hasCheck)

Thisistotallyvalidandworks,althoughtheclassdoesnotimplementanyfunctionalinterfaceandhasmanymethods,notonlythisone.However,themethodreferenceisexplicitandspecifieswhichmethodtoinvoke.

Afterthissecondfilter,welogtheelementsagain:

.peek(pi->log.info(

"Product{}isannotatedwithclass{}",pi.getId(),

pi.getCheck()))

ThenextmethodisflatMapandthisissomethingspecialandnoteasytocomprehend.Atleastforme,itwasabitmoredifficultthanunderstandingmapandfilterwhenIlearnedfunctionalprogramming:

.flatMap(pi->pi.getCheck().stream())

Thismethodexpectsthatthelambda,methodreference,orwhateverispassedtoitasanargument,

Page 666:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

createsawholenewstreamofobjectsforeachelementoftheoriginalstreamthemethodisinvokedon.Theresultis,however,notastreamofstreams,whichalsocouldbepossible,butratherthereturnedstreamsareconcatenatedintoonehugestream.

Ifthestreamweapplyittoisastreamofintegernumbers,suchas1,2,3,...,andthefunctionforeachnumbernreturnsastreamofthreeelementsn,n+1,andn+2,thentheresultingstream,flatMap,producesastreamcontaining1,2,3,2,3,4,3,4,5,4,5,6,andsoon.

Finally,thestreamwehaveshouldbecollectedtoaSet.Thisisdonebycallingthecollectormethod:

.collect(Collectors.toSet());

Theargumenttothecollectormethodis(againanameoveruse)Collector.Itcanbeusedtocollecttheelementsofthestreamintosomecollection.NotethatCollectorisnotafunctionalinterface.Youcannotjustcollectsomethingusingalambdaorasimplemethod.Tocollecttheelements,wedefinitelyneedsomeplacewheretheelementsarecollectedastheever-newerelementscomefromthestream.TheCollectorinterfaceisnotsimple.Fortunately,thejava.util.streams.Collectorsclass(againnotetheplural)hasalotofstaticmethodsthatcreateandreturnObjectthatcreateandreturnCollectorobjects.

OneoftheseistoSet,whichreturnsaCollectorthathelpscollecttheelementsofthestreamintoaSet.ThecollectmethodwillreturntheSetwhenalltheelementsarethere.Thereareothermethodsthathelpcollectthestreamelementsbysumminguptheelements,calculatingtheaverage,ortoaList,Collection,ortoaMap.CollectingelementstoaMapisaspecialthing,sinceeachelementofaMapisactuallyakey-valuepair.WewillseetheexampleforthatwhenwelookatProductInformationCollector.

TheProductInformationCollectorclasscodecontainsthecollectProductInformationmethod,whichwewillusefromtheCheckerclassaswellasfromtheProductsCheckerCollectorclass:

privateMap<OrderItem,ProductInformation>map=null;

publicMap<OrderItem,ProductInformation>

collectProductInformation(Orderorder){

if(map==null){

map=newHashMap<>();

for(OrderItemitem:order.getItems()){

finalProductInformationpi=

lookup.byId(item.getProductId());

if(!pi.isValid()){

map=null;

returnnull;

}

map.put(item,pi);

}

}

returnmap;

}

ThesimpletrickistostorethecollectedvalueinMap,andifthatisnotnull,thenjustreturnthealreadycalculatedvalue,whichmaysavealotofservicecallsincasethismethodiscalledmorethanoncehandlingthesameHTTPrequest.

Therearetwowaysofcodingsuchastructure.Oneischeckingthenon-nullityoftheMapandreturningiftheMapisalreadythere.Thispatterniswidelyusedandhasaname.Thisiscalledguardingif.Inthiscase,thereismorethanonereturnstatementinthemethod,

Page 667:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

whichmaybeseenasaweaknessoranti-pattern.Ontheotherhand,thetabulationofthemethodisonetabshallower.Itisamatteroftasteandincaseyoufindyourselfinthemiddleofadebateaboutoneortheothersolution,justdoyourselfafavorandletyourpeerwinonthistopicandsaveyourstaminaformoreimportantissues,forexample,whetheryoushouldusestreamsorjustplainoldloops.

Now,let'sseehowwecanconvertthissolutionintoafunctionalstyle:

publicMap<OrderItem,ProductInformation>collectProductInformation(Orderorder){

if(map==null){

map=

order.getItems()

.stream()

.map(item->tuple(item,item.getProductId()))

.map(t->tuple(t.r,lookup.byId((String)t.s)))

.filter(t->((ProductInformation)t.s).isValid())

.collect(

Collectors.toMap(t->(OrderItem)t.r,

t->(ProductInformation)t.s

)

);

if(map.keySet().size()!=order.getItems().size()){

log.error("Someoftheproductsintheorderdonothaveproductinformation,{}!={}",map.keySet().size(),order.getItems().size());

map=null;

}

}

returnmap;

}

Weuseahelperclass,Tuple,whichisnothingbuttwoObjectinstancesnamedrands.Wewilllistthecodeforthisclasslater.Itisverysimple.

Inthestreamsexpression,wefirstcreatethestreamfromthecollection,andthenwemaptheOrderItemelementstoastreamofOrderItemandproductIdtuples.ThenwemapthesetuplestotuplesthatnowcontainOrderItemandProductInformation.Thesetwomappingscouldbedoneinonemappingcall,whichwouldperformthetwostepsonlyinone.Idecidedtocreatethetwotohavesimplerstepsineachlineinavainhopethattheresultingcodewillbeeasiertocomprehend.

Thefilterstepisalsonothingnew.Itjustfiltersoutinvalidproductinformationelements.Thereshouldactuallybenone.IthappensiftheordercontainsanorderIDtoanon-existentproduct.Thisischeckedinthenextstatementwhenwelookatthenumberofcollectedproductinformationelementstoseethatalltheitemshaveproperinformation.

TheinterestingcodeishowwecollecttheelementsofthestreamintoaMap.Todoso,weagainusethecollectmethodandalsotheCollectorsclass.Thistime,thetoMapmethodcreatestheCollector.ThisneedstwoFunctionresultingexpressions.ThefirstoneshouldconverttheelementofthestreamtothekeyandthesecondshouldresultinthevaluetobeusedintheMap.Becausetheactualtypeofthekeyandthevalueiscalculatedfromtheresultofthepassedlambdaexpressions,weexplicitlyhavetocastthefieldsofthetupletotheneededtypes.

Finally,thesimpleTupleclassisasfollows:

publicclassTuple<R,S>{

finalpublicRr;

finalpublicSs;

Page 668:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privateTuple(Rr,Ss){

this.r=r;

this.s=s;

}

publicstatic<R,S>Tupletuple(Rr,Ss){

returnnewTuple<>(r,s);

}

}

Therearestillsomeclassesinourcodethatdeservetobeconvertedtofunctionalstyle.ThesearetheCheckerandCheckerHelperclasses.

IntheCheckerclass,wecanrewritetheisConsistentmethod:

publicbooleanisConsistent(Orderorder){

Map<OrderItem,ProductInformation>map=

piCollector.collectProductInformation(order);

if(map==null){returnfalse;}

finalSet<Class<?extendsAnnotation>>annotations=

pcCollector.getProductAnnotations(order);

return!checkers.stream().anyMatch(

checker->Arrays.stream(

checker.getClass().getAnnotations()

).filter(

annotation->

annotations.contains(

annotation.annotationType())

).anyMatch(

x->

checker.isInconsistent(order)

));

}

Sinceyouhavealreadylearntmostoftheimportantstreammethods,thereishardlyanynewissuehere.WecanmentiontheanyMatchmethod,whichwillreturntrueifthereisatleastoneelementsothatthePredicateparameterpassedtoanyMatchistrue.Itmayalsoneedsomeaccommodationsothatwecoulduseastreaminsideanotherstream.Itverywellmaybeanexamplewhenastreamexpressionisovercomplicatedandneedstosplitupintosmallerpiecesusinglocalvariables.

Finally,beforeweleavethefunctionalstyle,werewritethecontainsOneOfmethodintheCheckHelperclass.Thiscontainsnonewelementsandwillhelpyoucheckwhatyouhavelearnedaboutmap,filter,flatMap,andCollector.Notethatthismethod,aswediscussed,returnstrueifordercontainsatleastoneoftheorderIDsgivenasstrings:

publicbooleancontainsOneOf(String...ids){

returnorder.getItems().stream()

.map(OrderItem::getProductId)

.flatMap(itemId->Arrays.stream(ids)

.map(id->tuple(itemId,id)))

.filter(t->Objects.equals(t.s,t.r))

.collect(Collectors.counting())>0;

}

WecreatethestreamoftheOrderItemobjects,andthenwemapittoastreamoftheIDsoftheproductscontainedinthestream.ThenwecreateanotherstreamforeachoftheIDswiththeelementsoftheIDandoneofthestringIDsgivenastheargument.Then,weflattenthesesubstreamsintoonestream.Thisstreamwillcontainorder.getItems().size()timesids.lengthelements:allpossiblepairs.WewillfilteroutthosepairsthatcontainthesameIDtwice,andfinally,wewillcountthenumberofelementsinthestream.

Page 669:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 670:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ScriptinginJava9Wearealmostreadywithoursampleprogramforthischapter.Thereisoneissue,thoughitisnotprofessional.Whenwehaveanewproductthatneedsanewchecker,wehavetocreateanewreleaseofthecode.

Programsinprofessionalenvironmentshavereleases.Whenthecodeismodified,bugsarefixed,oranewfunctionisimplemented,therearenumerousstepsthattheorganizationrequiresbeforetheapplicationcangointoproduction.Thesestepscomposethereleaseprocess.Someenvironmentshavelightweightreleaseprocesses;othersrequirerigorousandexpensivechecks.Itisnotbecauseofthetasteofthepeopleintheorganization,though.Whenthecostofanon-workingproductioncodeislowanditdoesnotmatterifthereisanoutageorwrongfunctioningintheprogram,thenthereleaseprocesscanbesimple.Thisway,releasesgetoutfasterandcheaper.Anexamplecanbesomechatprogramthatisusedforfunbytheusers.Insuchasituation,itmaybemoreimportanttoreleasenewfancyfeaturesthanensuringbug-freeworking.Ontheotherendofthepalette,ifyoucreatecodethatcontrolsanatomicpowerplant,thecostoffailurecanbeprettyhigh.Serioustestingandcarefulcheckingofallthefeatures,evenafterthesmallestchange,canpayoff.

Inourexample,simplecheckersmaybeanareathatisnotlikelytoinduceseriousbugs.Itisnotimpossiblebutthecodeissosimple...Yes,Iknowthatsuchanargumentisabitfishy,butlet'sassumethatthesesmallroutinescouldbechangedwithlesstestingandinaneasierwaythantheotherpartsofthecode.Howtoseparatethecodefortheselittlescripts,then,sothattheydonotrequireatechnicalrelease,anewversionoftheapplication,andnotevenrestartingtheapplication?Wehaveanewproductthatneedsanewcheckandwewanttohavesomewaytoinjectthischeckintotheapplicationenvironmentwithoutanyservicedisruption.

Thesolutionwechooseisscripting.JavaprogramscanexecutescriptswritteninJavaScript,Groovy,Jython(whichistheJVMversionofthelanguagePython),andmanyotherlanguages.ExceptJavaScript,thelanguageinterpretersoftheselanguagesarenotapartoftheJDK,buttheyallprovideastandardinterface,whichisdefinedintheJDK.Theconsequenceisthatwecanimplementscriptexecutioninourcodeandthedevelopers,whoprovidethescripts,arefreetochooseanyoftheavailablelanguages;wedonotneedtocaretoexecuteaJavaScriptcode.WewillusethesameAPIastoexecuteGroovyorJython.Theonlythingweshouldknowiswhatlanguagethescriptisin.Thisisusuallysimple:wecanguessthatfromthefileextension,andifguessingisnotenough,wecandemandthatthescriptdevelopersputJavaScriptintofileswiththe.jsextension,Jythonintofileswith.jyor.py,Groovyintofileswith.groovy,andsoon.Itisalsoimportanttonotethatifwewantourprogramtoexecuteoneoftheselanguages,weshouldmakesurethattheinterpreterisontheclasspath.InthecaseofJavaScript,thisisgiven;therefore,asademonstrationinthischapter,wewillwriteourscriptsinJavaScript.Therewillnotbealot;thisisaJavabookandnotaJavaScriptbookafterall.

Scriptingisusuallyagoodchoicewhenwewanttopasstheabilityofprogrammaticallyconfiguringorextendingourapplication.Thisisourcasenow.

Thefirstthingwehavetodoistoextendtheproductioninformation.Incasethereisascriptthatcheckstheconsistencyofanorderthataproductisin,weneedafieldwherewecanspecifythenameofthe

Page 671:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

script:

privateStringcheckScript;

publicStringgetCheckScript(){

returncheckScript;

}

publicvoidsetCheckScript(StringcheckScript){

this.checkScript=checkScript;

}

Wedonotwanttospecifymorethanonescriptperproduct;therefore,wedonotneedalistofscriptnames.Wehaveonlyonescriptspecifiedbythename.

Tobehonest,thedatastructureforthecheckerclassesandtheannotations,allowingmultipleannotationsperproductandalsopercheckerclass,wastoocomplicated.Wecouldnotavoidthat,though,tohaveacomplexenoughstructurethatcoulddemonstratethepowerandcapabilityofstreamexpressions.Nowthatweareoverthatsubject,wecangoonusingsimplerdatastructuresfocusingonscriptexecution.

WealsohavetomodifytheCheckerclasstonotonlyusethecheckerclassesbutalsothescripts.Wecannotthrowawaythecheckerclassesbecause,bythetimewerealizethatwebetterneedscriptsforthepurpose,wealreadyhavealotofcheckerclassesandwehavenofinancingtorewritethemtobescripts.Wellyes,weareinabookandnotinreallife,butinanenterprise,thatwouldbethecase.Thatiswhyyoushouldbeverycarefulwhiledesigningsolutionsforacorporate.Thestructuresandthesolutionswillbethereforalongtimeanditisnoteasytothrowapieceofcodeoutjustbecauseitistechnicallynotthebest.Ifitworksandisalreadythere,thebusinesswillbeextremelyreluctanttospendmoneyoncodemaintenanceandrefactoring.

Summary:wemodifytheCheckerclass.Weneedanewclassthatcanexecuteourscripts;thus,theconstructorismodified:

privatefinalCheckerScriptExecutorexecutor;

publicChecker(

@AutowiredCollection<ConsistencyChecker>checkers,

@AutowiredProductInformationCollectorpiCollector,

@AutowiredProductsCheckerCollectorpcCollector,

@AutowiredCheckerScriptExecutorexecutor){

this.checkers=checkers;

this.piCollector=piCollector;

this.pcCollector=pcCollector;

this.executor=executor;

}

WealsohavetousethisexecutorintheisConsistentmethod:

publicbooleanisConsistent(Orderorder){

finalMap<OrderItem,ProductInformation>map=

piCollector.collectProductInformation(order);

if(map==null){

returnfalse;

}

finalSet<Class<?extendsAnnotation>>annotations=

pcCollector.getProductAnnotations(order);

Predicate<Annotation>annotationIsNeeded=annotation->

annotations.contains(annotation.annotationType());

Predicate<ConsistencyChecker>productIsConsistent=

checker->

Arrays.stream(checker.getClass().getAnnotations())

.parallel().unordered()

Page 672:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

.filter(annotationIsNeeded)

.anyMatch(

x->checker.isInconsistent(order));

finalbooleancheckersSayConsistent=!checkers.stream().

anyMatch(productIsConsistent);

finalbooleanscriptsSayConsistent=

!map.values().

parallelStream().

map(ProductInformation::getCheckScript).

filter(Objects::nonNull).

anyMatch(s->

executor.notConsistent(s,order));

returncheckersSayConsistent&&scriptsSayConsistent;

}

Notethatinthiscode,weuseparallelstreamsbecause,whynot?Wheneveritispossible,wecanuseparallelstreams,evenunordered,totelltheunderlyingsystemandalsototheprogrammerfellowsmaintainingthecodethatorderisnotimportant.

WealsomodifyoneofourproductJSONfilestoreferenceascriptinsteadofacheckerclassthroughsomeannotation:

{

"id":"124",

"title":"DeskLamp",

"checkScript":"powered_device",

"description":"thisisalampthatstandsonmydesk",

"weight":"600",

"size":["300","20","2"]

}

EvenJSONissimpler.NotethataswedecidedtouseJavaScript,wedonotneedtospecifythefilenameextensionwhenwenamethescript.

Wemaylaterconsiderfurtherdevelopmentwhenwewillallowtheproductcheckerscriptmaintainerstousedifferentscriptinglanguages.Insuchacase,wemaystillrequirethattheyspecifytheextension,andincasethereisnoextension,itwillbeaddedbyourprogramas.js.Inourcurrentsolution,wedonotcheckthat,butwemaydevoteafewsecondstothinkaboutittobesurethatthesolutioncanbefurtherdeveloped.Itisimportantthatwedonotdevelopextracodeforthesakeoffurtherdevelopment.Developersarenotfortunetellersandcannottellreliablywhatthefutureneedswillbe.Thatisthetaskofthebusinesspeople.

Weputthescriptintotheresourcedirectoryofourprojectunderthescriptsdirectory.Thenameofthefilehastobepowered_device.jsbecausethisisthenamewespecifiedintheJSONfile:

functionisInconsistent(order){

isConsistent=false

items=order.getItems()

for(iinitems){

item=items[i]

print(item)

if(item.getProductId()=="126"||

item.getProductId()=="127"||

item.getProductId()=="128"){

isConsistent=true

}

}

return!isConsistent

}

Page 673:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ThisisanextremelysimpleJavaScriptprogram.Asasidenote,whenyouiterateoveralistoranarrayinJavaScript,theloopvariablewilliterateovertheindexesofthecollectionorthearray.SinceIrarelyprograminJavaScript,IfellintothistrapandittookmemorethanhalfanhourtodebugtheerrorImade.

Wehavepreparedeverythingweneedtocallthescript.Westillhavetoinvokeit.Todoso,weusetheJDKscriptingAPI.First,weneedaScriptEngineManager.ThismanagerisusedtogetaccesstotheJavaScriptengine.AlthoughtheJavaScriptinterpreterhasbeenapartoftheJDKsinceJava7,itisstillmanagedinanabstractway.ItisoneofthemanypossibleinterpretersthataJavaprogramcanusetoexecutescript.ItjusthappenstobethereintheJDK,sowedonotneedtoaddtheinterpreterJARtotheclasspath.ScriptEngineManagerdiscoversalltheinterpretersthatareontheclasspathandregistersthem.

ItdoessousingtheServiceProviderspecification,whichhasbeenapartoftheJDKforalongtime,andbyJava9,italsogotextrasupportinmodulehandling.ThisrequiresthescriptinterpreterstoimplementtheScriptEngineFactoryinterfaceandalsotolisttheclassthatdoesitintheMETA-INF/services/javax.script.ScriptEngineFactoryfile.Thesefiles,fromalltheJARfilesthatarepartoftheclasspath,arereadasresourcesbyScriptEngineManager,andthroughthis,itknowswhichclassesimplementscriptinterpreters.TheScriptEngineFactoryinterfacerequiresthattheinterpretersprovidemethodssuchasgetNames,getExtensions,andgetMimeTypes.Themanagercallsthesemethodstocollecttheinformationabouttheinterpreters.WhenweaskaJavaScriptinterpreter,themanagerwillreturntheonecreatedbythefactorythatsaidthatoneofitsnamesisJavaScript.

Togetaccesstotheinterpretersthroughthename,filenameextensionormime-typeisonlyoneofthefunctionsofScriptEngineManager.TheotheroneistomanageBindings.

WhenweexecuteascriptfromwithintheJavacode,wedon'tdoitbecausewewanttoincreaseourdopaminelevels.Inthecaseofscripts,itdoesnothappen.Wewantsomeresults.Wewanttopassparametersandaftertheexecutionofthescript,wewantvaluesbackfromthescriptthatwecanuseintheJavacode.Thiscanhappenintwoways.Oneisbypassingparameterstoamethodorfunctionimplementedinthescriptandgettingthereturnvaluefromthescript.Thisusuallyworks,butitmayevenhappenthatsomescriptinglanguagedoesnotevenhavethenotionofthefunctionormethod.Insuchacase,itisnotapossibility.Whatispossibleistopasssomeenvironmenttothescriptandreadvaluesfromtheenvironmentafterthescriptisexecuted.ThisenvironmentisrepresentedbyBindings.

BindingsisamapthathasStringkeysandObjectvalues.

Inthecaseofmostscriptinglanguages,forexample,inJavaScript,Bindingsisconnectedtoglobalvariablesinthescriptweexecute.Inotherwords,ifweexecutethefollowingcommandinourJavaprogrambeforeinvokingthescript,thentheJavaScriptglobalvariable,globalVariable,willreferencethemyObjectobject:

myBindings.put("globalVariable",myObject)

WecancreateBindingsandpassittoScriptEngineManagerbutjustaswellwecanusetheonethatitcreatesautomatically,andwecancalltheputmethodontheengineobjectdirectly.

TherearetwoBindingswhenweexecutescripts.OneissetontheScriptEngineManagerlevel.Thisisnamedglobalbinding.ThereisalsoonemanagedbyScriptEngineitself.ThisisthelocalBindings.Fromthescript

Page 674:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

pointofview,thereisnodifference.Fromtheembeddingside,thereissomedifference.IncaseweusethesameScriptEngineManagertocreatemultipleScriptEngineinstances,thentheglobalbindingsaresharedbythem.Ifonegetsavalue,allofthemseethesamevalue;ifonesetsavalue,allotherswilllaterseethatchangedvalue.Thelocalbindingisspecifictotheengineitismanagedby.SinceweonlyintroduceJavascriptingAPIinthisbook,wedonotgetintomoredetailsandwewillnotuseBindings.WearegoodwithinvokingaJavaScriptfunctionandtogettheresultfromit.

TheclassthatimplementsthescriptinvocationisCheckerScriptExecutor:

packagepackt.java9.by.example.mybusiness.bulkorder.services;

import...

@Component

publicclassCheckerScriptExecutor{

privatestaticfinalLoggerlog=...

privatefinalScriptEngineManagermanager=

newScriptEngineManager();

publicbooleannotConsistent(Stringscript,Orderorder){

try{

finalReaderscriptReader=getScriptReader(script);

finalObjectresult=

evalScript(script,order,scriptReader);

assertResultIsBoolean(script,result);

log.info("Script{}wasexecutedandreturned{}",

script,result);

return(boolean)result;

}catch(ExceptionwasAlreadyHandled){

returntrue;

}

}

Theonlypublicmethod,notConsistent,getsthenameofthescripttoexecuteandalsoorder.Thelatterhastobepassedtothescript.FirstitgetsReader,whichcanreadthescripttext,evaluatesit,andfinallyreturnstheresultincaseitisbooleanorcanatleastbeconvertedtoboolean.Ifanyofthemethodsinvokedfromherethatweimplementedinthisclassiserroneous,itwillthrowanexception,butonlyafterappropriatelyloggingit.Insuchcases,thesafewayistorefuseanorder.

Actually,thisissomethingthatthebusinessshoulddecide.Ifthereisacheckscriptthatcannotbeexecuted,itisclearlyanerroneoussituation.Inthiscase,acceptinganorderandlaterhandlingtheproblemsmanuallyhascertaincosts.Refusinganorderorconfirmationbecauseofsomeinternalbugisalsonotahappypathoftheorderprocess.Wehavetocheckwhichapproachcausestheleastdamagetothecompany.Itiscertainlynotthedutyoftheprogrammer.Inoursituation,weareinaneasysituation.

Weassumethatthebusinessrepresentativessaidthattheorderinsuchasituationshouldberefused.Inreallife,similardecisionsaremanytimesrefusedbythebusinessrepresentativessayingthatitjustshouldnothappenandtheITdepartmenthastoensurethattheprogramandthewholeoperationistotallybugfree.Thereisapsychologicalreasonforsucharesponse,butthisreallyleadsusextremelyfarfromJavaprogramming.

EnginescanexecuteascriptpassedthroughReaderorasString.Becausenowwehavethescriptcodeinaresourcefile,itseemstobeabetterideatolettheenginereadtheresourceinsteadofreadingittoaString:

Page 675:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privateReadergetScriptReader(Stringscript)

throwsIOException{

finalReaderscriptReader;

try{

finalInputStreamscriptIS=newClassPathResource(

"scripts/"+script+".js").getInputStream();

scriptReader=newInputStreamReader(scriptIS);

}catch(IOExceptionioe){

log.error("Thescript{}isnotreadable",script);

log.error("Scriptopeningexception",ioe);

throwioe;

}

returnscriptReader;

}

Toreadthescriptfromaresourcefile,weusetheSpringClassPathResourceclass.Thenameofthescriptisprependedwiththescriptsdirectoryandappendedbythe.jsextension.Therestisfairlystandardandnothingwehavenotseeninthisbook.Thenextmethodthatevaluatesthescriptismoreinteresting:

privateObjectevalScript(Stringscript,

Orderorder,

ReaderscriptReader)

throwsScriptException,NoSuchMethodException{

finalObjectresult;

finalScriptEngineengine=

manager.getEngineByName("JavaScript");

try{

engine.eval(scriptReader);

Invocableinv=(Invocable)engine;

result=inv.invokeFunction("isInconsistent",order);

}catch(ScriptException|NoSuchMethodExceptionse){

log.error("Thescript{}thruwup",script);

log.error("Scriptexecutingexception",se);

throwse;

}

returnresult;

}

Toexecutethemethodinthescript,firstofall,weneedascriptenginethatiscapableofhandlingJavaScript.Wegettheenginefromthemanagerbyitsname.IfitisnotJavaScript,weshouldcheckthatthereturnedengineisnotnull.InthecaseofJavaScript,theinterpreterispartoftheJDKandcheckingthattheJDKconformstothestandardwouldbeparanoid.

IfeverwewanttoextendthisclasstohandlenotonlyJavaScriptbutalsoothertypesofscripts,thischeckhastobedone,andalsothescriptengineshouldprobablyberequestedfromthemanagerbythefilenameextension,whichwedonothaveaccesstointhisprivatemethod.Butthatisfuturedevelopment,notinthisbook.

Whenwehavetheengine,wehavetoevaluatethescript.Thiswilldefinethefunctioninthescriptsothatwecaninvokeitafterwards.Toinvokeit,weneedsomeInvocableobject.InthecaseofJavaScript,theenginealsoimplementsanInvocableinterface.Notallscriptenginesimplementthisinterface.Somescriptsdonothavefunctionsormethods,andthereisnothingtoinvokeinthem.Again,thisissomethingtodolater,whenwewanttoallownotonlyJavaScriptscriptingbutalsoothertypesofscripting.

Toinvokethefunction,wepassitsnametotheinvokeFunctionmethodandalsotheargumentsthatwewanttopasson.Inthiscase,thisistheorder.InthecaseofJavaScript,theintegrationbetweenthetwolanguagesisfairlydeveloped.Asinourexample,wecanaccessthefieldandthemethodsoftheJavaobjectsthatarepassedasargumentsandthereturnedJavaScripttrueorfalsevalueisalsoconvertedtoBooleanmagically.Therearesomesituationswhentheaccessisnotthatsimplethough:

Page 676:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privatevoidassertResultIsBoolean(Stringscript,

Objectresult){

if(!(resultinstanceofBoolean)){

log.error("Thescript{}returnednonboolean",

script);

if(result==null){

log.error("returnedvalueisnull");

}else{

log.error("returnedtypeis{}",

result.getClass());

}

thrownewIllegalArgumentException();

}

}

}

Thelastmethodoftheclasschecksthatthereturnedvalue,whichcanbeanythingsincethisisascriptengine,isconvertibletoboolean.

Itisimportanttonotethatthefactthatsomeofthefunctionalityisimplementedinscriptdoesnotguaranteethattheapplicationworksseamlessly.Theremaybeseveralissuesandscriptsmayaffecttheinnerworkingoftheentireapplication.Somescriptingenginesprovidespecialwaystoprotecttheapplicationfrombadscripts,othersdonot.Thefactthatwedonotpassbutordertothescriptdoesnotguaranteethatascriptcannotaccessotherobjects.Usingreflection,staticmethods,andothertechniquestherecanbewaystoaccessjustanythinginsideourJavaprogram.Wemaybeabiteasierwiththetestingcyclewhenonlyascriptchangesinourcodebase,butitdoesnotmeanthatweshouldblindlytrustanyscript.

Inourexample,itprobablywouldbeaverybadideatolettheproducersoftheproductsuploadscriptstooursystem.Theymayprovidetheircheckscripts,butthesescriptshavetobereviewedfromthesecuritypointofviewbeforebeingdeployedintothesystem.Ifthisisproperlydone,thenscriptingisanextremelypowerfulextensiontotheJavaecosystem,givinggreatflexibilitytoourprograms.

Page 677:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 678:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

Inthischapter,wehavedevelopedtheorderingsystemofourenterpriseapplication.Alongwiththedevelopmentofthecode,wemetmanynewthings.Youlearnedaboutannotationsandhowtheycanbehandledbyreflections.Althoughnotstronglyrelated,youlearnedhowtouselambdaexpressionsandstreamstoexpresssomeprogrammingconstructssimplerthanconventionalloops.Inthelastpartofthechapter,weextendedtheapplicationusingscripting,byinvokingJavaScriptfunctionsfromJavaandalsobyinvokingJavamethodsfromJavaScript.

Infact,withallthisknowledge,wematuredtoaJavalevelthatisneededforenterpriseprogramming.Therestofthetopicsthebookcoversarefortheaces.Butyouwanttobeone,don'tyou?ThisiswhyIwrotetherestofthechapters.Readon!

Page 679:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 680:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

BuildinganAccountingApplicationUsingReactiveProgramming

Inthischapter,wewilldevelopasampleprogramthatdoestheinventorymanagementpartofthecompanywecreatedtheorderhandlingcodefor.Donotexpectafullydeveloped,ready-to-use,professionalapplication,andalso,donotexpectthatwewillgetintothedetailsofaccountingandbookkeeping.Thatisnotouraim.Wewillfocusmoreontheprogrammingtechniquethatisofourinterest—reactiveprogramming.Sorrypals,Iknowthatbookkeepingandaccountingisfun,butthisisnotthatbook.

Reactiveprogrammingisanold(well,whatisoldincomputerscience?)approachthathascomerecentlytoJava.Java9isthefirstreleasethatsupportssomeoftheaspectsofreactiveprogramminginthestandardJDK.Inonesentence,reactiveprogrammingisaboutfocusingmoreonhowthedataflowsandlessonhowtheimplementationhandlesthedataflow.Asyoumayrecall,thisisalsoasteptowardsdescribingwhatwewanttodofromthedescriptionofhowtodoit.

Aftergoingthroughthischapter,youwillunderstandwhatreactiveprogrammingisandwhattoolsthereareinJavathatyoucanutilize.Youwillalsounderstandwhatreactiveprogrammingisgoodforandwhenandhowyoucanutilizethisprincipleinthefuture,astherewillbemoreandmoreframeworkssupportingreactiveprogramminginJava.Inthischapter,youwilllearnthefollowingtopics:

ReactiveprogrammingingeneralReactivestreamsinJavaHowtoimplementoursamplecodeinareactiveway

Page 681:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 682:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Reactive...what?Therearereactiveprogramming,reactivesystems,andreactivestreams.Thesearethreedifferentthingsrelatedtoeachother.Itisnotwithoutreasonthatallthethreearecalledreactive.

Reactiveprogrammingisaprogrammingparadigmsimilartoobject-orientedprogrammingandfunctionalprogramming.Areactivesystemisasystemdesignthatsetscertainaimsandtechnologicalconstraintsonhowacertaintypeofinformationsystemsshouldbedesignedtobereactive.Therearealotofresemblancestoreactiveprogrammingprinciplesinthis.Areactivestreamisasetofinterfacedefinitionsthathelpstoachievesimilarcodingadvantagetoreactivesystemsandwhichcanbeusedtocreatereactivesystems.ReactivestreaminterfacesareapartofJDK9,butareavailablenotonlyinJava,butalsoinotherlanguages.

Wewilllookattheseinseparatesections,attheendofwhich,youwillpresumablyhaveabetterunderstandingofwhyeachofthemiscalledreactive.

Page 683:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 684:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReactiveprogramminginanutshellReactiveprogrammingisaparadigmthatfocusesmoreonwherethedataflowsduringcomputationthanonhowtocomputetheresult.Iftheproblemisbestdescribedasseveralcomputationsthatdependontheoutputofeachotherbutseveralmaybeexecutedindependentoftheother,reactiveprogrammingmaycomeintothepicture.Asasimpleexample,wecanhavethefollowingcomputationthatcalculatesthevalueofhfromsomegivenb,c,e,andfvalues,usingf1,f2,f3,f4,andf5assimplecomputationalsteps:

a=f1(b,c)

d=f2(e,f)

k=f3(e,c)

g=f4(b,f,k)

h=f5(d,a,g)

IfwewritetheseinJavaintheconventionalway,themethodsf1tof5willbeinvokedoneaftertheother.Ifwehavemultipleprocessorsandareabletoparallelizetheexecution,wemayperformsomeofthemethodsinparallel.This,ofcourse,assumesthatthesemethodsarepurelycomputationalmethodsanddonotchangethestateoftheenvironment,and,inthisway,canbeexecutedindependentofeachother.Forexample,f1,f2,andf3canbeexecutedindependentofeachother.Theexecutionofthefunctionf4dependsontheoutputoff3,andtheexecutionoff5dependsontheoutputoff1,f2,andf4.

Ifwehavetwoprocessors,wecanexecutef1andf2together,followedbytheexecutionoff3,thenf4,andfinally,f5.Thesearefoursteps.Ifwelookattheprecedingcalculationnotascommandsbutratherasexpressionsandhowthecalculationsdependoneachother,thenwedonotdictatetheactualexecutionorderandtheenvironmentmaydecidetocalculatef1andf3together,thenf2andf4,andfinallyf5,savingonestep.Thisway,wecanconcentrateonthedataflowandletthereactiveenvironmentactuponitwithoutputtingextraconstraints.

Thisisaverysimpleapproachofreactiveprogramming.Thedescriptionofthecalculationintheformofexpressionsgivesthedataflow,butintheexplanation,westillassumedthatthecalculationisexecutedsynchronously.Ifthecalculationsareexecutedondifferentprocessorsthatareondifferentmachines

Page 685:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

connectedtoanetwork,thenthecalculationmaynotanddoesnotneedtobesynchronous.Reactiveprogramscanbeasynchronouslyexecutediftheenvironmentisasynchronous.Itmayhappenthatthedifferentcalculations,f1tof4,areimplementedanddeployedondifferentmachines.Insuchacase,thevaluescalculatedaresentfromonetotheotheroverthenetworkandthenodesexecutethecalculationeverytimethereisachangeintheinputs.Thisisverysimilartogoodoldanalogcomputersthatwerecreatedusingsimplebuildingblocksandthecalculationsweredoneusinganaloguesignals.

Theprogramwasimplementedasanelectroniccircuit,andwhentheinputvoltageorcurrent(usuallyvoltage)changedintheinputs,theanalogcircuitsfolloweditinlight'sspeed,andtheresultappearedintheoutput.Insuchacase,thesignalpropagationwaslimitedbythespeedoflightonthewiresandanalogcircuitryspeedinthewiredmodules,whichwasextremelyfastandmaybeatdigitalcomputers.

Whenwetalkaboutdigitalcomputersthepropagationofthesignalisdigital,andthisway,itneedstobesentfromonecalculationnodetotheotherone,beitsomeobjectinJVMorsomeprogramonthenetwork.Anodehastoexecuteitscalculationif:

SomeofthevaluesintheinputhavechangedTheoutputofthecalculationisneeded

Iftheinputhasnotchanged,thentheresultshouldeventuallybethesameasthelasttime;thus,thecalculationdoesnotneedtobeexecutedagain—itwouldbeawasteofresources.Iftheresultofthecalculationisnotneeded,thenthereisnoneedtoperformthecalculationeveniftheresultwouldnotbethesameasthelastone.Noonecares.

Toaccommodatethis,reactiveenvironmentsimplementtwoapproachestopropagatethevalues.Thenodesmaypullthevaluesfromtheoutputofothermodules.Thiswillensurethatnocalculationthatisnotneededwillbeexecuted.Themodulesmaypushtheiroutputtothenextmodulethatdependsonthem.Thisapproachwillensurethatonlychangedvaluesignitecalculation.Someoftheenvironmentsmayimplementahybridsolution.

Whenvalueschangeinthesystem,thechangeispropagatedtowardstheothernodesthatagainpropagatethechangestoanothernodeandsoon.Ifweimaginethecalculationdependenciesasadirectedgraph,thenthechangestraveltowardsthetransitiveclosureofthechangedvaluesalongthenodesconnected.Thedatamaytravelwithallthevaluesfromonenodeoutputtotheothernodeinputoronlythechangemaytravel.Thesecondapproachismorecomplexbecauseitneedsthechangeddataandalsometainformationthatdescribeswhathaschanged.Ontheotherhand,thegainmaybesignificantwhentheoutputandinputsetofdataishugeandonlyasmallportionofitischanged.Itmayalsobeimportanttocalculateandpropagateonlytheactualdeltaofthechangewhenthereisahighprobabilitythatsomeofthenodesdonotchangetheoutputformanyofthedifferentinputs.Insuchacase,thechangepropagationmaystopatthenodewherethereisnorealchangeinspiteofthechangedinputvalues.Thiscansaveupalotofcalculationinsomeofthenetworks.

Intheconfigurationofthedatapropagation,thedirectedacyclicgraphcanbeexpressedinthecodeoftheprogram,itcanbeconfiguredoritcanevenbesetupandchangedduringtheexecutionofthecodedynamically.Whentheprogramcodecontainsthestructureofthegraph,theroutesandthedependenciesarefairlystatic.Tochangethedatapropagation,thecodeoftheprogramhastobechanged,recompiled,

Page 686:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

anddeployed.Inthecaseofmultiplenetworknodeprograms,thismayevenneedmultipledeploymentsthatshouldbecarefullyfurnishedtoavoiddifferentincompatibleversionsrunningondifferentnodes.Thereshouldbesimilarconsiderationswhenthegraphisdescribedinsomeconfiguration.Insuchacase,thecompilationoftheprogram(s)maynotbeneededwhenonlythewiringofthegraphischanged,buttheburdentohavecompatibleconfigurationondifferentnodesinthecaseofanetworkexecutionisstillthere.

Lettingthegraphchangedynamicallyalsodoesnotsolvethisproblem.Thesetupandthestructurearemoreflexibleand,atthesametime,morecomplex.Thedatapropagatedalongtheedgesofthegraphmaycontainnotonlycomputationaldatabutalsodatathatdriveschangeinthegraph.Manytimes,thisleadstoaveryflexiblemodelcalledhigher-orderreactiveprogramming.

Reactiveprogramminghasalotofbenefitsbut,atthesametime,maybeverycomplex,sometimestoocomplex,forsimpleproblems.Itistobeconsideredwhentheproblemtobesolvedcaneasilybedescribedusingdatagraphandsimpledatapropagations.Wecanseparatethedescriptionoftheproblemandtheorderoftheexecutionofthedifferentblocks.Thisisthesameconsiderationthatwediscussedinthepreviouschapter.Wedescribemoreaboutthewhattodopartandlessaboutthehowtodopart.

Ontheotherhand,whenthereactivesystemdecidestheorderofexecution,whatischanged,andhowthatshouldbereflectedontheoutputofotherblocks,itshoulddosowithoutknowingthecoreoftheproblemthatitissolving.Insomesituations,codingtheexecutionordermanuallybasedontheoriginalproblemcouldperformbetter.

Thisissimilartothememorymanagementissue.Inmodernruntimeenvironments,suchastheJVM,Pythonruntime,Swiftprogramming,orevenGolang,thereissomeautomatedmemorymanagement.WhenprogramminginC,theprogrammerhasfullcontrolovermemoryallocationandmemoryrelease.Inthecaseofreal-timeapplications,wheretheperformanceandresponsetimeisoftheutmostimportance,thereisnowaytoletanautomatedgarbagecollectortaketimeanddelaytheexecutionfromtimetotime.Insuchacase,theCcodecanbeoptimizedtoallocatememorywhenneeded;thereisaresourcefortheallocationandreleaseofmemorywhenpossibleandthereistimetomanagememory.Theseprogramsarebetterperformingthantheonescreatedforthesamepurposeusingagarbagecollector.Still,wedonotuseCinmostoftheapplicationsbecausewecanaffordtheextraresourceneededforautomatedmemorycollection.Eventhoughitwouldbepossibletowriteafastercodemanagingthememorymanually,automatedcodeisfasterthanwhatanaverageprogrammerwouldhavecreatedusingC,andalso,thefrequencyofprogrammingerrorsismuchlower.

Justastherearesomeissuesthatwehavetopayattentiontowhenusingautomatedmemorymanagement,wehavetopayattentiontosomeissuesinareactiveenvironment,whichwouldnotexistinthecaseofmanualcoding.Still,weusethereactiveapproachforitsbenefits.

Themostimportantissueistoavoidloopsinthedependencygraph.Althoughitisabsolutelyperfecttowritethedefinitionofcalculations,areactivesystemwouldprobablynotbeabletocopewiththesedefinitions.Somereactivesystemsmayresolveinsomesimple-casecyclicredundancy,butthatissomeextrafeatureandwegenerallyjusthavetoavoidthat.Considerthefollowingcomputations:

Page 687:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

a=b+3

b=4/a

Here,adependsonb,sowhenbchanges,aiscalculated.However,balsodependsona,whichisrecalculatedand,inthisway,thesystemgetsintoaninfiniteloop.Theprecedingexampleseemstobesimple,butthatisthefeatureofagoodexample.Real-lifeproblemsarenotsimple,andinadistributedenvironment,itisextremelyhardsometimestofindcyclicredundancy.

Anotherproblemiscalledglitch.Considerthefollowingdefinition:

a=b+3

q=b+a

Whentheparameterbischanged,forexample,from3to6,thevalueofawillchangefrom6to9,andthus,qwillchangefrom9to15.Thisisverysimple.However,theexecutionorderbasedontherecognitionofthechangesmayfirstalterthevalueofqfrom9to12beforemodifyingitto15inasecondstep.Thiscanhappenifthecalculatingnoderesponsibleforthecalculationofqrecognizesthechangeinbbeforethevalueofaasaconsequenceofthechangeinthevalueofb.Forashortperiodoftime,thevalueofqwillbe12,whichdoesnotmatchthepreviousandalsodoesnotthechangedstate.Thisvalueisonlyaglitchinthesystemthathappensafteraninputchangesandalsodisappearswithoutanyfurtherchangeintheinputinthesystem.

Ifyouhaveeverlearntthedesignoflogicalcircuits,thenstatichazardsmayringabell.Theyareexactlythesamephenomenon.

Reactiveprogrammingalsoassumesthatthecalculationsarestateless.Theindividualnodesthatperformthecalculationmayhaveastateinpracticeand,manytimes,theydo.Itisnotinherentlyeviltohaveastateinsomecalculation.However,debuggingsomethingthathasastateissignificantlymorecomplexthandebuggingsomethingthatisstateless,functional.

Itisalsoanimportantaidtothereactiveenvironment,lettingitperformdifferentoptimizationsbasedonthefactthatthecalculationsarefunctional.Ifthenodeshaveastate,thenthecalculationsmaynotbe

Page 688:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

rearrangedfreelybecausetheoutcomemaydependontheactualevaluationorder.Thesesystemsmaynotreallybereactive,or,atleast,itmaybedebated.

Page 689:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 690:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Reactivesystems

Reactivesystemisdefinedinthereactivemanifestoathttp://www.reactivemanifesto.org/.Thecreatorsofthemanifestorealizedthatwiththechangeoftechnology,newsystempatternswillneedtobedevelopedinenterprisecomputingtoleveragethenewtechnologyandyieldbetteroutcomes.Themanifestoenvisionssystemsthatare:

ResponsiveResilientElasticMessage-driven.

Thefirstthreefeaturesareuservalues;thelastoneismoreofatechnologicalapproachtogetthevalues.

Page 691:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 692:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ResponsiveAsystemisresponsiveifitgivesresultsinareliablemanner.Ifyoutalktome,Iwillansweryourquestionor,atleast,tellyouthatIdonotknowtheanswerorthatIwasnotabletounderstandthequestion.Betterifyougettheanswer,butifasystemcannotgivethattoyouitisstillexpectedtogivesomethingback.Ifyouhavepastexperiencewithclientoperatingsystemsfromjusttenyearsagoandsomeoldcomputers,youcanunderstandthis.Gettingarotatinghourglassisfrustrating.Youjustdonotknowwhetherthesystemisworkingtogetyoutheansweroristotallyfrozen.

Areactivesystemhastoberesponsive.Theresponseshouldcomeinatimelymanner.Theactualtimingdependsontheactualsystem.Itmaybemilliseconds,seconds,orevenhoursincasethesystemisrunningonaspaceshiptravellingtowardstheothersideofJupiter.Theimportantthingisthatthesystemshouldguaranteesomesoftupperlimitfortheresponsetime.Thisdoesnotnecessarilymeanthatthesystemshouldbeareal-timesolution,whichisamuchstricterrequirement.

Theadvantageofresponsivenessisnotonlythattheuserdoesnotbecomenervousinfrontofthecomputer.Afterall,mostoftheseservicesareusedbyotherservicesthatmainlycommunicatewitheachother.Therealadvantageisthaterrordiscoveryismorereliable.Ifareactivesystemelementbecomesnonresponsive,itiscertainlyanerrorcondition,andsomethingshouldbedoneaboutit,outofthescopeofnormaloperations(replaceafaultycommunicationcard,restartasystem,andsoon).Thesoonerwecanidentifyanerrorstate,thecheaperitistofixit.Themorewecanidentifywheretheproblemis,thelesstimeandmoneywecouldspendlocalizingtheerror.Responsivenessisnotaboutspeed.Itisaboutbetteroperation,betterquality.

Page 693:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 694:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ResilientResilientsystemskeepworkingevenwhenthereissomeerror.Well,notanyerror.Thatwouldbeamiracle,orsimplynonsense!Anerrorgenerallyisanerror.IftheArmageddoncomesanditistheendoftheworldasweknowit,evenresilientsystemswillnotberesponsive.Forsmallerdisruptions,however,theremaybesomecuretomakethesystemsresilient.

Therearetechniquesthatmayhelpifonlyadiskfails,thereisapoweroutage,orthereisaprogrammingerror.Systemsmaybereplicated,sowhenoneoftheinstancesstopsresponding,someotherinstancemaytakeupthetaskofthefailingoneandcangoonworking.Systemspronetoerrorsmaybeisolatedfromeachotherintermsofspaceortime.Whenthereisanearthquakeorfloodatonelocation,theotherlocationmaystillgoonworking.Ifdifferentcomponentsdonotneedtocommunicateinrealtimeandmessagesarestoredandforwardedinareliablemanner,thenthisisnotaproblemevenifthetwosystemsareneveravailableatthesametime.Theycanstillcooperatetakingupthemessages,performingthetasktheyaresupposedto,andsendingouttheresultingmessageafterwards.

Errorsinthesystemhavetobeaddressedevenifthesystemremainsresponsive.Errorsdonotaffecttheresponsivenessofaresilientsystem,butthelevelofresiliencedecreasesandshouldberestored.

Page 695:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 696:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ElasticElasticitymeansthatthesystemisadaptingtotheload.Wecanhaveahugesystem,withlotsofprocessorscapableofservingthelargestanticipateddemand.Thatisnotelasticity.Sincethedemandisnotconstantand,mostofthetime,issmallerthanthemaximum,theresourcesofsuchasystemareidle.Thiscauseswasteoftime,CPUcycle,energy,and,thus,ecologicalfootprint.

Havingsystemsrunonthecloudcanavoidsuchlosses.Thecloudisnothingbutmanycomputersthatsomebodyoperatesformultipleapplications,formultiplecorporationseven,andeachrentsonlytheCPUcyclesthatitreallyneedsandonlywhenitneeds.Othertimes,whentheloadissmallertheCPUandtheelectricpowercanbeusedbysomeoneelse.Sincedifferentapplicationsanddifferentcorporationshavedifferentpeaktimes,thelossofresourcesislesswiththismodel.Therearemanyissuesthathavetobesolved,suchasdataisolationandprotectionofinformationfromeavesdropping,butthesearemainlysolved.Secretservicecorporationswillnotrentresourcesfromacloudservicetoruntheircomputations(perhaps,they'ddoforsomeotherpurpose)andsomeotherparanoidcompaniesmayalsorefrainfromdoingthat,butmostofthecompanieswilldo.Itismoreeffectiveandisthuscheaperevenafterconsideringallthesideeffectsonecanconsider.

Elasticitymeansthattheallocatedresourcesfollow,orratheranticipatethecomingneeds.Whenthesystemanticipateshighercapacityneeds,itallocatesmoreresourcesandatoff-peaktime,itreleasestheresourcessothatothercloudcustomerscanuseit.

Elasticityalsoassumesthatthesystemisscalable.Thetwothings,elasticityandscalability,arecloselyrelatedbutarenotthesame.Scalabilitymeansthattheapplicationcanaccommodatehigherload,allocatingmoreresources.Scalabilitydoesnotcarewhetherthisallocationisstaticbuyingandpoweringofhugecomputerboxesinacomputingcenterdedicatedtotheapplicationordynamicallocationofresourcesfromthecloudondemand.Scalabilitysimplymeansthatifthedemanddoubles,thentheresourcescanalsobemultipliedtomeetthedemand.Ifthemultiplicationfactorintheresourcesneededisthesameorisnotmorethanthefactorindemand,thentheapplicationisscalable.Ifweneedmoreresourcestomeetthedemand,orifwecannotmeetthedemandevenifthedemandincreasesonlymoderately,thentheapplicationisnotscalable.Elasticapplicationsarealwaysscalable;otherwise,theycannotbeelastic.

Page 697:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 698:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Message-drivenReactivesystemsaremessage-driven;notbecauseweneedmessage-drivensystemsbutmuchratherbecausemessage-drivensystemsarethosethatcandeliverresponsiveness,resilience,andelasticityatthesametime.

Message-drivenarchitecturemeansthattheinformationtravelsbetweenthecomponentsdisconnected.Onecomponentsendsamessageandthenforgetsit.Itdoesnotwaitfortheothercomponenttoactuponthemessage.Whenthemessageissent,allthetasksonbehalfofthesendingcomponentareperformedandalltheresourcesneededtohandlethetasksarereleased,resultinginthemessagebeingreleasedandreadytobeusedforthenexttask.

Message-drivendoesnotnecessarilymeannetworking.Messagescantravelbetweenobjects,threads,andprocessesinsidethesamemachine.Ontheotherhand,iftheinterfacestothemessagingarchitecturearewell-designed,thenthecomponentsdonotneedtobemodifiediftheinfrastructurechangesandthemessagesthatwerepreviouslypassingbetweenthreadswillnowhavetotravelthroughtheoceaninIPpackets.

Sendingmessagesmakesitpossibletoisolatethesenderandthereceiverinspaceandtime,justaswedescribed,asameansforelasticity.Thereceivermaypickupthemessagesometimeafteritarrived,whenithastheresourcestodoso.Responsiveness,though,requiresthatthistimeisnotintheunreachabledistantfuturebutinsomelimiteddistance.Ifthemessagecannotbeprocessedsuccessfully,anothermessagemaysignaltheerror.Anerrormessageisnottheresultweexpect,butitisstillsomeresponseandthesystemremainsresponsivewithallthebenefitsitmeans.

Page 699:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 700:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Back-pressureMessagehandling,withtheappropriatemessaginginterfacesandimplementation,supportsback-pressure.Back-pressureisameanstolessentheburdenonacomponentwhenitcannotorcanbarelyhandlemoremessages.Messagesmaybequeuingforprocessing,butnoreal-lifequeuehasunlimitedcapacityandreactivesystemsshouldnotloseamessageuncontrolled.Back-pressuresignalstheloadofthecomponenttothemessageproducers,askingthemtolessentheproduction.Itislikeawaterpipe.Ifyoustartclosingtheoutletofthepipe,thepressurestartstoincreaseinthepipebackward,thewatersourceforcingittodeliverlessandlesswater.

Back-pressureisaneffectivewayofhandlingloadbecauseitmovesloadhandlingtothecomponentthatcanreallydoit.Inold-fashionedqueuingsystems,thereisaqueuethatstorestheitemstillthecomponentreceivingthemcanconsumethem,doingitsjob.Aqueuedesigncanbegoodifthereisawell-definedlimitforthesizeoftheloadandforthemaximumsizeofthequeue.Ifeverthequeueisfull,theitemscannotbedeliveredandthesystemstalls.

Applyingback-pressureisabitdifferent.Aqueuemaystillbeusedinfrontofthecomponentsforperformanceoptimizationandtoensureresponsiveness.Theproduceroftheitemcanstillputtheproducediteminthequeueandreturntoattendingtoitsowndutiesanddoesnotneedtowaittilltheconsumercanattendtotheitem.Thisisdecoupling,aswementionedearlier.Seeingthatthequeueisfulloralmostfullcanalsoactasaverysimpleback-pressure.Itisnottrueifsomeonesaysthatqueuesaretotallymissingthisfeature.Attimes,itmaysimplybetotallysufficientjusttolookatthecapacityofaqueue,andalsotheitemsinit,toseeifthereissomeneedtolessentheloadonthereceiverthequeuebelongsto.Buttheproducerdoesthis,notthereceiver,andthatisanessentialproblem.

Theproducerseesthatthereceiverisnotkeepingpacewiththesupplybuttheproducerdoesnothaveanyinformationaboutthecause,andnotknowingthecausecannotpredictthefuturebehavior.Havingaback-pressureinformationchannelfromthereceivertotheproducermakesthestorymorefinegrained.

Theproducermayseethatthereare,say,10slotsinthequeueanditthinksthatthereisnoproblem;theproducerdecidestodelivereightmoreitemsinthenext150ms.Oneitemusuallytakes10mstoprocess,giveortake;thustheitemsareexpectedtobeprocessedinlessthan100ms,whichisjustbetterthantherequired200msmaximum.Theproduceronlyknowsthatanitemusuallytakes10mstoprocess.Thereceiver,ontheotherhand,seesthatthelastitemitgotintothequeuerequiressomuchprocessingthat,byitself,itwillrequire200ms.Tosignalthis,itcantelltheproducerovertheback-pressurenottodelivernewitemstillfurthernotice.Thereceiverknowsthattheitemswouldhavefitinthequeuefinebutwouldnotbeprocessedinatimelymanner.Usingthisinformation,theproducerwillissuesomecommandstothecloudcontroltoallocateanotherprocessingandsendsthenexteightitemstothenewreceiver,lettingtheoldonedoitscumbersomejobithastowiththatfarabovethanaverageitem.

Back-pressureletsyouaidthedataloadcontrol,withinformationcreatedbythereceiversthathavethemostinformationaboutprocessingtheitems.

Page 701:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 702:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReactivestreamsReactivestreamsstartedasaninitiativetoprovideastandardofhandlingdatastreamsinanasynchronousmodebyregulatingthepushofthedatausingback-pressure.Theoriginalsiteoftheprojectishttp://www.reactive-streams.org/.

ReactivestreamsarenowimplementedinJDK9inthejava.util.concurrentpackage.

Theaimofthedefinitionofreactivestreamsistodefinetheinterfacethatcanhandlethepropagationofthegenerateddatainatotallyasynchronouswaywithouttheneedonthereceivingsidetobuffertheunlimitedcreateddata.Whendataiscreatedinastreamandismadeavailabletobeworkedontheworkerthatgetsthedata,hastobefastenoughtohandleallthedatathatisgenerated.Thecapacityshouldbehighenoughtohandlethehighestproduction.Someintermediatebuffersmayhandlepeaks,butifthereisnocontrolthatstopsordelaysproductionwhentheconsumerisatthetopofitscapacity,thesystemwillfail.Reactivesysteminterfacesaredesignedtoprovideawaytosupportback-pressure.Back-pressureisaprocesstosignaltheproducerofthedatatoslowdownoreventostoptheproductiontothelevelthatfitstheconsumer.Everycalltheinterfacesdefineisasynchronoussothattheperformanceofonepartisnotaffectedbythedelaysintheexecutionofotherparts.

Theinitiativedidnotaimtodefinethewayinwhichdataistransferredbetweenproductionandconsumption.ItfocusesontheinterfacestogiveaclearstructurefortheprogramsandalsotogiveanAPIthatwillworkwithalltheimplementations.

Page 703:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 704:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReactiveprogramminginJavaJavaisnotareactivelanguage.ThisdoesnotmeanthatwecannotcreatereactiveprogramsinJava.Therearelibrariesthatsupportdifferentreactiveprogrammingapproaches.ItistomentiontheAkkaframeworkandtheReactiveXthatalsoexistforotherlanguagesaswell.WithJava9,theJDKstartstosupportreactiveprogramming,providingafewclassesandinterfacesforthepurpose.Wewillfocusonthesefeatures.

TheJDKcontainsthejava.util.concurrent.Flowclass,whichcontainsrelatedinterfacesandsomestaticmethodstosupportflowcontrolledprograms.ThemodelthatthisclasssupportsisbasedonPublisher,Subscriber,andSubscription.

Asaverysimpleexplanation,aPublisheracceptsasubscriptionfromaSubscriber.ASubscribergetsthedataitsubscribedtowhenthedataisavailable.Theinterfacesfocusontheverycoreofthedataflowcontrolofthecommunicationandareabitabstract.Nosurprise,theyareinterfaces.However,itmaynotbesimpletounderstandtheirworkingatfirst.

ThePublisherinterfacedefinesthesubscribemethod.Thisistheonlymethodthisinterfacedefinesandthatisbecausethisistheonlythingthatarealpublishercanbeasked.Youcansubscribetothepublications.TheargumentofthemethodisaSubscriberthatsubscribestothepublications:

voidsubscribe(Flow.Subscriber<?superT>subscriber)

ThereisareadilyavailablePublisherclassintheJDKthatwewilllookatlater.WhenthesubscribemethodofthePublisheriscalled,ithastodecideifthesubscribercangetthesubscriptionornot.Usually,thesubscriptionisacceptedbuttheimplementationhasthefreedomtorefuseasubscriptionattempt.Publishermayrefuseasubscriptionif,forexample,thesubscriptionfortheactualsubscriberwasalreadyperformedandthePublisherimplementationdoesnotallowmultiplesubscriptionsfromthesamesubscriber.

TheimplementationofthemethodisrequiredtocalltheonErrormethodofsubscriber,withThrowableastheargument.Inthecaseofmultiplesubscriptions,IllegalStateExceptionseemstobesuitable,astheJDKdocumentationdefinesatthemoment.

Ifthesubscriptionissuccessful,PublisherisexpectedtocalltheonSubscribemethodofsubscriber.TheargumenttothismethodisaSubscriptionobject(aninstanceofaclassthatimplementstheinterfaceSubscription).Thisway,thePublishernotifiestheSubscriberthatthesubscriptionrequestwasaccepted,andalsopassesanobjecttomanagethesubscription.

Managingthesubscriptionasanabstractioncouldbeimaginedasacomplextask,butinthecaseofreactivestreams,itisverysimple.Allthesubscribercanandshoulddoistosetthenumberofitemsitcanreceiveatthemoment,andthesubscriptioncanbecancelled.

WhyshouldthePublishercallbacktheonSubscribemethodofSubscriber?Whydoesn'titsimplyreturnthesubscriptionorthrowsomeerror?ThereasonforthiscomplexbehavioristhatitmaynotbetheSubscriberthatinvokesthesubscribemethod.Justasinreallife,I

Page 705:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

cansubscribeandpayforayearofamagazinesubscriptionasaChristmasgift.(ThisistheseasonwhenIamwritingthispartofthebook.)Inourcode,somewiringcomponentresponsibleforwhoisnotifiedaboutacertaindatachangecallssubscribeandnotnecessarilythesubscriber.TheSubscriberisonlyresponsiblefortheminimalthingsthatasubscribershouldberesponsiblefor.Theotherreasonisthatthewholeapproachisasynchronous.Whenwesubscribetosomething,thesubscriptionmaynotbeavailableandreadyimmediately.Therecouldbesomelong-runningprocessesthatneedtofinishtillthesubscriptionwillbeavailableandthecallerthatiscallingsubscribedoesnotneedtowaitforthecompletionoftheprocess.Whenthesubscriptionisreadyitispassedtothesubscriber,totheveryentitythatreallyneedsit.

TheSubscriberinterfacedefinestheonSubscribe,onError(wehavealreadytalkedaboutthese),onCompleteandonNextmethods.

ItisimportantinthedefinitionoftheseinterfacesthatthesubscribergetstheitemsfromPublisherorfromsomeotherobjecttowhichthePublisherdelegatesthistaskviasomepush.Thesubscriberdoesnotneedtogotothenewsstandtogetthenextissue;someonecallingtheonNextmethoddeliverstheissuetoitdirectly.

ThisalsobearstheconsequencethatunlesstherearesomecontrolsinthehandsoftheSubscriber,itcouldhappenthatthePublisherfloodstheSubscriberwithitems.NoteverySubscriberiscapableofhandlingunlimiteditems.TheSubscribergetsaSubscriptionobjectuponperformingthesubscriptionandthisobjectcanbeusedtocontroltheflowoftheitemobjects.

ThePublishercreatestheSubscriptionobjectandtheinterfacedefinestwomethods:cancelandrequest.ThecancelmethodshouldbecalledbytheSubscribertonotifythePublisherthatitshouldnotdelivermoreitems.Thesubscriptioniscancelled.Therequest(longn)methodspecifiesthatthesubscriberispreparedtogetatmostnitemsviasubsequentcallstotheonNextmethod:

Ifthesubscriberhasalreadyinvokedtherequestmethod,thespecifiednumberisaddedtothesubscriptioncounter.Inotherwords,thespecifiedlongvaluedoesnotreflecttheactualstateofthesubscriber.Itisa

Page 706:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

delta,increasingsomecountersmaintainedbythePublisherthatcountsthenumberofitemsthatcanbedeliveredaddingthevalueofthelongargumentanddecrementingbyoneoneachitemdeliveredtotheSubscriber.Themostusualapproachistocallrequest(1)eachtimetheSubscriberhasfinishedprocessingarequest.

IftherequestmethodisinvokedwiththeLong.MAX_VALUEargument,thePublishermayjustsendanyitemthatitcanwithoutcountingandwithoutlimit.Thisisessentiallyswitchingofftheback-pressuremechanism.

Thespecificationalsomentionsthatthecalltocanceldoesnotnecessarilymeanthattherewillbenomoreissuesdeliveredatall.Cancellationisdoneonbesteffort.Justasinreallife,whenyousendyourmailtothedailypaperwithyourintenttocancelthesubscription,thepublisherwillnotsendanagenttostopthepostmanbeforehedropstheissuetoyourmailbox.Ifsomethingwasalreadyonitswaywhenthecancellationarrivedtothepublisheritgoesitsway.IfthePublisherhasalreadystartedsomeasynchronousprocessthatcannotreasonablybestopped,thenthemethodonNextmethodwillbeinvokedwithsomeoftheelements.

ThePublisherandSubscriberinterfaceshaveagenericparameter,T.ThisisthetypeofitemsthatthePublisherinterfacepublishesandtheSubscriberinterfacegetsintheonNextmethod.Tobeabitmoreprecise,theSubscriberinterfacecanhaveanRtype,whichisasuperclassofT;thus,itiscompatiblewiththePublisherinterface.Forexample,ifPublisherpublishesLongvalues,thentheSubscriberinterfacecanacceptLong,Number,orObjectintheargumentoftheonNextmethod,dependingonthedeclarationoftheclassthatimplementsSubscriber.

TheFlowclassalsocontainsaProcessorinterfacethatextendsbothPublisherandSubscriber.Thisinterfaceistheretobeimplementedbyclassesthatalsoacceptdataandsenddatatoothercomponentsinthereactiveflow.Suchelementsareverycommoninreactivestreamprogramsbecausemanyelementsthatperformsometasksgettheitemstoworkonfromotherreactivestreamelements;thus,theyareSubscribersand,atthesametime,theysenditaftertheyhavefinishedtheirtasks;thus,theyarePublishers.

Page 707:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 708:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ImplementinginventoryNowthatwehavediscussedalotoftechnologiesandprogrammingapproach,itisverymuchthetimetoimplementsomesamplecode.Wewillimplementinventorykeepinginourapplicationusingreactivestreams.Fortheexample,theinventorywillbeverysimple.ItisaMap<Product,InventoryItem>thatholdsthenumberofitemsforeachproduct.TheactualmapisConcurrentHashMapandtheInventoryItemclassisabitmorecomplexthanaLongnumbertoproperlyhandleconcurrencyissues.Whenwedesignaprogramthatisbuiltonresponsivestreams,wedonotneedtodealwithmuchconcurrencylocking,butwestillshouldbeawarethatthecoderunsinamultithreadenvironmentandmayexhibitstrangebehaviorifwedonotfollowsomerules.

ThecodefortheInventoryclassisfairlysimplesinceithandlesonlyamap:

packagepackt.java9.by.example.mybusiness.inventory;

import...;

@Component

publicclassInventory{

privatefinalMap<Product,InventoryItem>inventory=

newConcurrentHashMap<>();

privateInventoryItemgetItem(Productproduct){

inventory.putIfAbsent(product,newInventoryItem());

returninventory.get(product);

}

publicvoidstore(Productproduct,longamount){

getItem(product).store(amount);

}

publicvoidremove(Productproduct,longamount)

throwsProductIsOutOfStock{

if(getItem(product).remove(amount)!=amount)

thrownewProductIsOutOfStock(product);

}

}

Theinventoryitemmaintainingtheclassisabitmorecomplexsincethisisthelevelwherewehandleabitofconcurrencyor,atleast,thisistheclasswherewehavetopaysomeattention:

packagepackt.java9.by.example.mybusiness.inventory;

importjava.util.concurrent.atomic.AtomicLong;

publicclassInventoryItem{

privatefinalAtomicLongamountOnStock=

newAtomicLong(0);

voidstore(longn){

amountOnStock.accumulateAndGet(n,

(stock,delta)->stock+delta);

}

longremove(longdelta){

classClosureData{

longactNr;

}

ClosureDatad=newClosureData();

amountOnStock.accumulateAndGet(delta,

(stock,n)->

stock>=n?

stock-(d.actNr=n)

:

stock-(d.actNr=0)

);

Page 709:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

returnd.actNr;

}

}

Whenweaddproductstotheinventory,wehavenolimit.Thestorageshelvesareextremelyhugeandwedonotmodelthattheyoncemaygetfullandtheinventorymaynotbeabletoaccommodatemoreitems.Whenwewanttoremoveitemsfromtherepository,however,wehavetodealwiththefactthattheremaynotbeenoughitemsfromtheproduct.Insuchacase,wedonotremoveanyitemsfromtherepository.Weservethecustomertofullsatisfactionorwedonotserveatall.

Tomaintainthenumberoftheitemsintheinventory,weuseAtomicLong.ThisclasshastheaccumulateAndGetmethod.ThismethodgetsaLongparameterandaLongBinaryOperatorthatweprovideinourcodeasalambda.ThiscodeisinvokedbytheaccumulateAndGetmethodtocalculatethenewvalueofthestock.Ifthereareenoughitems,thenweremovetherequestednumberofitems.Iftherearenotenoughitemsonstock,thenweremovezero.Themethodreturnsthenumberofitemsthatweactuallyreturn.Sincethatnumberiscalculatedinsidethelambda,ithastoescapefromthere.Todoso,weuseClosureDatadefinedinsidethemethod.

Notethat,forexample,inGroovywecouldsimplyuseaLongdvariableandalterthevariableinsidetheclosure.Groovycallslambdatoclosures,sotosay.InJavawecannotdosobecausethevariablesthatwecanaccessfrominsidethemethodshouldbeeffectivelyfinal.However,thisisnothingmorethanabitmoreexplicitnotationthatbelongstotheclosureenvironment.TheClosureDatadobjectisfinalasopposedtothefieldtheclasshas,whichcanbemodifiedinsidethelambda.

ThemostinterestingclassthatwearereallyinterestedinthischapterisInventoryKeeper.ThisclassimplementstheSubscriberinterfaceandiscapableofconsumingorderstomaintaintheinventory:

packagepackt.java9.by.example.mybusiness.inventory;

import...

publicclassInventoryKeeperimplementsFlow.Subscriber<Order>{

privatestaticfinalLoggerlog=

LoggerFactory.getLogger(InventoryKeeper.class);

privatefinalInventoryinventory;

publicInventoryKeeper(@AutowiredInventoryinventory){

this.inventory=inventory;

}

privateFlow.Subscriptionsubscription=null;

privatestaticfinallongWORKERS=3;

@Override

publicvoidonSubscribe(Flow.Subscriptionsubscription){

log.info("onSubscribewascalled");

subscription.request(WORKERS);

this.subscription=subscription;

}

TheonSubscribemethodisinvokedaftertheobjectissubscribed.Thesubscriptionispassedtotheobjectandisalsostoredinafield.Sincethesubscriberneedsthissubscriptioninsubsequentcalls,whenanitempassedinonNextisprocessedandanewitemisacceptable,afieldisagoodplacetostorethisobjectin.Inthismethod,wealsosettheinitialrequesttothreeitems.Theactualvalueissimplydemonstrative.Enterpriseenvironmentsshouldbeabletoconfiguresuchparameters:

Page 710:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privateExecutorServiceservice=

Executors.newFixedThreadPool((int)WORKERS);

ThemostimportantpartofthecodeistheonNextmethod.Whatitdoesisactuallygoesthroughalltheitemsoftheorderandremovesthenumberofitemsfromtheinventory.Ifsomeoftheitemsareoutofstock,thenitlogsanerror.Thisistheboringpart.Theinterestingpartisthatitdoesthisthroughanexecutorservice.ThisisbecausethecalltoonNextshouldbeasynchronous.ThepublishercallsonNexttodelivertheitem,butweshouldnotmakeitwaitfortheactualprocessing.Whenthepostmanbringsyourfavoritemagazine,youdon'tstartreadingitimmediatelyandmakethepostmanwaitforyoursignatureapprovingacceptance.AllyouhavetodoinonNextisfetchthenextorderandmakesurethatthiswillbeprocessedinduetime:

@Override

publicvoidonNext(Orderorder){

service.submit(()->{

intc=counter.incrementAndGet();

for(OrderItemitem:order.getItems()){

try{

inventory.remove(item.getProduct(),

item.getAmount());

}catch(ProductIsOutOfStockexception){

log.error("Productoutofstock");

}

}

subscription.request(1);

counter.decrementAndGet();

}

);

}

@Override

publicvoidonError(Throwablethrowable){

log.info("onErrorwascalledfor{}",throwable);

}

@Override

publicvoidonComplete(){

log.info("onCompletewascalled");

}

}

TheactualimplementationinthiscodeusesThreadPoolwiththreethreadsinit.Also,thenumberofrequireditemsisthree.Thisisalogicalcoincidence:eachthreadworksonasingleitem.Itdoesnotneedtobelikethat,evenifinmostcasesitis.Nothingcanstopusfrommakingmorethreadsworkingonthesameitemifthatmakessense.Theoppositeisalsotrue.Onesinglethreadmaybecreatedtoworkonmultipleitems.Thesecodeswillprobablybemorecomplexandthewholeideaofthesecomplexexecutionmodelsistomakethecodingandthelogicsimpler,movethemultithreading,coding,andimplementationissuesintotheframework,andfocusonthebusinesslogicintheapplicationcode.ButIcannottellthattheremaynotbeanexampleforasubscriberworkingmultiplethreadsonmultipleitems,intermingled.

Thelastcodewehavetolookatinthischapteristheunittestthatdrivesthecodewithsomeexamples:

publicvoidtestInventoryRemoval(){

Inventoryinventory=newInventory();

SubmissionPublisher<Order>p=

newSubmissionPublisher<>();

WecreatePublisherusingtheJDKclass,SubmissionPublisher,whichneatlyimplementsthisinterfacedeliveringmultithreadfunctionalityforuswithoutmuchhassle:

p.subscribe(newInventoryKeeper(inventory));

Page 711:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Wecreateaninventorykeeperandwesubscribetothepublisher.Thisdoesnotstartdeliveringanythingbecausetherearenopublicationsyet,butitcreatesabondbetweenthesubscriberandthepublishertelling,themthatwheneverthereisaproductsubmitted,thesubscriberwantsit.

Afterthat,wecreatetheproductsandstorethemintheinventory,20piecesaltogether,andwealsocreateanorderthatwants10productstobedelivered.Wewillexecutethisordermanytimes.Thisisabitofsimplification,butforthetest,thereisnoreasontocreateseparateorderobjectsthathavethesameproductsandthesameamountsinthelistofitems:

Productproduct=newProduct();

inventory.store(product,20);

OrderItemitem=newOrderItem();

item.setProduct(product);

item.setAmount(10);

Orderorder=newOrder();

List<OrderItem>items=newLinkedList<>();

items.add(item);

order.setItems(items);

Afterallthishasbeendone,wesubmittheordertothePublisher10times.Itmeansthatthereare10ordersforthesameproduct,eachaskingfor10pieces,thatis,100piecestogether.Thoseare100piecesagainstthewarehousewherewehaveonly20ofit.Whatweshouldexpectisthatonlythefirsttwoorderswillbefulfilledandtherestwillberejectedandthatiswhatwillactuallyhappenwhenweexecutethiscode:

for(inti=0;i<10;i++)

p.submit(order);

log.info("Allordersweresubmitted");

Afteralltheordersarepublished,wewaitforhalfasecondsothattheotherthreadshavetimetoexecuteandthenwefinish:

for(intj=0;j<10;j++){

log.info("Sleepingabit...");

Thread.sleep(50);

}

p.close();

log.info("Publisherwasclosed");

}

Notethatthisisnotaregularunittestfile.Itissometestcodetoplayaround,whichIalsorecommendforyoutoexecute,debug,andlookatthedifferentlogoutputs.

Page 712:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 713:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SummaryInthisshortchapter,wehadalookatreactiveprogramming,reactivesystems,andreactivestreams.Wediscussedthesimilaritiesandthedifferencesbetweenthesethatmayleadtoconfusions.WepaidspecialattentiontoJava9reactivestreamsthathavepracticallynothingtodowithStreamclassesandmethods.

Inthesecondhalfofthechapter,wediscussedaverysimpleexamplethatusesreactivestreams.

Afterreadingthischapter,youhavelearnedalotabouttheJavalanguageandprogramming.WedidnotdetailallthesmallbitsofJava,butthatisnotpossibleinabook.Idaresaythatthereisnoman(orwomanforthatmatter)ontheEarthorarounditonanorbitalroute,whereverhumansare,whoknowseverythingaboutJava.We,however,knowenoughbynowtostartcodinginanenterpriseenvironmentandtolearnmoreandmoreonthegotillweretire,orevenafterthat.Whatisstillleftisalittlebitofprogramming.IntheprevioussentenceIsaidcodingtomakesomedistinction.Codingisnotthesameasprogramming.Codingisatechniqueusedintheprofessionofprogramming.Duringthenext,andlast,chapterwewillseetheaspectsofprogrammingandhowitcan,andshould,bedoneinprofessionalmanner.Thisisrarelyapartofanintroductorybook,butIamhappythatwecouldagreeonthistopicwiththepublisher.Thisway,youcanfinishthebooknotonlywiththeknowledgethatyoulearnfromthisbook,butalsowithavision,lookingaheadontheroadyouwillwalkupthehillsidetothetop.Youwillknowthetopics,areas,andsubjectsthatyoucangoonlearning.

Page 714:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 715:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

FinalizingJavaKnowledgetoaProfessionalLevel

Bynow,youhavelearnedthemostimportantareasandtopicsneededforaprofessionalJavadeveloper.Whatwestillhaveaheadofusinthisbookistodiscusssometopicsthatwillleadyoufrombeingajuniordevelopertoaseniordeveloper.Readingthischapterwillnotmakeanyoneaseniordeveloper,though.Thepreviouschaptersweretheroadsthatwewalkedthrough.Thischapterisonlythemap.Ifeachofthepreviouschapterscoveredashortwalkofafewmilesinthejourneyofcodingtoreachtheharbor,thenthischapteristhenauticalmaptodiscoveranewcontinent.

Wewillbrieflybiteintosomeverydeepandhigh-levelprofessionalareas,suchascreatingaJavaagent,compile-timeannotationprocessing,polyglotprogramming,abitofarchitecturedesignandtools,andtechniquestoworkinteams.We'lldoitjustforthetaste.Now,youhaveenoughknowledgetounderstandtheimportanceofthesetopics,andgettingatastewillcreateanappetiteforthecomingyearsofself-development,or,atleast,thatismyintentiontomakeyou,thereader,addicted.

Page 716:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 717:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Javadeeptechnologies

Inthissection,wewilllistthreetechnologies:

JavaagentPolyglotprogrammingAnnotationprocessing

KnowingthemisnotamustforaJavaprofessional.Knowingaboutthemis.Javaagentsareusedmainlyindevelopmentenvironmentsandinoperation.TheyarecomplexruntimetechnologiesthatinteractwiththealreadyrunningJVM.Annotationprocessingistheotherend.AnnotationprocessorsarepluggedintotheJavacompiler.Polyglotprogrammingisinthemiddle.ItisJVMprogramming,justlikeprogramminginJava,butbyusingsomedifferentlanguageor,perhaps,somedifferentlanguageandJavatogether.Orevenmanylanguages,suchasJython,Groovy,Clojure,andJavatogether.

Wewilldiscussthesetechnologiessothatwewillgetsomeideaaboutwhattheyareandwheretolookforfurtherinformationincasewewanttolearnmoreaboutthem.

Page 718:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 719:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

JavaagentAJavaagentisaJavaprogramthatisloadedbytheJavaruntimeinaspecialwayandcanbeusedtointerferewiththebytecodeoftheloadedclasses,alteringthem.Theycanbeusedto:

Listorlog,andreporttheloadedclassesduringruntime,astheyareloadedModifytheclassessothatthemethodswillcontainextracodetoreportruntimebehaviorSupportdebuggerstoalterthecontentofaclassasthedevelopermodifiesthesourcecode

Thistechnologyisusedin,forexample,theproductsJRebelandXRebelfromhttps://zeroturnaround.com/.

AlthoughJavaagentsworkinthedeepdetailsofJava,theyarenotmagic.TheyareabitcomplexandyouneedadeepunderstandingofJava,butanyonewhocanprograminJavacanwriteaJavaagent.Allthatisrequiredisthattheclass,whichistheagent,hassomepredefinedmethodspackagedintoaJARfilealongwiththeotherclassesoftheagentandhasaMETA-INF/MANIFEST.MFfilethatdefinesthenamesoftheclassesimplementingthepremainand/oragentmainmethods,andsomeotherfields.

ThedetailedandprecisereferencedocumentationispartoftheJDKJavaDocavailableathttp://download.java.net/java/jdk9/docs/api/inthedocumentationofthejava.lang.instrumentpackage.

WhenaJavaapplicationisstartedwithaJavaagent,thecommandlinehastocontainthefollowingoption:

-javaagent:jarpath[=options]

Here,jarpathpointstotheJARfilethatcontainstheagentclassandthemanifestfile.Theclassmusthaveamethodnamedpremainoragentmain.Itmayhaveoneortwoarguments.TheJVMtriestocallthetwo-argumentversionfirstaftertheJVMisinitialized:

publicstaticvoidpremain(StringagentArgs,Instrumentationinst);

Ifatwo-argumentversiondoesnotexist,thentheone-argumentversionisused,whichisessentiallythesameasthetwo-argumentversionbutmissestheinstrumentationargument,which,inmyopinion,doesnotmaketoomuchsensesinceaJavaagentcannotdomuchwithouttheInstrumentationobject:

publicstaticvoidpremain(StringagentArgs);

TheagentArgsparameteristhestringpassedasanoptiononthecommandline.Thesecondargument,Instrumentation,providesmethodstoregisterclasstransformersthatcanmodifyclassbytecodesandalsomethodsthatcanasktheJVMtoperformredefinitionorretransformationofclassesduringruntime.

Javaapplicationscanalsoloadanagentaftertheprogramhasalreadystarted.Insuchacase,theagentcannotbeinvokedbeforethemainmethodoftheJavaapplication,sinceithasalreadystartedbythattime.Toseparatethetwocases,JVMcallsagentmaininsuchascenario.Notethateitherpremainoragentmainisinvokedforanagentandneverboth.Asingleagentcanimplementbothsothatitiscapableofperformingitstaskloadedatthestartup,specifiedonthecommandlineoraftertheJVMstarted.

Page 720:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Ifagentmainisused,ithasthesameargumentsaspremain.

Thereisonemajorandimportantdifferencebetweentheinvocationofpremainandagentmain.Ifanagentcannotbeloadedduringstartup,forexample,ifitcannotbefound,iftheJARfiledoesnotexist,iftheclassdoesnothavethepremainmethod,orifitthrowsanexception,theJVMwillabort.IftheagentisloadedaftertheJVMisstarted(inthiscase,agentmainistobeused),theJVMwillnotabortifthereissomeerrorintheagent.

Thisapproachisfairlyreasonable.ImaginethatthereisaserverapplicationthatrunsontheTomcatservletcontainer.Whenanewversionisstarted,thesystemisdownforamaintenanceperiod.Ifthenewversioncannotbestartedbecausetheagentisnotbehavingwell,thenitisbetternotstarted.Thedamagetodebugthesituationandfixit,orrollbacktheapplicationtotheoldversionandcallforalongerfixingsessionmaybelessthanstartinguptheapplicationandnothavingtheproperagentfunctionality.Iftheapplicationstartsuponlywithouttheagent,thenthesuboptimaloperationmaynotimmediatelyberecognized.Ontheotherhand,whenanagentisattachedlater,theapplicationisalreadyrunning.Anagentisattachedtoanalreadyrunningapplicationtogetinformationfromanalreadyrunninginstance.Tostopthealreadyrunninginstanceandfailit,especiallyinanoperationalenvironment,ismoredamagingthanjustnotattachingtheagent.Itmaynotgounnoticedanywaybecausetheagentthatismostprobablyattachedisusedbyoperationalpersonnel.

ApremainoragentmainagentgetsanInstrumentationobjectasthesecondargument.Thisobjectimplementsseveralmethods.Oneofthemis:

voidaddTransformer(ClassFileTransformertransformer)

Theagentimplementsthetransformer,andithasthetransformmethodsignature:

byte[]transform(Modulemodule,ClassLoaderloader,

StringclassName,

Class<?>classBeingRedefined,

ProtectionDomainprotectionDomain,

byte[]classfileBuffer)

throwsIllegalClassFormatException

ThismethodiscalledbytheJVMwhenaclassisloadedorwhenitistobetransformed.Themethodgetstheclassobjectitself,but,moreimportantly,itgetsthebytearraycontainingthebytecodeoftheclass.Themethodisexpectedtoreturnthebytecodeofthetransformedclass.Modifyingthebytecodeneedssomeknowledgeofhowthebytecodeisbuiltandwhatthestructureofaclassfileis.Therearelibrariesthathelptodothat,suchasJavassist(http://www.javassist.org/)orASM(http://asm.ow2.org/).Nevertheless,Iwillnotstartcodingbeforegettingacquaintedwiththestructureofthebytecode.

Agents,runninginaseparatethreadandpresumablyinteractingwiththeuserorthefilesystemandbaseduponsomeexternalobservationatanytime,maycallthefollowingmethodtoperformtheretransformationoftheclassesusingtheregisteredtransformers:

voidretransformClasses(Class<?>...classes)

Page 721:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Theagentcanalsocallthefollowingmethod,whichwillredefinetheclassesgivenasarguments:

voidredefineClasses(ClassDefinition...definitions)

TheClassDefinitionclassissimplyaClassandabyte[]pair.ThiswillredefinetheclassesthroughtheclassmaintainingmechanismoftheJVM.

NotethatthesemethodsandJavaagentsinteractwiththedeep,low-levelpartoftheJVM.ThisalsobearstheconsequencethatitisveryeasytodestroythewholeJVM.Thebytecodeisnotchecked,unlikeduringtheloadingoftheclass,andthus,ifthereissomeerrorinit,theconsequencemaynotonlybeanexceptionbutalsothecrashingoftheJVM.Also,theredefinitionandthetransformationsshouldnotalterthestructureoftheclasses.Theyshouldnotchangetheirinheritancefootprint,add,rename,orremovemethods,orchangethesignatureofthemethods,andthisisalsotrueforfields.

Alsonotethatthealreadycreatedobjectswillnotbeaffectedbythechanges;theywillstillusetheolddefinitionoftheclassandonlynewinstanceswillbeaffected.

Page 722:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 723:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PolyglotprogrammingPolyglotprogrammingisthetechniquewhentherearedifferentprogramminglanguagesusedinthesameapplication.Suchanapproachisnotonlyappropriatewhenadifferentpartoftheapplicationrunsonadifferentenvironment.Forexample,theclientexecutesinthebrowserusingJavaScript,CSS,andHTMLwhiletheserverisprogrammedtoruninaTomcatenvironmentinJava.Thisisadifferentstory,and,usually,thisisnotthetypicalusewhensomeoneisspeakingaboutpolyglotprogramming.

WhentheapplicationthatrunsontheserverpartiallyrunsinJavaandalsoinsomeotherlanguage,thenwecanspeakaboutpolyglotprogramming.Forexample,wecreatetheorderhandlingapplicationinJavaandsomeofthecodethatchecksthecorrectnessoftheorderbasedontheproduct-specificcodesthattheordercontainsiswritteninJavaScript.Doesitringabell?WehavealreadydonethatinthisbooktodemonstratethescriptingAPIoftheJDK.Thatwasrealpolyglotprogramingevenifwedidnotmentionitthatway.

TheJVMthatrunsthecompiledJavacodeisaverygoodtargetfordifferentlanguagecompilers,andthus,therearemanylanguagesthatcompileforit.WhentheJVMrunsthebytecodeofaclass,itdoesnotknowwhatthesourcelanguagewas,anditdoesnotreallycare;somecompilercreatedthebytecodeanditjustexecutesthat.

Wecanusedifferentlanguages,suchasJython,Groovy,andScala,tonameafewpopularonesthatcompilefortheJVM.Wecanwriteoneclassusingonelanguageandtheotheroneusinganother.WhentheyareputtogetherintoaJAR,WAR,oranEARfile,theruntimesystemwilljustrunthem.

Whendoweusepolyglotprogramming?

Page 724:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 725:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PolyglotconfigurationUsually,weturntowardspolyglotprogrammingwhenwewanttocreateanapplicationthatismoreflexibleandmoreconfigurable.Applicationsthatgetinstalledinmanyinstances,usually,atdifferentcustomersiteshavesomeconfigurations.TheseconfigurationscanbeXMLfiles,propertiesfiles,andINIfiles(thosecomefromWindows).Astheprogramsdevelopsoonerorlater,thesestaticconfigurationpossibilitiesreachtheirlimits.Applicationdeveloperssoonseethattheyneedtoconfiguresomefunctionalitythatiscumbersometodescribeusingthesetechnologies.Configurationfilesstartbeinglargerand,also,thecodethatreadsandinterpretstheconfigurationfilesgrowlarge.Gooddevelopershavetorealizethatthisisthesituation,andbeforetheconfigurationfilesandthecodehandlingthembecomeunmanageable,somescriptingconfiguration,polyglotprogramminghastobeimplemented.

Decentdeveloperteamsmayreachapointwhentheydeveloptheirconfigurationlanguageandtheinterpreterofthatlanguage.ItcanbebasedonXML,oritcanjustbeanyotherlanguage.Afterall,writingalanguageisfun;Ihavedoneitafewtimesmyself.Mostofthesewere,however,hobbiesandnotprofessionalprojects.Usually,thereisnocustomervalueincraftinganotherlanguage.Wecanbetteruseanexistingone.

Inthecaseofconfiguration,Groovyisaveryhandylanguagethatsupportscomplexclosureandmeta-classsyntaxandimplementation.Thisway,thelanguageisextremelysuitabletocreateadomain-specificlanguage.SinceGroovyiscompiledtoJVM,GroovyclassescanbeinvokeddirectlyfromJava,andintheotherwayround,readingtheconfigurationisessentiallyinvokingtheclasscompiledfromtheconfigurationfile.Thecompilationcanbeduringapplicationbuildtime,butinthecaseofconfiguration,itmakesmoresensetodoitduringapplicationstartup.WehavealreadyseenthattheGroovyimplementationofthescriptingAPIorthespecialAPIthatGroovyprovidesisabsolutelycapableofdoingthat.

Haveweseenexamplesofthisinourbook?Itmaybeasurprisetoyou,butwehaveinfactusedGroovytodescribesomeconfigurationmanytimes.GradlebuildfilesarenothingmorethanGroovyDSLdevelopedmainlyinGroovytosupportprojectbuildconfiguration.

Page 726:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 727:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

PolyglotscriptingConfigurationisnottheonlyapplicationofpolyglotprogramming.Configurationisexecutedattheprogramstartupandtheconfigurationdataisusedasstaticdataafterwards.Wecanexecutescriptsduringtheapplication'sexecutionanytimeandnotonlyduringitsstartup.Thiscanbeusedtoprovideextrafunctionalitytotheprogram'suserwithinstallationsthatusethesameapplicationbutarefurnishedwithdifferentscripts.

Oneofthefirstapplicationsthatprovidedsuchscriptingcapabilitywastheemacseditor.ThecoreoftheapplicationwaswritteninClanguageanditcontainedaLispinterpreterthatlettheusertowritescripts,whichwereexecutedintheeditorenvironment.Theengineeringprogram,AutoCAD,alsousedaLispinterpreterforsimilarpurposes.WhywasLispusedforthispurpose?Lisphasverysimplesyntax,andtherefore,itiseasytoparseLispcode.Atthesametime,thelanguageispowerful,andlastbutnotleast,therewereopensourceLispinterpreters(atleastone)availablebythetime.

Togetthiskindofflexibility,applications,manytimes,providepluginAPIs,whichadevelopercanusetoextendtheapplication.This,however,requiresthatthedevelopersetsupcodingtools,includingIDE,buildtool,continuousintegration,andsoon,thatis,aprofessionalprogrammingenvironment.Whenthetasktobesolvedbythepluginissimple,theoverheadissimplytoolarge.Insuchacase,ascriptingsolutionishandier.

Scriptingisnotasolutionforeverything.Whenthescriptsextendingtheapplicationtendtobecometoocomplex,itmeansthatthescriptingpossibilityisjusttoomuch.Itisdifficult,however,totakebackatoyfromachild.Ifusersgetusedtothescriptingpossibility,thentheywillnottakeiteasyifthenextversionoftheapplicationwereleasedoesnotprovidethatpossibility.Thus,itisextremelyimportanttoassessthepossibleuseofthescriptingcapabilityinourapplication.Scriptingand,moregenerally,anyfeatureofourprogramwillnotbeusedforwhatweintendedthemfor.Theywillbeusedforwhateveritispossibletousethemfor.Userscangobeyondallimaginationwhenitcomestoabusingsomefeature.Itmaybeagoodideatothinkaboutlimitingthescriptingpossibilitybeforehand,limitingtherunningtimeofthescriptsorthesizeofthescriptourprogramagreestoworkwith.Iftheselimitationsaresetreasonably,andtheusersunderstandandacceptthese,apluginstructureinadditiontothescriptingcapabilityhastobeconsidered.

Thesecurityofanapplication,includingpluginorscriptingextension,isalsoveryimportant.ThescriptsorpluginsrunonthesameJVMasthecoreapplication.Somescriptinglanguagesprovidesomefencearoundthescriptsthatlimitstheaccesstothecoreapplication'sobjectsandclasses,butthisisanexception.Usually,scriptsrunwiththesameprivilegeasthecoreapplicationandthatwaytheycandojustanything.Thus,scriptsshouldbetrustedthesamewayasthecoreapplication.Scriptinstallationormodificationshouldneverbepossibleforanunprivilegeduseroftheapplication.Suchanactionisalmostalwaysreservedforthesystemadministrator.

Ifanunprivilegedusercanuploadascripttotheserverandthenhaveitexecuted,wejustopenedasecurityholeinourapplication.Sinceaccessrestrictionsareenforcedbytheapplication,itiseasyto

Page 728:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

overridetheselimitationsusinganuncontrolledscript.Thehackercanjustaccessotherusers'dataeasily,whichheisnotentitledto,andreadandmodifyourdatabase.

Page 729:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 730:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

BusinessDSLPolyglotprogrammingmayalsocomeintothepicturewhentheapplication'scodecanbeseparatedintobusinesscodeandtechnologycode.Thebusinesscodecontainsthetop-levelbusinesslogicthatweactuallywritetheapplicationfor,andthisisthecodethatcontainsthelogicthatthecustomerpaysfor.ThetechnologycodeistosupportthealgorithmscodedinthebusinessDSL.

Mostoftheenterpriseapplicationscontainthesetwotypesofcodebutmanydonotseparatethem.Thisleadstoamonolithicapplicationthatcontainsrepetitivecode.Whenyoufeelthatyouarewritingthesametypeofcodewhenyouneedpersistenceornetworking,andagainthesametypeofcodewhilecodingsomebusinessrules,thenthisisthecodesmellthatsuggeststhatthetwocodetypesarenotseparated.DSLandscriptingarenotamagicwandanddonotsolvealltheproblemsthatstemfromawrongapplicationstructure.Insuchasituation,thecodehastoberefactoredfirsttoseparatethebusinesslogicandtheinfrastructurecode,anditisonlythesecondsteptoimplementaDSLandabusinessAPIsupportingitandtorewritethebusinesscodeintotheDSL.EverystepofsuchaprojectdeliversvaluefortheapplicationandevenifitnevergetstoDSLandscripting,theeffortinvestedisnotwasted.

ThebusinessDSLscriptingisverysimilartopluggablescripts,exceptthatthistimeitisnottheapplicationthatcallsthescriptsfromtimetotimetoexecutesomespecialextensionfunctionality.Instead,theDSLcodecallstheapplicationthroughthebusinessAPIthatitprovides.TheadvantageofprovidingtheAPIandusingaDSListhatthecodethatimplementsthebusinesslogicgetsridofthetechnicaldetails,canbeveryabstract,and,thisway,bemuchclosertoabusiness-leveldescriptionoftheproblemratherthanjustprogramcode.EvensomebusinesspersoncanunderstandabusinessDSL,andthoughitisnotagoalinreal-lifeexamples,theycouldevenwritecode.

AtTUVienna,wealsousedasimilarapproachtomakesemiconductorsimulationmoreusableforthesemiconductordesignengineer.ThecorecalculatingcodewaswritteninFortran.AClanguageframeworkthathandledthemassivesimulationdatainputandoutputandthatembeddedtheXLISPinterpreterexecutedtheseprograms.TheLispcodecontainedthesimulationconfigurationdataandcouldalsocontainsimpleloopswhenthesimulationwastobeexecutedformanyconfigurationpoints.Itwaspolyglotprogramming,exceptthatwedidnotknowthatthisisgoingtobethenameyearsafterthisapplicationcodingstyle.

Page 731:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 732:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ProblemswithpolyglotPolyglotprogrammingisnotonlyallaboutadvantages.Beforejumpingintothisdirection,developersmakingthedecisionhavetoconsideralotofthings.

Usinganotherlanguagefortheapplicationneedsknowledge.FindingpeoplewhocancodeinthelanguagesthatareusediseventuallymoredifficultthanfindingdeveloperswhoonlyknowJava.(ThisisalsotrueifthekernelapplicationlanguageisnotJava.)Differentlanguagesrequiredifferentmindsetsand,manytimes,differentpeople.Theteamshouldalsohavesomememberswhoareproficientinbothlanguages,anditisalsoanadvantageifmostofthepeopleknowatleastabitabouttheotherlanguage.

ThetoolsetsupportingJavaisoutstanding.Thebuildtools,integrateddevelopmentenvironment,libraries,debuggingpossibilities,andloggingframeworks,tonameafew,areallextremelygoodcomparedwithotherlanguages.Polyglotdevelopmentneedssupportfortheotherlanguageaswell,whichmaynotbeasadvancedasthesupportforJava.Manytimes,itisreallyanissuetodebugDSLsolutionsandIDEsupportmayalsobelagging.

WhenweprograminJava,manytimes,wetakeforgrantedthattheIDEreadsthemeta-dataofthelibrariesandwheneverweneedtocallamethod,orreferenceaclass,theIDEsuggeststhebestpossibility.XMLandpropertiesfilesmayalsobesupportedandtheIDEmayknowsomeofthemostusedframeworks,suchasSpring,andunderstandtheXMLconfigurationhandlingthenamesoftheclassesashyperlinks,evenwhentheclassnamesareinsidesomeattributestrings.

Thisisfarfrombeingthiseasyinthecaseofotherlanguages.Forthelanguagesthathaveawideuserbase,thetoolingsupportmaybegood,butifyoupicksomeexoticlanguage,youareonyourown.Themoreexoticthelanguagethelesssupportyoumayhave.

YoucancreatesometooltosupportyourDSLthatyoudevelop.Itisnothardtodosousingtoolssuchashttp://www.eclipse.org/Xtext/.Insuchacase,youaretiedtoEclipse,whichmayormaynotbeaproblem.Youcanpickaspeciallanguage,forexample,Kotlin,whichisextensivelysupportedbyIntelliJ,becausethesamecompanysupportsthelanguageandtheIDE,butagain,youbuyintoaspecialtechnologythatcanbeexpensivetoreplaceincaseyouhaveto.Itisgenerallytruenotonlyforlanguagesbutalsoforanytechnologyyouincludeintoyourdevelopment.Whenyouselectone,youshouldconsiderthesupportandthecostofgettingoffthehorseiforwhenitstartsdying.

Page 733:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 734:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

AnnotationprocessingWehavealreadydiscussedannotationsingreatdetail.Youmayrecallthatwedefinedourannotationinterfacesusingthefollowingannotation:

@Retention(RetentionPolicy.RUNTIME)

ThistoldtheJavacompilertokeeptheannotationandputitintotheJVMcodesothatthecodecanaccessitduringruntimeusingreflection.ThedefaultvalueisRetentionPolicy.CLASS,whichmeansthattheannotationgetsintothebytecode,buttheJVMdoesnotmakeitavailablefortheruntimesystem.IfweuseRetentionPolicy.SOURCE,theannotationdoesnotevengetintotheclassfile.Inthiscase,thereisonlyonepossibilitytodoanythingwiththeannotation:compiletime.

Howcanwewritecodethatrunsduringcompiletime?Javasupportsthenotionofannotationprocessors.Ifthereisaclassontheclasspathofthecompilerthatimplementsthejavax.annotation.processing.Processorinterface,thenthecompilerwillinvoketheimplementedmethodsoneormoretimes,passinginformationaboutthesourcefilethatthecompilerisactuallyprocessing.Themethodswillbeabletoaccessthecompiledmethods,classes,orwhateverisannotated,andalsotheannotationthattriggeredtheprocessorinvocation.Itisimportant,however,thatthisaccessisnotthesameasinruntime.Whattheannotationprocessoraccessesisneitheracompilednoraloadedclass,thatis,itisavailablewhenthecodeusesreflection.Thesourcefileatthistimeisundercompilation;thus,thedatastructuresthatdescribethecodeareactuallystructuresofthecompiler,aswewillseeinournextexample.

Theannotationprocessoriscalledoneormoretimes.Thereasonitisinvokedmanytimesisthatthecompilermakesitpossiblefortheannotationprocessorstogeneratesourcecodebasedonwhatitseesinthepartiallycompiledsourcecode.IftheannotationprocessorgeneratesanyJavasourcefile,thecompilerhastocompilethenewsourcecodeandperhapscompilesomeofthealreadycompiledfilesagain.Thisnewcompilationphaseneedsannotationprocessorsupportuntiltherearenomoreroundstoexecute.

Annotationprocessorsareexecutedoneaftertheother,andtheyworkonthesamesetofsourcefiles.Thereisnowaytospecifytheorderoftheannotationprocessorexecutions;thus,twoprocessorsworkingtogethershouldperformtheirtasks,nomatterinwhatordertheyareinvoked.Also,notethatthesecodesruninsidethecompiler.Ifanannotationprocessorthrowsanexception,thenthecompilationprocesswillmostprobablyfail.Thus,throwinganexceptionoutoftheannotationprocessorshouldonlybedoneifthereisanerrorthatcannotberecoveredandtheannotationprocessordecidesthatthecompilationafterthaterrorcannotbecomplete.

Whenthecompilergetstothephasetoexecutetheannotationprocessors,itlooksattheclassesthatimplementthejavax.annotation.processing.Processorinterfaceandcreatesinstancesoftheseclasses.Theseclasseshavetohaveapublicno-argumentconstructor.Tostreamlinetheexecutionoftheprocessorsandtoinvokeaprocessoronlyfortheannotationsthatitcanhandle,theinterfacecontainstwomethods:

getSupportedSourceVersiontoreturnthelatestversiontheannotationprocessorcansupportgetSupportedAnnotationTypestoreturnasetofStringobjectscontainingthefullyqualifiedclassnameof

Page 735:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

theannotationsthatthisprocessorcanhandle

IfanannotationprocessorwascreatedforJava1.8,itmayworkwithJava9,butitmayalsonotwork.Ifitdeclaresthatthelatestsupportedversionis1.8,thenthecompilerinaJava9environmentwillnotinvokeit.Itisbetternottoinvokeanannotationprocessorthancallingitandmessingupthecompilationprocess,whichmayevencreatecompiledbuterroneouscode.

Thevaluesreturnedbythesemethodsarefairlyconstantforanannotationprocessor.Anannotationprocessorwillreturnthesamesourceversionitcanhandleandwillreturnthesamesetofannotations.Therefore,itwouldbeclevertohavesomewaytodefinethesevaluesinthesourcecodeinadeclarativemanner.

Itcanbedonewhenweextendthejavax.annotation.processing.AbstractProcessorclassinsteadofdirectlyimplementingtheProcessorinterface.Thisabstractclassimplementsthesemethods.Bothofthemgettheinformationfromtheannotationsothatwecandecoratetheclassthatextendstheabstractclass.Forexample,thegetSupportedAnnotationTypesmethodlooksattheSupportedAnnotationTypesannotationandreturnsanarrayofannotationtypestringsthatarelistedintheannotation.

Now,thisisabitbraintwistingandcanalsobeconfusingatfirst.Weareexecutingourannotationprocessorduringcompiletime.ButthecompileritselfisaJavaapplication,andinthisway,thetimeisruntimeforthecodethatrunsinsidethecompiler.ThecodeofAbstractProcessoraccessestheSupportedAnnotationTypesannotationasaruntimeannotationusingreflectionmethods.Thereisnomagicinit.ThemethodintheJDK9isasfollows:

publicSet<String>getSupportedAnnotationTypes(){

SupportedAnnotationTypessat=this.getClass().getAnnotation

(SupportedAnnotationTypes.class);

if(sat==null){

...errormessageissenttocompileroutput...

returnCollections.emptySet();

}

else

returnarrayToSet(sat.value());

}

(Thecodehasbeeneditedforbrevity.)

Tohaveanexample,wewillsortoflookatthecodeofapolyglotannotationprocessor.Ourverysimpleannotationprocessorwillprocessonesimpleannotation:com.javax0.scriapt.CompileScript,whichcanspecifyascriptfile.TheannotationprocessorwillloadthescriptfileandexecuteitusingthescriptinginterfaceofJava9.

ThiscodewasdevelopedasademonstrationcodebytheauthorofthisbookafewyearsagoandisavailablewiththeApachelicensefromGitHub.Thus,thepackageoftheclassesisretained.

Theannotationprocessorcontainstwocodefiles.Oneoftheannotationitselfthattheprocessorwillworkon:

@Retention(RetentionPolicy.SOURCE)

@Target(ElementType.TYPE)

public@interfaceCompileScript{

Page 736:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Stringvalue();

Stringengine()default"";

}

Asyoucansee,thisannotationwillnotgetintotheclassfileaftercompilation;thus,therewillbenotraceduringruntimesothatanyclasssourcemayoccasionallyusethisannotation.TargetoftheannotationisElementType.TYPE,meaningthatthisannotationcanonlybeappliedtothoseJava9languageconstructsthataresomekindoftypes:class,interface,andenum.

Theannotationhastwoparameters.Thevalueshouldspecifythenameofthescriptfile,andtheenginemayoptionallydefinethetypeofthescriptthatisinthatfile.Theimplementationwe'llcreatewilltrytoidentifythetypeofthescriptfromthefilenameextension,butifsomebodywouldliketoburysomeGroovycodeintoafilethathasthe.jyextension(whichisusuallyforJython),sobeit.

TheprocessorextendsAbstractProcessorand,inthisway,someofthemethodsareinheritedattheexpenseofsomeannotationsusedintheclass:

packagecom.javax0.scriapt;

import...

@SupportedAnnotationTypes("com.javax0.scriapt.CompileScript")

@SupportedSourceVersion(SourceVersion.RELEASE_9)

publicclassProcessorextendsAbstractProcessor{

ThereisnoneedtoimplementthegetSupportedAnnotationTypesandgetSupportedSourceVersionmethods.Thesearereplacedbytheuseoftheannotationsontheclass.Wesupportonlyoneannotationinthisprocessor,theonethatwedefinedinthepreviouslylistedsourcefile,andwearepreparedtomanagethesourcecodeuptoJavaversion9.Theonlymethodwehavetooverrideisprocess:

@Override

publicbooleanprocess(

finalSet<?extendsTypeElement>annotations,

finalRoundEnvironmentroundEnv){

for(finalElementrootElement:

roundEnv.getRootElements()){

try{

processClass(rootElement);

}

catch(Exceptione){

thrownewRuntimeException(e);

}

}

returnfalse;

}

Thismethodgetstwoarguments.Thefirstisthesetofannotationsthatitwasinvokedfor.Thesecondistheroundenvironment.Becausetheprocessorcanbeinvokedmanytimes,thedifferentinvocationsmayhavedifferentenvironments.EachinvocationisinaroundandtheRoundEnvironmentargumentisanobjectthatcanbeusedtogetinformationaboutthegivenround.Itcanbeusedtogettherootelementsoftheroundforwhichthisannotationisinvoked.Inourcase,thiswillbeasetofclasselementsthathavetheCompileScriptannotation.Weiterateoverthisset,andforeachclass,weinvoketheprocessClassmethod(seethenextcodesnippet).Themethodmaythrowsomecheckedexceptionandthemethodprocesscannotbecauseitshouldmatchthesamemethodoftheinterface.Thus,wecatchanyexceptionthatmaybethrownandwere-throwtheseencapsulatedinRunTimeException.Ifanyoftheseexceptionsarethrownbythecalledmethod,thenthecompilationcouldnotrunthescriptsanditshouldbetreatedasfailed.Thecompilationshouldnotsucceedinsuchacase:

Page 737:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

privatevoidprocessClass(finalElementelement)

throwsScriptException,FileNotFoundException{

for(finalAnnotationMirrorannotationMirror:

element.getAnnotationMirrors()){

processAnnotation(annotationMirror);

}

}

Theactualannotationisnotavailableduringcompiletimeaswealreadymentioned.Hence,whatwehaveavailableisonlyacompiletimemirrorimageoftheannotation.IthastheAnnotationMirrortype,whichcanbeusedtogettheactualtypeoftheannotationand,also,thevaluesoftheannotation.Thetypeoftheannotationisavailableduringcompiletime.Thecompilerneedsit;otherwise,itcouldnotcompiletheannotation.Thevaluesareavailablefromtheannotationitself.OurprocessAnnotationmethodhandleseachannotationitgetsasanargument:

privatevoidprocessAnnotation(

finalAnnotationMirrorannotationMirror)

throwsScriptException,FileNotFoundException{

finalStringscript=

FromThe.annotation(annotationMirror).

getStringValue();

finalStringengine=

FromThe.annotation(annotationMirror).

getStringValue("engine");

execute(script,engine);

}

Our@CompileScriptannotationdefinestwoparameters.Thefirstvalueisthescriptfilenameandthesecondoneisthescriptingenginename.Ifthesecondoneisnotspecified,thenanemptystringissetasthedefaultvalue.Theexecutemethodiscalledforeachandeveryoccasionoftheannotation:

privatevoidexecute(finalStringscriptFileName,

finalStringengineName)

throwsScriptException,FileNotFoundException{

finalScriptEngineManagerfactory=

newScriptEngineManager();

finalScriptEngineengine;

if(engineName!=null&&engineName.length()>0){

engine=factory.getEngineByName(engineName);

}

else{

engine=

factory.getEngineByExtension

(getExtensionFrom(scriptFileName));

}

ReaderscriptFileReader=newFileReader

(newFile(scriptFileName));

engine.eval(scriptFileReader);

}

Themethodtriestoloadthescript,basedonthefilename,andtriestoinstantiatethescriptengine,basedonthegivenname.Ifthereisnonamegiven,thenthefilenameextensionisusedtoidentifythescriptingengine.Bydefault,theJavaScriptengineisontheclasspathasitispartoftheJDK.IfanyotherJVM-basedscriptingengineisinuse,thenithastobemadeavailableontheclasspathoronthemodulepath.

Thelastmethodoftheclassisasimplescriptmanipulationmethod,nothingspecial.Itjustchopsoffthefilenameextensionsothattheenginecanbeidentifiedbasedontheextensionstring:

privateStringgetExtensionFrom(finalStringscriptFileName){

finalintindexOfExtension=scriptFileName.lastIndexOf('.');

if(indexOfExtension==-1){

return"";

}

else{

Page 738:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

returnscriptFileName.substring(indexOfExtension+1);

}

}

Andjustforthesakeofcompleteness,wehavetheclosingbraceoftheclass:

}

Page 739:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 740:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ProgrammingintheenterpriseWhenaprofessionalworksforanenterprise,shedoesnotworkalone.Therearealotofpeople,developersaswellasothercoworkers,wehavetocooperatewith.TheoldertheITdepartmentoftheenterpriseis,andthelargertheenterpriseis,themorespecializedrolespeoplearein.Youwillcertainlymeetbusinessanalysts,projectmanagers,testengineers,buildengineers,subject-matterexperts,testers,architects,scrummasters,andautomationengineers,tonameafewroles.Someoftheserolesmayoverlap,nopersonmayhavemorethanoneresponsibility,andwhileinothercases,somerolescouldevenbemorespecialized.Someoftherolesareverytechnicalandrequirelessbusiness-relatedknowledge;othersaremorebusinessoriented.

Workingtogetherasateamwithsomanypeopleandwithsomanydifferentrolesisnotsimple.Thecomplexityofthetaskmaybeoverwhelmingforanovicedeveloperandcannotbedonewithoutdefinitepoliciesthatallmembersoftheoperationfollow,moreorless.Perhapsyourexperiencewillshowthatitismoretimeslessthanmore,butthatisadifferentstory.

Forthewaydevelopersworktogether,therearewell-establishedindustrypractices.ThesesupporttheSoftwareDevelopmentLifecycle(SDLC)usingwaterfall,agile,oramixofthetwomodelsinsomeway.Inthefollowingsections,wewilllookattoolsandtechniquesthatare,oratleastshouldhavebeen,usedineverysoftwaredevelopmentorganization.Theseare:

StaticcodeanalysistoolsthatcontrolthequalityofthecodeexaminingthesourcecodeSourcecodeversioncontrolthatstoresalltheversionsofthesourcecodeandhelpgetthesourcecodeforanyoldversionofthedevelopmentSoftwareversioningtokeepsomeorderofhowweidentifythedifferentversionsanddonotgetlostamongthedifferentversionsCodereviewandtoolsthathelpinpin-pointingbugsthatarenotrevealedbytestsandaidknowledgesharingKnowledgebasetoolstorecordanddocumentthefindingsIssuetrackingtoolsthatrecordbugs,customerissues,andothertasksthatsomebodyhastoattendtoSelectionprocessandconsiderationsforexternalproductsandlibrariesContinuousintegrationthatkeepsthesoftwareinaconsistentstateandreportsimmediatelyifthereissomeerrorinitbeforetheerrorpropagatestootherversionsorothercode,dependingonhowtheerroneouscodegetsdevelopedReleasemanagement,whichkeepstrackofthedifferentreleaseversionsofthesoftwareCoderepository,whichstoresthecompiledandpackedartifacts

Thefollowingdiagramshowsthemostwidelyusedtoolsforthesetasks:

Page 741:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 742:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 743:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

StaticcodeanalysisStaticcodeanalysistoolsreadthecodejustlikethecompilerandanalyzeit,butinsteadofcompilation,theytrytofinderrorsormistakesinit.Notthesyntaxerrors.Forthat,wealreadyhavetheJavacompiler.Mistakes,suchasusingaloopvariableoutsidealoop,whichmaybeabsolutelyvalidbutisusuallybadstyleand,manytimes,suchusagecomesfromsomesimplemistakes.Theyalsocheckthatthecodefollowsthestylingrulesthatweset.

Staticcodeanalyzershelpidentifymanysmallandobviouserrorsinthecode.Sometimes,theyareannoying,warningaboutsomethingthatmaynotbereallyaproblem.Insuchacase,itisbettertocodetheprogramabitdifferently,notbecausewewantthestaticcodeanalysistorunwithoutwarning.Weshouldnevermodifythecodebecauseofatool.Ifwecodesomethinginsuchawaythatitpassessomequalitychecktoolandnotbecauseitisbetterthatway,thenweareservingthetoolsinsteadofthetoolsservingus.

Thereasontochangethecodetopassthecodeanalysisisthatitisveryprobablethatthecodeismorereadabletoanaverageprogrammerifitdoesnotviolatethecodingstyle.Youortheotherteammemberscanbeexcellentprogrammerswhounderstandthecodeveryeasilyevenifitusessomespecialconstruct.However,youcannotsaythataboutalltheprogrammerswhowillmaintainyourcodeinthefuture.Thecodelivesalonglife.Iworkwithsomeprogramsthathavebeenwritten50yearsago.Theyarestillrunningandmaintainedbyyoungprofessionalsaroundtheageof30.Itmeansthattheywerenotevenbornwhenthecodewasdeveloped.Itcaneasilyhappenthatthepersonmaintainingyourcodeisnotevenbornbythetimeyouwritethecode.Youcannottellanythingabouttheirclevernessandcodingpractices.Thebestwecandoistopreparefortheaverageandthatisexactlywhatstaticcodeanalysistoolsaresetfor.

Thechecksthatthesetoolsperformarenothardwiredintothetools.Somespeciallanguageinsidethetoolsdescribestherulesandtheycanbedeleted,otherrulescanbeadded,andrulescanbemodified.Thisway,youcanaccommodatethecodingstandardsoftheenterpriseyouworkfor.Thedifferentrulescanbecategorizedascosmetic,minor,major,andcritical.Cosmeticthingsaremainlywarningsandwedonotreallycareaboutthem,eventhoughitisnicetofixeventheseissues.Sometimes,thesesmallthingsmaysignalsomereallybigissue.Wecansetlimitsforthenumberofminorandmajorbugsbeforethecheckisdeclaredasfailingandalsoforthecriticalerrors.Inthelastcase,thislimitisusuallyzero.Ifacodingerrorseemstobecritical,thenbetternothaveanyinthecode.

ThemostfrequentlyusedtoolsareCheckstyle,FindBugs,andPMD.Theexecutionofthesetoolsisusuallyautomated,andthoughtheycanbeexecutedfromtheIDEorfromthedeveloper'scommandline,theirmainuseisonthecontinuousintegration(CI)server.Duringthebuild,thesetoolsareconfiguredontheCIservertorun,anditcanbeconfiguredsuchthatthebuildshouldbebrokenifthestaticcodeanalysisfailswithsomelimit.Executingthestaticcodeanalysisisusuallythenextstepaftercompilationandunittestexecution,andbeforetheactualpackaging.

TheSonarQubetool(https://www.sonarqube.org/)isaspecialtoolinadditiontobeingastaticcodeanalysistool.SonarQubemaintainsthehistoryofthepreviouschecksaswellassupportsunittestcodecoverageandcanreportthechangeofthequalityovertime.Thisway,youcanseehowthequality,coveragepercentage,andnumberofdifferentqualificationsofcodestyleerrorshavechanged.Manytimes,youcan

Page 744:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

seethatwhenapproachingthereleasedate,thecodequalitydecreasesaspeopleareinarush.Thisisverybadbecausethisisthetimewhenmostofthebugsshouldbeeliminated.Havingastatisticaboutthequalitymayhelpchangethepracticebyseeingthetrendsbeforethequality,andthusthemaintainabilityofthecodegetsoutofhand.

Page 745:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 746:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SourcecodeversioncontrolSourcecodeversioncontrolsystemsstoredifferentversionsofthesourcecode.Thesedays,wecannotimagineprofessionalsoftwaredevelopmentwithoutit.Thiswasnotalwaysthecase,buttheavailabilityoffreeonlinerepositoriesencouragedhobbydeveloperstousesomeversioncontrol,andwhenthesedevelopersworkedforenterpriseslater,itwasevidentthattheuseofthesesystemsiskindofamust.

Therearemanydifferentrevisioncontrolsystems.ThemostwidelyusedoneisGit.TheversioncontrolthatwaspreviouslywidelyusedwasSVNand,evenbeforethat,CVS.Thesearelessandlessusedthesedays.WecanseeSVNasasuccessorofCVSandGitasasuccessorofSVN.Inadditiontothese,thereareotherversioncontrolsystemssuchasMercurial,Bazaar,orVisualStudioTeamServices.Foracomprehensivelistoftheavailabletools,visittheWikipediapageathttps://en.wikipedia.org/wiki/List_of_version_control_software.

MybetisthatyouwillmeetGitinthefirstplaceandthereisahighprobabilityofyoucomingacrossSVNwhenprogrammingforanenterprise.Mercurymayappearinyourpracticebutanyoftheothersthatcurrentlyexistareveryrare,areusedforaspecificarea,oraresimplyextinct.

Versioncontrolsystemsallowthedevelopmentteamtostorethedifferentversionsofthesoftwareinanorganizedmanneronastoragethatismaintained(backedupregularlyinareliablemanner).Thisisimportantfordifferentpurposes.

Thefirstthingisthatdifferentversionsofthesoftwaremaybedeployedtodifferentinstances.Ifwedevelopsoftwareforclientsandwehavemanyclientswithwhomwehopetohavetomakeaterrificbusiness,thendifferentclientsmayhavedifferentversions.Thisisnotonlybecausesomeclientsarereluctanttopayfortheupgrade,andwejustdonotwanttogivethenewversionforfree.Manytimes,thecoststhatriseonthesideofthecustomerpreventtheupgradeforalongtime.Softwareproductsdonotworkontheirowninanisolatedenvironment.Differentclientshavedifferentintegratedenvironments;thesoftwarecommunicateswithdifferentotherapplications.Whenanewversionistobeintroducedinanenterpriseenvironment,ithastobetestedforwhetheritworkswithallthesystemsithastocooperatewith.Thistestingtakesalotofeffortandmoney.Ifthenewfeaturesorothervaluesthatthenewversiondeliversovertheoldonedonotjustifythecost,thenitwouldbewasteofmoneytodeploythenewversion.Thefactthatthereisanewversionofoursoftwaredoesnotmeanthattheoldversionsarenotusable.

Ifthereissomebugatthecustomer'send,thenitisvitalthatwefixthebuginthatversion.Todoso,thebughastobereproducedinthedevelopmentenvironment,whicheventuallymeansthatthesourcecodeforthatversionhastobeavailableforthedevelopers.

Thisdoesrequirethecustomerdatabasetocontainreferencestothedifferentversionsofoursoftwareproductsthatareinstalledatthecustomersite.Tomakeitmorecomplicated,acustomermayhavemorethanoneversionatatimeindifferentsystemsandmayalsohavedifferentlicenses,sotheissueismorecomplexthanitfirstseems.Ifwedonotknowwhichversiontheclienthas,thenweareintrouble.Sincethedatabaseregisteringtheversionsforthecustomersandreallifemayget

Page 747:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

unsynchronized,softwareproductslogtheirversionatstartup.Wehaveaseparatesectionaboutversioninginthischapter.

Ifthebugisfixedintheversionthattheclienthas,theincidentatthecustomer'sendmaybesolvedafterdeployment.Theproblem,though,stillremainsiftheversionisnotthepreviousversionofthesoftware.Thebugfixintroducedtoanoldversionofthesoftwaremaystillbelurkingaroundinthelateror,forthatmatter,earlierversions.Thedevelopmentteamhastoidentifywhichversionsarerelevanttoclients.Forexample,anoldversionthatisnotinstalledanymoreatanyoftheclients'sitesdoesnotdeservetheinvestigation.Afterthat,therelevantversionshavetobeinvestigatedtocheckwhethertheyexhibitthebug.Thiscanonlybedoneifwehavethesourceversion.Someoldversionsmaynothavethebugifthecodecausingthebugisintroducedinlaterversions.Somenewversionsmayalsobeimmunetothebugbecausethebugwasalreadyfixedinthepreviousversion,orsimplybecausethepieceofcodethatcausedthebugwasrefactoredevenbeforethebugmanifested.Somebugsmayevenaffectaspecificversioninsteadofarangeofproducts.Bigfixingmaybeappliedtodifferentversionsandtheymayneedslightlydifferentfixes.Allthisneedsamaintainedsourceversionrepository.

Evenwhenwedonothavedifferentcustomerswithdifferentversions,itismorethanlikelythatwehavemorethanoneversionofoursoftwareindevelopment.Thedevelopmentofamajorreleaseiscomingtoanend,andtherefore,onepartoftheteamresponsiblefortestingandbugfixingfocusesonthoseactivities.Atthesametime,thedevelopmentoffeaturesforthenextversionstillgoeson.Thecodeimplementingthefunctionalitiesforthenextversionshouldnotgetintotheversionthatisabouttobereleased.Thenewcodemaybeveryfresh,untested,andmayintroducenewbugs.Itisverycommontointroducefreezetimesduringthereleaseprocess.Forexample,itmaybeforbiddentoimplementanynewfeatureoftheupcomingrelease.Thisiscalledfeaturefreeze.

Revisioncontrolsystemsdealwiththesefreezeperiods,maintainingdifferentbranchesofthecode.Thereleasewillbemaintainedinonebranchandtheversionforlaterreleasesinadifferentone.Whenthereleasegoesout,thebugfixesthatwereappliedtoitshouldalsobepropagatedtothenewerversion;otherwise,itmightsohappenthatthenextversionwillcontainbugsthatwerealreadyfixedinthepreviousversion.Todoso,thereleasebranchismergedwiththeongoingone.Thus,versioncontrolsystemsmaintainagraphoftheversions,whereeachversionofthecodeisanodeinthegraphandthechangesarevertices.

Gitgoesveryfarinthisdirection.Itsupportsbranchcreationandmergingsowellthatdeveloperscreateseparatebranchesforeachchangethattheycreateandthentheymergeitbackwiththemasterbranchwhenthefeaturedevelopmentisdone.Thisalsomakesforagoodopportunityforcodereview.ThedevelopermakingthefeaturedevelopmentorbugfixcreatesapullrequestintheGitHubapplication,andanotherdeveloperisrequestedtoreviewthechangeandperformthepull.Thisisakindoffour-eyedprincipleappliedtocodedevelopment.

Someoftherevisioncontrolsystemskeeptherepositoryonaserverandanychangegetstotheserver.Theadvantageofthisisthatanychangecommittedgetstoaserverdiskthatisregularlybackedupandisthussafe.Sincetheserver-sideaccessiscontrolled,anycodesenttotheservercannotberolledbackwithouttrace.Allversions,eventhewrongversions,arestoredontheserver.Thismayberequiredbysomelegalcontrol.Ontheotherhand,ifcommitrequiresnetworkaccessandserverinteraction,itmaybeslowandthiswill,inthelongrun,motivatedevelopersnottocommittheirchangesfrequently.Thelonger

Page 748:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

achangeremainsonthelocalmachine,themoreriskwehaveoflosingsomeofthecode,andmergingbecomesmoreandmoredifficultwithtime.Tohealthissituation,Gitdistributestherepositoryandthecommithappenstothelocalrepository,whichisexactlythesameastheremoteoneonsomeserver.Therepositoriesaresynchronizedwhenonerepositorypushesthechangestoanotherone.Thisencouragesthedeveloperstomakefrequentcommitstotherepository,givingshortcommitmessages,whichhelpsintrackingthechangemadetothecode.

Someolderversioncontrolsystemssupportfilelocking.Thisway,whenadeveloperchecksoutacodefile,otherscannotworkonthesamepieceofcode.Thisessentiallyavoidsthecollisionsduringcodemerging.Overtheyears,thisapproachdidnotseemtofitthedevelopmentmethodologies.Mergeissuesarelessofaproblemthanfilesthatarecheckedoutandforgotten.SVNsupportsfilelockingbutthisisnotreallyseriousanddoesnotpreventonedevelopertocommitchangestoafilethatsomebodyelselocked.Itismoreofonlyasuggestionthanreallocking.

Sourcecoderepositoriesareveryimportantbutshouldnotbeconfusedwithreleaserepositories,whichstorethecompiledreleasedversionofthecodeinbinary.Sourceandreleaserepositoriesworktogether.

Page 749:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 750:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SoftwareversioningSoftwareversioningismagic.ThinkaboutthedifferentversionsofWindowsorStarWarsmovies.Well,thelatterisnotreallysoftwareversioningbutitshowsthattheissueisverygeneral.InthecaseofJava,versioningisnotthatcomplex.Firstofall,theversionofJavaweusenowis9.Thepreviousversionwas1.8,beforethat1.7,andsoon,downto1.0.EarlierversionsofJavawerecalledOakbutthatishistory.Afterall,thatis,whocantellwhatJava2was?

Fortunately,whenwecreateaJavaapplication,thesituationissimpler.TherehasbeenasuggestionfromOracle,fromthetimeofJava1.3,abouthowtoversionJARs:

http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/versioning.html

Thisdocumentdistinguishesbetweenspecificationversionandimplementationversion.IfthespecificationofaJARcontentchanges,thecodehastobehavedifferentlyfromhowitwasbehavingtillthen;thespecificationversionshouldchange.Ifthespecificationisnotchangedbuttheimplementationdoes--forexample,whenwefixabug--thentheimplementationversionchanges.

Inpractice,nobodyhasusedthisscheme,althoughitisabrilliantideatoseparatetheimplementationandspecificationversions,atleast,intheory.Ievenbetthatmostofyourcolleagueshavenoteveneverheardaboutthisversioning.Whatweuseinpracticeissemanticversioning.

Semanticversioning(http://semver.org/)mixesthespecificationandimplementationversionsintoonesingleversionnumbertriplet.Thistriplethastheformatofmmp,thatis:

m:majorversionnumberm:minorversionnumberp:patchnumber

Thespecificationsaysthatthesenumbersstartwithzeroandincreasebyone.Ifthemajornumberiszero,itmeansthatthesoftwareisstillindevelopment.Inthisstate,theAPIisnotstableandmaychangewithoutanewmajorversionnumber.Themajorversionnumbergetsto1whenthesoftwareisreleased.LaterithastobeincreasedwhentheAPIoftheapplication(library)haschangedfromthepreviousversionandtheapplicationisnotbackwardcompatiblewiththepreviousversion.Theminorversionnumberisincreasedwhenthechangeeffectsonlytheimplementationbutthechangeissignificant,perhaps,eventheAPIisalsochangingbutinabackward-compatiblemanner.Thepatchversionisincreasedwhensomebugisfixed,butthechangeisnotmajorandtheAPIdoesnotchange.Theminorandthepatchlevelshavetoberesettozeroifanyversionnumberinthetripletinfrontofanyofthemisincreased:majorversionnumberincreaseresetsbothminorandpatchversion;minorversionnumberincreaseresetspatchnumber.

Thisway,semanticversioningkeepsthefirstelementofthetripletforthespecificationversion.Theminorisamixofthespecificationandimplementationversions.Apatchversionchangeisclearlyanimplementationversionchange.

Page 751:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Inadditiontothese,semanticversioningallowsappendingapre-releasestring,suchas-RC1and-RC2.Italsoallowstheappendingofmetadata,suchasadateafteraplussign,forexample,+20160120asadate.

Theuseofsemanticversioninghelpsthosethatusethesoftwaretoeasilyspotcompatibleversionsandtoseewhichversionisolderandwhichisnewer.

Page 752:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 753:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CodereviewWhenwecreateprogramsinaprofessionalway,itisdoneinteams.Thereisnoone-manshowprogrammingotherthaninahobbyorgoingalongwiththetutorials.Itisnotonlybecauseitismoreeffectivetoworkinteamsbutalsobecauseonepersonisvulnerable.Ifyouworkaloneandgethitbythebusoryouhitthelotteryandloseyourabilityormotivationtoworkontheproject,yourcustomerisintrouble.Thatisnotprofessional.Professionalprojectsshouldberesilienttoanymemberfallingoff.

Teamworkneedscooperationandoneformofcooperationiscodereview.Thisistheprocesswhenadeveloperoragroupofdevelopersreadsapartofthecodethatsomeotherteammembershavewritten.Therearedirectgainsfromthisactivity;

Thedevelopersreadingthecodegetmoreknowledgeaboutthecode;theylearnthecode.Thisway,ifthedevelopercreatingthecodegetsoutoftheprocessforanyreason,theotherscancontinuetheworkwithminimalbump.Codingstylescanbealigned.Developers,evenseniors,payingcarefulattentionmakecodingmistakes.Thismaybeabugoritmaybeacodingstyleviolation.Codingstyleisimportantbecausethemorereadablethecodeis,thelesspossibilityofithavingunnoticedbugs.(Alsoseethenextbulletpoint.)Itisalsoimportantthatthecodingstyleisthesamefortheteam.Allteammembersshouldusethesamestyle.LookingatacodethathasadifferentstylefromtheoneIwroteisabithardertofollowandunderstand.Thedifferencesmaydistractthereaderandtheteammembershavetobeabletoreadthecode.Thecodebelongstotheteamandnotasingledeveloper.Anyteammembershouldknowthecodeandbeabletomodifyit.Duringcodereview,alotofbugscanbediscovered.Thepartieslookingatthecodeandtryingtounderstandtheworkingofitmayoccasionallydiscoverbugsfromthestructureofthecode,whichareotherwisehardtodiscoverusingtests.Ifyouwant,codereviewisthewhitestwhiteboxtest.Peoplethinkdifferentlyanddifferentmindsetscatchdifferentbugs.

Codereviewcanbedoneonlineandoffline.Itcanbedoneinteamsorpeer-to-peer.

MostteamsfollowthecodereviewprocessthatGitHubsupports,whichisthesimplest.Changestothecodearecommittedtoabranchandarenotmergedwiththecodedirectlybut,rather,apullrequestiscreatedonthewebinterface.Thelocalpolicymayrequirethatadifferentdeveloperperformthepull.Thewebinterfacewillhighlightthechangesandwecanaddcommentstothechangedcode.Ifthecommentsaresignificant,thentheoriginaldeveloperrequestingthepullshouldmodifythecodetoanswerthecommentsandrequestthepullagain.Thisensuresthatatleasttwodevelopersseeanychange;theknowledgeisshared.

Feedbackispeer-to-peer.Itisnotaseniorteachingajunior.Thatneedsadifferentchannel.CommentsinGitHubarenotgoodforthispurpose;atleast,therearebetterchannels.Perhapstalkingfacetoface.Commentsmaycomefromaseniortoajuniororfromajuniortoasenior.Inthiswork,givingfeedbackonthequalityofthecode,seniorsandjuniors,areequal.

Thesimplestandperhapsthemostfrequentcommentisthefollowing:IcanseethatXyz.javawaschangedinthemodificationbutIseenochangemadeto

Page 754:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

XyzTest.java.Thisisalmostaninstantrefusalforthemerge.Ifanewfeatureisdeveloped,unittestshavetobecreatedtotestthatfeature.Ifabugisfixed,thenunittestshavetobecreatedtopreventthebugfromcomingback.Ipersonallygotthiscommentmanytimes,evenfromjuniors.Oneofthemtoldme,"Weknowthatyouweretestingusifwedaredtogivefeedback."GodknowsIwasnot.Theydidnotbelieve.

WhilechangereviewandGitHubisagoodtoolduringdevelopment,itmaynotbeappropriatewhenalargerchunkofcodehastobereviewed.Insuchacase,othertools,suchasFishEye,havetobeused.Inthistool,wecanselectthesourcefilesforrevieweveniftheywerenotrecentlychanged.Wecanalsoselectreviewersanddeadlines.CommentingissimilartoGitHub.Finally,thistypeofcodereviewfinisheswithacodereviewsession,wherethedevelopersgatheranddiscussthecodeinperson.

Whileorganizingsuchasession,itisimportantthatapersonwhohasexperiencemanagingotherpeoplemediatesthesesessions.Codeanddiscussiononstylescangetverypersonal.Atthesametime,whenattendingsuchameeting,youshouldalsopayattentionsoasnottogetpersonal.Therewillbeenoughparticipantswhomaynotknowthisorarelessdisciplined.

Neverattendareviewsessionwithoutreviewingthecodefirstusingtheonlinetools.Whenyoumakecomments,thelanguageshouldbeverypoliteforthereasonIhavealreadymentioned.Finally,themediatorofthemeetingshouldbeabletoseparateimportantandnotsoimportantissuesandtostopdebateonbagatellethings.Somehow,thelessimportantissuesaremoresensitive.Ipersonallydonotcareaboutformattingthetabsizeifitistwoorfourspacesandifthefileshouldcontainonlyspacesoriftabcharactersareallowed,butpeopletendtoliketowastetimeonsuchissues.

ThemostimportantissueduringcodereviewsessionsisthatweareprofessionalanditmayhappenthatIreviewandcommentyourcodetoday,buttomorrow,itwillbejusttheopposite,andweworktogetherandwehavetoworktogetherasateam.

Page 755:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 756:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

KnowledgebaseKnowledgebasewasabuzzwordafewyearsago.Fewcompanieswereevangelizingtheideaofwikitechnologyandnobodywasusingit.Today,thelandscapeofknowledgebaseistotallydifferent.Allenterprisesusesomekindofwikiimplementationthatistheretoshareknowledge.TheymostlyuseConfluence,buttherearealsootherwikisolutionsavailable,commercialandfreeaswell.

Knowledgebasesstoreinformationthatyou,asadeveloper,wouldwritedowninapapernotebookforyourlaterreference,forexample,theIPaddressofthedevelopmentserver,directorieswheretoinstalltheJARfiles,whatcommandstouse,whatlibrariesyouhavecollected,andwhyyouusethem.Themajordifferenceisthatyouwriteitinaformattedwayintoawikianditisavailableimmediatelyforotherdevelopers.Itisabitofaburdenonthedevelopertowritethesepages,anditneedssomeself-disciplinefirst.StickingtotheexampleoftheIPaddressofthedevelopmentserverandtheinstalldirectories,youhavetowritenotonlytheIPaddressoftheserverbutalsosometextexplainingwhattheinformationis,becausetheothersmaynotunderstanditotherwise.Itisalsoabitofworktoplacethepagewiththeinformationinthewikisystemwithagoodname,linkingittootherpages,orfindingtheappropriatepositionofthepageinthetreeofpages.Ifyouwereusingthepapernotebook,youcouldjustwritedowntheIPaddressandthedirectoriesonthefirstfreepageofthebookandyouwouldjustrememberallothers.

Thewikiapproachwillpaybackwhencoworkersdonotneedtofindtheinformationthemselves;youcanfindtheinformationinaneasierwaybecauseothercoworkershavealsorecordedtheirfindingsintheknowledgebaseand,lastbutnotleast,afewmonthslater,youfindtheinformationyourecordedyourself.Inthecaseofapapernotebook,youwouldturnthepagestofindtheIPaddressandyoumayormaynotrememberwhichoneistheprimaryandwhichisthesecondaryserver.Youmayevenforgetbythenthattherearetwoservers(orwasitadoublecluster?).

Tohavealonglistofavailablewikisoftware,visithttps://en.wikipedia.org/wiki/Comparison_of_wiki_software.

Page 757:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 758:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

IssuetrackingIssuetrackingsystemskeeptrackofissues,bugs,andothertasks.Thefirstissuetrackingsystemswerecreatedtomaintainthelistofbugsandalsothestateofthebugfixingprocesstoensurethatabug,identifiedandrecorded,willnotgetforgotten.Later,thesesoftwaresolutionsdevelopedandbecamefull-fledgedissuetrackersandareunavoidableprojectmanagementtoolsineveryenterprise.

ThemostwidelyusedissuetrackingapplicationusedinmanyenterprisesisJira,butonthehttps://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systemspage,youcanfindmanyotherapplicationslisted.

Themostimportantfeatureofanissuetrackerapplicationisthatithastorecordanissueindetailinaneditablemanner.Ithastorecordthepersonwhorecordedtheissueincasemoreinformationisneededduringissuehandling.Thesourceoftheissueisimportant.Similarly,issueshavetobeassignedtosomeresponsibleperson,whoisaccountablefortheprogressofissuehandling.

Modernissuetrackingsystemsprovidecomplexaccesscontrol,workflowmanagement,relationmanagement,andintegrationwithothersystems.

Accesscontrolwillonlyallowthepersonwhohassomethingtodowithanissueaccesstoit,sootherscannotalterthestateofanissueorevenreadtheinformationattachedtoit.

Anissuemaygothroughdifferentworkflowstepsdependingonthetypeofissue:abugmaybereportedorreproduced,arootcauseanalyzed,afixdevelopedortested,apatchcreated,afixmergedwiththenextreleaseversionorpublishedintherelease.Thisisasimpleworkflowwithafewstates.

Relationmanagementallowssettingdifferentrelationsbetweenissuesandallowingtheusertonavigatefromissuetoissuealongtheserelations.Forexample,aclientreportsabug,andthebugisidentifiedasbeingthesameasanotheralreadyfixed.Insuchacase,itwouldbeinsanetogothroughtheoriginalworkflowandcreatinganewpatchforthesamebug.Instead,theissuegetsarelationpointingtotheoriginalissueandsetsthestatetobeclosed.

Integrationwithothersystemsisalsousefultokeepaconsistentdevelopmentstate.Versioncontrolmayrequirethat,foreverycommit,thecommitmessagecontainsareferencetotheissuethatdescribestherequirement,bug,orchangethatthecodemodificationsupports.Issuesmaybelinkedtoknowledgebasearticlesoragileprojectmanagementsoftwaretoolsusingweblinks.

Page 759:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 760:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TestingWehavealreadydiscussedtestingwhenwetalkedaboutunittesting.Unittestingisextremelyimportantinagiledevelopmentandithelpskeepthecodecleanandreducethenumberoferrors.Butthisisnottheonlytypeoftestingthatyouwillseeinenterprisedevelopment.

Page 761:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 762:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TypesoftestsTestingisperformedformanyreasonsbutthereareatleasttworeasonsthatwehavetomention.Oneistohuntthebugsandcreateerror-freecodeasmuchaspossible.Theotheristoprovethattheapplicationisusableandcanbeutilizedforthepurposeitwasmeantfor.Itisimportantfromtheenterprisepointofviewandconsidersalotofaspectsthatunittestdoesnot.Whileunittestfocusesononeunitand,thus,isanextremelygoodtooltopointoutwheretheerroris,itistotallyunusablewhenitcomestodiscoveringbugsthatcomefromerroneousinterfacesbetweenmodules.Theunittestsmockexternalmodulesand,thus,testthattheunitworksasexpected.However,ifthereisanerrorinthisexpectationandtheothermodulesdonotbehaveinthesamewayastheunittestmock,theerrorwillnotbediscovered.

Todiscovertheerrorsonthislevel,whichisthenextlevelaboveunittest,wehavetouseintegrationtests.Duringintegrationtests,wetesthowindividualunitscanworktogether.WhenweprograminJava,theunitsareusuallyclasses;thus,theintegrationtestwilltesthowthedifferentclassesworktogether.Whilethereisaconsensus(moreorless)aboutwhataunittestisinJavaprogramming,thisislesssointhecaseofintegrationtests.

Inthisregard,theexternaldependencies,suchasothermodulesreachableviathenetworkordatabaselayersmaybemocked,ormaybesetupusingsometestinstanceduringintegrationtesting.Theargumentisnotaboutwhetherthesepartsshouldbemockedornot,onlytheterminology.Mockingsomecomponentssuchasthedatabasehasadvantagesaswellasdrawbacks.Asinthecaseofanymock,thedrawbackisthecostofsettingupthemockaswellasthefactthatthemockbehavesdifferentlyfromtherealsystem.Suchadifferencemayresultinsomebugsstillremaininginthesystemandlurkingthereuntilalatercaseoftestingor,Godforgive,productionisused.

Integrationtestsareusuallyautomatedinawaysimilartounittests.However,theyusuallyrequiremoretimetoexecute.Thisisthereasonwhythesetestsarenotexecutedateachsourcecodechange.Usually,aseparatemavenorGradleprojectiscreatedthathasadependencyontheapplicationJARandcontainsonlyintegrationtestcode.Thisprojectisusuallycompiledandexecuteddaily.

Itmayhappenthatdailyexecutionisnotfrequentenoughtodiscovertheintegrationissuesinatimelymanner,butamorefrequentexecutionoftheintegrationtestsisstillnotfeasible.Insuchacase,asubsetoftheintegrationtestcasesisexecutedmorefrequently,forexample,everyhour.Thistypeoftestingiscalledsmoketesting.Thefollowingdiagramshowsthepositionofthedifferenttestingtypes:

Page 763:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Whentheapplicationistestedinafullysetupenvironment,thetestingiscalledsystemtesting.Suchtestingshoulddiscoveralltheintegrationbugsthatmayhavebeenlurkingandcoveredduringtheprevioustestingphases.Thedifferenttypeofsystemtestscanalsodiscovernon-functionalissues.Bothfunctionaltestingandperformancetestingaredoneonthislevel.

Functionaltestingchecksthefunctionsoftheapplication.Itensuresthattheapplicationfunctionsasexpectedoratleasthasfunctionsthatareworthinstallingintheproductionenvironmentandcanleadtocostsavingorprofitincrease.Inreallife,programsalmostneverdeliverallthefunctionsthatwereenvisionedinanyrequirementdocumentation,butiftheprogramisusableinasanemanner,itisworthinstallingit,assumingthattherearenosecurityissuesorotherissues.

Incasetherearealotoffunctionsintheapplication,functionaltestingmaycostalot.Insuchacase,somecompaniesperformasanitytest.Thistestdoesnotcheckthefullfunctionalityoftheapplication,onlyasubsettoensurethattheapplicationreachesaminimalqualityrequirementanditisworthspendingthemoneyonthefunctionaltesting.

Theremaybesometestcasesthatarenotenvisionedwhentheapplicationwasdesignedandthusthereisnotestcaseinthefunctionaltestplan.Itmaybesomeweirduseraction,auserpressingabuttononthescreenwhennobodythoughtitwaspossible.Users,evenifbenevolent,happentopressortouchanythingandenterallpossibleunrealisticinputsintoasystem.Ad-hoctestingtriestoamendthisshortage.Atesterduringad-hoctestingtriesallthepossiblewaysofuseoftheapplicationthatheorshecanimagineatthemomentthetestisexecuted.

Thisisalsorelatedtosecuritytesting,alsocalledpenetrationtestingwhenthevulnerabilitiesofthesystemarediscovered.Thesearespecialtypesofteststhatareperformedbyprofessionalswhohavetheircoreareaofexpertiseinsecurity.Developersusuallydonothavethatexpertise,butatleast,thedevelopersshouldbeabletodiscussissuesthatarediscoveredduringsuchatestandamendtheprogramtofixthesecurityholes.ThisisextremelyimportantinthecaseofInternetapplications.

Page 764:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Performancetestingchecksthattheapplication,inareasonableenvironment,canhandletheexpectedloadthattheuserputsonthesystem.Aloadtestemulatestheuserswhoattackthesystemandmeasurestheresponsetimes.Iftheresponsetimeisappropriate,thatis,lowerthantherequiredmaximumunderthemaximumload,thenthetestpasses;otherwise,itfails.Ifaloadtestfails,itisnotnecessarilyasoftwareerror.Itmaysohappenthattheapplicationneedsmoreorfasterhardware.Loadtestsusuallytestthefunctionalityoftheapplicationinonlyalimitedwayandonlytestusescenariosthatposereadloadontheapplication.

Manyyearsago,weweretestingawebapplicationthathadtohavearesponsetimeof2seconds.Theloadtestwasverysimple:issueGETrequestssothatthereareamaximumof10,000requestsactiveatthesametime.Westartedwith10clients,andthenascriptwasincreasingtheconcurrentusersto100,then1,000,andthensteppingupbythousandeveryminute.Thisway,theloadtestwas12minuteslong.Thescriptprintedtheaverageresponsetime,andwewerereadytoexecutetheloadtestat4:40pmonaFriday.Theaverageresponsetimestartedfromafewmillisecondsandwentupto1.9secondsastheloadwasincreasedto5,000concurrentusers,andfromthere,itwasdescendingdownto1secondastheloadwasincreasedto10,000users.YoucanunderstandtheattitudeofthepeopleonaFridayafternoon,beinghappythatwemettherequirements.Mycolleaguesleftfortheweekendhappily.IremainedtestingabitmorebecauseIwasbotheredbythephenomenonthattheresponsetimedecreasesasweincreasetheloadabove5,000.First,Ireproducedthemeasurementandthenstartedlookingatthelogfiles.At7pm,Ialreadyknewwhatthereasonwas.Whentheloadwentabove5,000,theconnectionstheApacheserverwasmanagingstartedtoexhaustandthewebserverstartedtosendback500internalerrorcodes.ThatissomethingthatApachecanveryeffectivelydo.Itisveryfastintellingyouthatyoucannotbeserved.Whentheloadwasaround10,000concurrentusers,70%oftheresponsesalreadyhad500errors.Theaveragewentdown,buttheuserswereactuallynotserved.IreconfiguredtheApacheserversothatitcouldservealltherequestsandforwardeachtoourapplicationjusttolearnthattheresponsetimeofourapplicationwasaround10secondsatthemaximumload.Around10pm,whenmywifewascallingmymobilethethirdtime,IalsoknewhowlargeamemoryIshouldsetintheTomcatstartupfileintheoptionsfortheJVMtogetthedesired2-secondresponsetimeincaseof10,000concurrentusers.

Stresstestisalsoatypeofperformancetestthatyoumayalsoface.Thistypeoftestincreasestheloadonthesystemuntilitcannothandletheload.Thattestshouldensurethatthesystemcanrecoverfromtheextremeloadautomaticallyormanuallybut,innocase,willdosomethingthatitshouldn'tatall.Forexample,abakingsystemshouldnotevercommitanunconfirmedtransaction,nomatterhowbigtheloadthereis.Iftheloadistoohigh,thenitshouldleavethedoughrawbutshouldnotbakeextrabread.

Themostimportanttestatthetopofthehierarchyistheuseracceptancetest.Thisisusuallyanofficialtestthatthecustomer,whobuysthesoftware,executesandinthecaseofsuccessfulexecution,paysthepriceforthesoftware.Thus,thisisextremelyimportantinprofessionaldevelopment.

Page 765:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 766:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

TestautomationTestscanbeautomated.Itisnotaquestionofwhetheritispossibletoautomatizeatest,onlywhetheritisworthdoingso.Unittestsandintegrationtestsareautomated,andastimeadvances,moreandmoretestsgetautomatedaswemovealongtohigherstepstowardstheuseracceptancetest(UAT).UATisnotlikelytobeautomated.Afterall,thistestcheckstheintegrationbetweentheapplicationandtheuser.Whiletheuser,asanexternalmodule,canbemockedusingautomationinlowerlevels,weshouldreachthelevelwhentheintegrationtesthappenswithoutmocks.

Therearemanytoolsthathelptheautomationoftests.Theblockerfortestautomation,thesedays,isthecostofthetoolstodoso,thecostoflearninganddevelopingthetests,andthefearthattheautomatedtestsarenotdiscoveringsomeoftheerrors.

Itistruethatitiseasiertodosomethingwrongwithaprogramthanwithout.Thisissotrueforalmostanythingnotonlyfortesting.Andstillwedouseprograms;whyelsewouldyoureadthisbook?Someoftheerrorsmaynotbediscoveredduringautomatedfunctionaltesting,whichwouldotherwisehavebeendiscoveredusingmanualtests.Atthesametime,whenthesametestisexecutedthehundredthtimebythesamedeveloper,itisextremelyeasytoskipanerror.Anautomatedtestwillnoteverdothat.Andmostimportantly,thecostoftheautomatedtestisnot100timesthecostofrunningitonce.

Wehaveusedtestautomationtoolsinthisbook.SoapUIisatoolthathelpsyoucreateteststhatcanbeexecutedautomatically.OthertestingtoolsthatareworthlookingatareCucumber,Concordion,Fintnesse,andJBehave.Thereisagoodcomparisonoftoolsathttps://www.qatestingtools.com/.

Page 767:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 768:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

BlackboxversuswhiteboxYoumayhaveheardmanytimesthatatestisablackboxtest.Thissimplymeansthatthetestdoesnotknowanythingabouthowthesystemundertest(SUT)isimplemented.ThetestreliesonlyontheinterfaceoftheSUTthatisexportedfortheoutsideworld.Awhiteboxtest,ontheotherendofthescale,teststheinternalworkingoftheSUTandverymuchreliesontheimplementation:

Boththeapproacheshaveadvantagesanddisadvantages.Weshoulduseone,orthemixtureofthetwoapproaches,awaythatfitsthepurposeoftheactualtestingneedsthemost.Ablackboxtestnotrelyingontheimplementationdoesnotneedtochangeiftheimplementationchanges.Iftheinterfaceofthetestedsystemchanges,thenthetestshouldalsobechanged.Awhiteboxtestmayneedchangesiftheimplementationchanges,eveniftheinterfaceremainsthesame.Theadvantageofthewhiteboxtestisthat,manytimes,itiseasiertocreatesuchatestandthetestingcanbemoreeffective.

Togetthebestofbothworlds,systemsaredesignedtobetestable.Becareful,though.Itmeansmanytimesthatthefunctionalityinternaltothetestedsystemispropagatedtotheinterface.Thatway,thetestwilluseonlytheinterfaceand,thus,canbedeclaredtobeablackbox,butitdoesnothelp.Ifsomethingchangesintheinternalworkingofthetestedsystem,thetesthastofollowit.Theonlydifferenceisthatyoumaycallitablackboxtestiftheinterfacealsochanges.Thatdoesnotsaveanywork.Rather,itincreasesit:wehavetocheckallthemodulesthatrelyontheinterfaceiftheyalsoneedanychange.

Idonotsaythatweshouldnotpayattentiontocreatingtestablesystems.Manytimesmakingasystemtestableresultsincleanerandsimplercode.Ifthecode,however,getsmessierandmuchlongerbecausewewanttomakeittestable,thenweareprobablynotgoingintherightway.

Page 769:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 770:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

SelectinglibrariesProgrammingfortheenterpriseorevenprogrammingamoderatelysizedprojectcannotbedonewithouttheuseofexternallibraries.IntheJavaworld,mostofthelibrariesthatweuseareopensourceand,moreorless,freetouse.Whenwebuyalibrarythatissoldformoney,thereisusuallyastandardprocessenforcedbythepurchasingdepartment.Insuchacase,thereisawrittenpolicyabouthowtoselectthevendorandthelibrary.Inthecaseof"free"software,theydonotusuallycare,thoughtheyshould.Insuchacase,theselectionprocessmainlylieswiththeITdepartmentanditisthereforeimportanttoknowthemajorpointstobeconsideredbeforeselectingalibraryevenifforfree.

Inthepreviousparagraph,Iputthewordfreebetweenquotes.Thatisbecausethereisnosoftware,whichisfree.Thereisnosuchthingasafreelunch,astheysay.Youhaveheardthismanytimesbutitmaynotbeobviousinthecaseofanopensourcecodelibraryorframeworkyouaregoingtoselect.Themajorselectionfactorforanypurchaseorimplementationisthecost,theprice.Ifthesoftwareisfree,itmeansthatyoudonotneedtopayanupfrontfeeforthesoftware.However,thereisacostinintegratingitandusingit.Supportcostsmoney.Somebodymaysaythatthesupportiscommunitysupportandalsoavailablefreeofcharge.Thethingisthatthetimeyouspendhuntingforaworkaroundthathelpsyoutogetoverabugisstillmoney.Itisyourtime,orincaseyouareamanager,itisthetimeoftheprofessionalinyourdepartmentwhosetimeyoupayfor,or,asamatteroffact,itcanbeanexternalcontractorwhowillhandyouahugebillincaseyoudonothavetheexpertisein-housetosolvetheissue.

Sincefreesoftwaredoesnothaveapricetagattached,wehavetolookattheotherfactorsthatareimportantintheselectionprocess.Attheendoftheday,theyallwillaffectthecostinsomeway.Sometimes,thewayacriterionaltersthecostisnotobviousoreasilycalculable.However,foreachone,wecansetno-golevelsthatarebasedontechnologydecisions,andwecancomparelibrariesforbeingbetterorworsealongwitheachofthecriteria.

Page 771:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 772:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Fitforthepurpose

Perhaps,thisisthemostimportantfactor.Otherfactorsmaybearguedaboutintermsofthescaleofimportance,butifalibraryisnotappropriateforthepurposewewanttouse,thenthisiscertainlynotsomethingtoselect,nomatterwhat.Itmaybeobviousinmanycases,butyoumaybesurprisedhowmanytimesIhaveseenaproductselectedbecauseitwasthefavoriteofapersoninsomeotherprojectandthelibrarywasforcedforuseinthenewprojecteventhoughtherequirementsweretotallydifferent.

Page 773:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 774:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

LicenseThelicenseisanimportantquestionasnotallfreesoftwareisfreeforalluses.Someofthelicensesallowfreeuseforhobbyprojectsandeducationbutrequireyoutopurchasethesoftwareforprofessional,profit-orienteduse.

Themostwidelyusedlicensesandtheirexplanation(andthewholetextofthelicense)isavailableonthewebpageoftheOpenSourceInitiative(https://opensource.org/licenses).Itlistsninedifferentlicenses,andtomakethesituationabitmorecomplex,theselicenseshaveversions.

OneoftheoldestlicensesistheGeneralPublicLicense(GPL)standingforGNU.Thislicensecontainsthefollowingsentences:

Forexample,ifyoudistributecopiesofsuchaprogram,whethergratisorforafee,youmustpassontotherecipientsthesamefreedomsthatyoureceived.Youmustmakesurethatthey,too,receiveorcangetthesourcecode.

Ifyoucreatesoftwareforafor-profitenterpriseandthecompanyintendstosellsoftware,youprobablycannotuseanylineofcodethatisfromaGPL-licensedsoftware.Itwouldimplythatyouarerequiredtopassonyourownsourcecode,whichmaynotbethebestsalesstrategy.Apachelicense,ontheotherhand,maybeokayforyourcompany.Thisissomethingthatthelawyersshoulddecide.

Eventhoughthisisthelawyers'work,thereisoneimportantpointthatwedevelopersmustbeawareofandpaycloseattentionto.Sometimes,thelibrariescontaincodefromotherprojectsandtheirlicense,asadvertised,maynotbetherealone.AlibrarymaybedistributedundertheApachelicensebutcontainscodethatisGPL-licensed.ThisisobviouslyaviolationoftheGPLlicense,whichwascommittedbysomeopensourcedevelopers.Whywouldyoucare?Herecomestheexplanationviaanimaginedsituation.

Youdevelopsoftwareforanenterprise.Let'ssaythatthiscompanyisoneofthelargestcarmanufacturersoftheworld,oritisoneofthelargestbanks,pharma,whatever.TheowneroftheGPLsoftwareseeksremediesforthemisuseofhersoftware.Willshesuethesoftwaredeveloper,JohnDoe,whohasatotalwealthof200K,oryourcompany,claimingthatyoudidnotdulycheckthelicenseofthecode?Shecertainlywillnotdigforgoldwherethereisnone.Suingthecompanyyouworkformaynotbesuccessful,butcertainlynotagoodprocessyouoranyoneatthecompanywants.

Whatcanweassoftwareprofessionalsdo?

Wehavetouselibrariesthatarewellknown,usedwidely.Wecancheckthesourcecodeofthelibrarytoseewhetherthereissomecopiedcode.Somepackagenamesmaypresentsomeclue.YoucanGooglesomepartofthesourcecodetofindmatches.Lastbutnotleast,thecompanycansubscribetoservicesthatprovidesimilarresearchforthelibraries.

Page 775:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 776:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Documentation

Documentationisanimportantaspect.Ifthedocumentationisnotappropriate,itwillbehardtolearnhowtousethelibrary.Someoftheteammembersmayhavealreadyknownthelibrary,but,again,thismaynotbethecaseforlaterteammembers.Weshouldconsiderourcolleagues,whoareexpectedtobeaverageprogrammers,andtheywillhavetolearntheuseofthelibrary.Thusdocumentationisimportant.

Whenwespeakaboutdocumentation,weshouldnotonlythinkabouttheJavaDocreferencedocumentationbutalsotutorialsandbooksiftheyareavailable.

Page 777:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 778:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ProjectaliveItisimportantnottoselectalibraryforusethatisnotalive.Havealookattheroadmapofthelibrary,thelasttimeareleasewasshipped,andthefrequencyofthecommits.Ifthelibraryisnotalive,weshouldconsidernotusingit.Librariesworkinanenvironmentandtheenvironmentchanges.Thelibrarymayconnecttoadatabase.Thenewversionofthedatabasemayprovidenewfeaturesthatgiveusbetterperformanceonlyifthelibraryismodifiedtoaccommodatethesenewfeatures.ThelibrarycommunicatesoverHTTP;willitsupportthenew2.0versionoftheprotocol?Ifnothingelse,theversionoftheJavaenvironmentwillchangeovertheyearsandthelibraryweuseshouldsoonerorlaterfollowittoleveragethenewfeatures.

Thereisnoguaranteethatanalivelibrarywillalwaysstayalive.However,alibrarythatisalreadydeadwillcertainlynotresurrect.

Eveniftheprojectisaliveatthemoment,therearesomepointsthatmaygivesomehintsaboutthefutureofthelibrary.Ifthecompanydevelopingitiswell-establishedandfinanciallystable,andthelibraryisdevelopedwithareasonablebusinessmodel,thenthereisalowriskthattheprojectdies.Iftherearealotofcompanieswhousethelibrary,thenitislikelythattheprojectwillstayaliveeveniftheoriginalteamstopsworkingonitortheoriginalfinancingstructurechanges.However,theseareonlysmallfactorsandnotwell-establishedfacts.Thereisnoguarantee,andtellingthefutureismoreanartthanascience.

Page 779:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 780:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

MaturityMaturityissimilartothepreviouscriterion.Aprojectmayverywellbealivejuststartingup,butifitisinitsinfancy,webetternotusethelibraryforalargeproject.Whenaprojectisinitsearlyphase,alotofbugscanbeinthecode,theAPImaychangeradically,andpresumably,theremayonlybeasmallnumberofcompaniesrelyingonthecode.Thisalsomeansthatthecommunitysupportislower.

Ofcourse,ifalltheprojectsselectonlymatureopensourcecode,thennoopensourceprojectwouldevergettothematurestate.Weshouldassesstheimportanceoftheproject.Istheprojectbusiness-critical?Willtheprojectbecomebusiness-critical?

Iftheprojectisnotbusiness-critical,thecompanymayaffordtoinventafreshlibrarythatisnotthatmature.Itmaybereasonableiftherearenomaturelibrariesforthepurposebecausethetechnologyyouaregoingtouseisrelativelynew.Insuchacase,theprojectinthecompanyisprobablyalsonewandnotbusiness-criticalyet.Itwillbebusiness-critical,wehope,aftersometime,butbythattime,thelibrarywillbemature,ormayjustdieandwecanselectacompetingsolutionbeforetheprojectbecomestooexpensivetoswitch.

Judgingthematurityofalibraryisalwaysdifficultandhastobealignedwiththematurityandimportanceoftheprojectthatwewanttousethelibraryfor.

Page 781:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 782:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Numberofusers

Ifthelibraryisaliveandmaturebuttherearenotmanyusers,thensomethingissmelly.Whydon'tpeopleusethelibraryifitisgood?Ifthenumberofusersforalibraryorframeworkislowandtherearenolargecorporationsamongtheusers,thenitisprobablynotagoodone.Nobodyusingitmaysignalthatourassessmentoftheothercriteriamaynotbeappropriate.

Alsonotethatifthereareonlyafewusersofthelibrary,thentheknowledgeinthecommunityisalsoscarceandwemaynotbeabletogetcommunitysupport.

Page 783:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 784:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

The"Ilikeit"factor

Lastbutnotleast,theIlikeitfactorisextremelyimportant.Thequestionisnotwhetheryoulikethelibrarybutratherhowmuchthedeveloperslikeit.Developerswilllikealibrarythatiseasytouseandfuntoworkwith,andthiswillresultinlowcost.Ifthelibraryishardtouseanddevelopersdonotlikeit,thentheywillnotlearntouseittothelevelofprofessionrequiredforgoodquality,onlytothelevelthatisjustneeded.Theendresultwillbesuboptimalsoftware.

Page 785:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 786:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ContinuousintegrationanddeploymentContinuousintegrationmeansthatwheneveranewversionispushedtothesourcecoderepository,thecontinuousintegrationserverkicksin,pullsthecodetoitsdisk,andstartsthebuild.Itcompilesthecodefirst,thenrunstheunittests,firesthestaticcodeanalysistools,and,ifallgoesright,itpackagesasnapshotreleaseanddeploysitonadevelopmentserver.

CIservershavewebinterfacesthatcanbeusedtocreatearelease.Insuchacase,thedeploymentcanevengotothetestserversoreventoproductiondependingonlocalbusinessneedsandonthepolicythatwascreatedaccordingly.

Automatingthebuildanddeploymentprocesshasthesameadvantagesasanyotherautomation:repeatedtaskscanbeperformedwithoutmanualintervention,whichistedious,boring,and,thus,error-proneifdonebyahuman.Theoutstandingadvantageisthatifthereissomeerrorinthesourcecodethatcanbediscoveredbytheautomatedbuildprocess,itwillbediscovered.Novicedeveloperssaythatitischeaperandeasiertobuildthecodelocally,whichthedevelopersdoanyway,andthenpushthecodetotheserverifthebuildprocessisalreadychecked.Itispartlytrue.Developershavetocheckthatthecodeisofgoodqualityandbuildswell,beforesendingittothecentralrepo.However,thiscannotalwaysbeachieved.Someerrorsmaynotmanifestonlocalenvironments.

ItmaysohappenthatonedeveloperaccidentallyusesanewerversionofJavathantheonesupportedandusesanewfeatureofthenewversion.Enterprisesdonotgenerallyusethelatesttechnology.Theytendtouseversionsthatareproven,havemanyusers,andaremature.Thisyear,in2017,whenJava9isgoingtobereleasedinJuly,hugeenterprisesstilluseJava1.6and1.7.SinceJava9hasmanynewfeaturesthatarenottrivialtoimplement,IexpectthattheadoptionofthetechnologymaytakeevenlongerthantheadoptionofJava1.8,whichgaveusfunctionalprogrammingandlambda.

Itmayalsohappenthatanewlibraryisaddedtothedependenciesofthebuildandthedeveloperwhoaddedittothebuildfile(pom.xml,orbuild.gradle)coulduseitwithoutanyproblemonherlocalmachine.Itdoesnotmeanthatthelibraryisofficiallyaddedtotheproject,anditmaynotbeavailableinthecentralcoderepository(Artifactory,Nexus,orotherimplementationsofthecoderepository).Thelibrarymayhaveonlybeenonthelocalrepositoryofthedeveloper,andshemayhaveassumedthatsincethecodecompiles,thebuildisOK.

Somelargeorganizationsusedifferentcoderepositoriesfordifferentprojects.Thelibrariesgetintotheserepositoriesfollowingmeticulousexaminationanddecisions.Somelibrariesmaygetthere,whileothersmaynot.Thereasontohavedifferentrepositoriescouldbenumerous.Someprojectisdevelopedforonecustomerwhohasadifferentpolicyaboutanopensourceprojectthantheother.Iftheenterprisedevelopscodeforitself,itmaysohappenthatsomelibraryisphasedoutornotsupportedanymore,andcanonlybeusedforprojectsthatareold.Amaintenancereleasemaynotneedtoreplacealibrary,butnewprojectsmaybenotbeallowedtouseadyingsoftwarelibrary.

TheCIservercanrunonasinglemachineoritcanrunonseveralmachines.Incaseitservesmany

Page 787:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

projects,itmaybesetupasacentralserverwithmanyagentsrunningondifferentmachines.Whensomebuildprocesshastobestarted,thecentralserverdelegatesthistasktooneoftheagents.Theagentsmayhavedifferentloads,runningseveraldifferentbuildprocesses,andmayhavedifferenthardwareconfiguration.Thebuildprocessmayhaverequirementsregardingthespeedoftheprocessororabouttheavailablememory.Someagentmayrunsimplerbuildsforsmallerprojectsbutwouldfailtoexecutethebuildofalargeprojectorofsomesmallprojectthatstillhasahugememoryrequirementtoexecutesometests.

Whenabuildfails,thebuildserversendsoute-mailstothedevelopers,andthepersonwhosentthelastupdatetothecoderepositoryisobligatedtofixthebugwithoutdelay.Thisencouragesthedeveloperstocommitfrequently.Thesmallerthechange,thefewerchancesthereareofabuildproblem.Thebuildserverwebinterfacecanbeusedtoseetheactualstateoftheprojects,whichprojectisfailingtobuild,andwhichisjustfine.Ifabuildfails,thereisaredsigninthelineofthebuild,andifthebuildisOK,thesignisgreen.

Manytimes,thesereportsarecontinuallydisplayedonsomeoldmachineusingahugedisplaysothateverydeveloperorjustanybodywhoenterstheroomcanseetheactualstateofthebuilds.Thereisevenspecialhardwarethatyoucanbuythathasred,yellow,andgreenlampstofollowthestateofthebuildandringabellwhenthebuildfails.

Page 788:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 789:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

ReleasemanagementDevelopingsoftwaremeansacontinuouslychangingcodebase.Noteveryversionofthesoftwareissupposedtobeinstalledinproduction.Mostoftheversionsarepushedtotherepositoryonabranchhalfcomplete.Someversionsaremeantonlyfortestingandafewaremeanttobeinstalledinproductionevenifonlysomeofthosewillfinallygettoproduction.

Almostallthetime,thereleasesfollowthesemanticversioningthatwediscussedinanearliersection.Theversionsthataremeantonlytobetestedusuallyhavethe-SNAPSHOTmodifierattheendoftheversionnumber.Forexample,the1.3.12-SNAPSHOTversionistheversionthatwasoncedebugged,andisgoingtobecomethe1.3.12version.Thesnapshotversionsarenotdefiniteversions.Theyarethecodeasitisbythen.Becauseasnapshotreleasenevergetsinstalledinproduction,itisnotneededtoreproduceasnapshotversionformaintenance.Thus,thesnapshotversionsarenotincreasedcontinually.Sometimes,theymaybechanged,butthatisarareexception.

Itmaysohappenthatweworkonabugfix,1.3.12-SNAPSHOT,andduringthedevelopment,wechangesomuchcodethatwedecidethatithastobe1.4.0whenitisreleased,andwerenamethesnapshotas1.4.0-SNAPSHOT.Thisisararecase.Manytimes,thereleasecreationcreatesa1.4.0versionfrom1.3.12-SNAPSHOTasthedecisionaboutthenewreleasenumberistakenbythetimethereleaseiscreated.

Whenthereleaseprocessisstarted,usuallyfromthewebinterfaceoftheCIserver,thedevelopercreatingthereleasehastospecifythereleaseversion.Thisisusuallythesameasthesnapshotversionwithoutthe-SNAPSHOTpostfix.Thebuildprocessnotonlycreatesthebuildinthiscasebutalsotagsthesourcecoderepositoryversionitwasusingandloadsthepackagedprogram(artifact)tothecoderepository.Thetagcanbeusedlatertoaccesstheexactversionofthesourcecodethatwasusedtocreatetherelease.Ifthereisabuginaspecificversion,thenthisversionhastobecheckedoutonadevelopermachinetoreproducethebugandfindtherootcause.

Ifthebuildofareleasefails,itcanberolledback,oryoubetterjustskipthatreleasenumberandnoteitasafailedreleasebuild.Anexistingreleasecanneverhavetwoversions.Thesourcecodeistheonlyonethatisforthatreleaseandthegeneratedcodehastobeexactlytheoneinanystorage.Subsequentcompilationofthesamesourcemayresultinslightlydifferentcode,forexample,ifadifferentversionofJavaisusedtocreatethelatterone.Eveninsuchacase,theonethatwascreatedbythebuildserverinthefirstplaceistheversionthatbelongstotherelease.Whenabugisreproducedandthecodeisrecompiledfromtheexactsamesource,itisalreadyasnapshotversion.Multiplereleasesmaybepossiblefromthesamesourceversion,forexample,compiledwithJavaversionsfrom1.5to1.8andversion9butasinglereleasealwaysbelongstotheexactsamesourcecode.

IfareleasethatwassupposedtobeareleaseversionfailsduringQAchecks,thenanewreleasehastobecreatedandthefailedreleasehastobenotedassuch.Theversionthatmarketingusestonamethedifferentversionsshouldnothavearelationtothetechnicalversionnumbersweworkwith.Manytimes,itis,anditcausesmuchheadache.Ifyourealizethatthetwoaretotallydifferentthingsandonedoesnothavetodoanythingwiththeother,lifegetssimpler.LookatthedifferentversioningoftheWindowsoperatingsystemorJava.Asmarketing,Javaused1.0then1.1,butJava1.2wasadvertisedasJava2andstillthecodecontained1.2(whichnowsevenmajorreleaseslateralsobecomes9insteadof1.9)

Page 790:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Thelastpartofreleasemanagementisthatdeploymentsshouldregistertheversionnumbers.Thecompanyhastoknowwhichreleaseisinstalledonwhichserver,andofwhichclient.

Page 791:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 792:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

CoderepositoryCoderepositorystoresthelibrariesandhelpsmanagethedependenciesofthedifferentlibraries.Intheoldtimes,whenJavaprojectsusedANTasabuildtoolandwithoutthelateraddedIvydependencymanagement,thelibrariesthatwereneededbyaprojectweredownloadedtothesourcecode,usuallytotheliblibrary.Ifalibraryneededanotherlibrary,thenthosewerealsodownloadedandstoredmanually,andthiscontinueduntilallthelibrariesthatoneofthealreadydownloadedlibrariesneededwerecopiedtothesourcecodetree.

Thiswasalotofmanualworkand,also,thelibrarycodewasstoredinthesourcecoderepositoryinmanycopies.Acompiledlibraryisnotsourcecodeandhasnothingtodointhesourcecoderepository.Manualworkthatcanbeautomatedhastobeautomated.Notbecausedevelopersarelazy(yes,weareandwehavetobe)butbecausemanualworkiserrorproneand,thus,expensive.

ThiswaswhenApacheIvywasinventedandMaven,followingANT,alreadysupportedrepositorymanagementbuiltin.Theyallstoredthelibrariesstructuredindirectoriesandsupportedmetadatathatdescribedthedependenciestootherlibraries.LuckythatGradledidnotinventitsowncoderepository.Instead,itsupportsbothMavenandIvyrepositories.

Usingtherepository,thebuildtoolsautomaticallydownloadthelibrariesthatareneeded.Incasealibraryhasanewversion,thenthedeveloperonlyhastoupdatetheversionoftheneededlibraryinthebuildconfigurationandalltasks,includingdownloadingallthenewversionsoftheotherlibrariesthatareneededbythatversion,aredoneautomatically.

Page 793:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 794:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

WalkinguptheladderAtthispoint,youhavegotalotofinformationthatwillrocketyourstartasanenterpriseJavadeveloper.Youhavegotabaseknowledgethatyoucanbuildon.ThereisalongwaytobecomeaprofessionalJavadeveloper.Thereisalotofdocumentationtoread,alotofcodetoscanandunderstand,andalsoalotofcodetowritetillyoucanclaimtobeaprofessionalJavadeveloper.Youmayprobablyfacemanyyearsofcontinuouseducation.Thegoodthingisthatevenafterthat,youcancontinueyourjourneyandyoucaneducateyourself,asbeingaprofessionalJavadeveloperisrarelyajobpeopleretirefrom.No,no!Notbecausetheydiewhileatit!Rather,professionalsoftwaredevelopersgainingexperiencestarttocodelessandlessandsupportthedevelopmentprocessindifferentways,whichleveragesmoreoftheirexperience.Theycanbecomebusinessanalysts,projectmanagers,testengineers,subject-matterexperts,architects,scrummasters,automationengineers,andsoon.Isitafamiliarlist?Yes,thesearethepeopleyouwillworkwithasadeveloper.Manyofthemmayhavestartedasadeveloperthemselves.Thefollowingdiagramshowstherelativepositionoftheseroles:

Let'stakeabitmoredetailedlookintowhattheserolesperforminenterprisedevelopment:

Businessanalystsworkwiththeclientandcreatethedocuments,specifications,usecases,anduserstoriesneededbythedeveloperstodevelopthecode.Projectmanagersadministertheprojectsandhelptheteamingettingthingsdoneincooperationwithotherteams,caringforalltheprojectmattersthatdeveloperscannotattendtoorwouldunnecessarilyburntheirtimethattheyshouldhavedevotedtocoding.Subject-matterexpertsaremoreadvancedinknowingthebusinessneeds,soitisabitrareforadevelopertobecomeone,butincasetheindustryyouworkinistechnologyoriented,itmaynotbeincredibletobecomeone.TestengineerscontroltheQAprocessandunderstandnotonlythetestmethodologiesandrequirementsoftestingbutalsothedevelopmentprocesssothattheycansupportbugfixesandnot

Page 795:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

onlyidentifythem,whichwouldbepoor.ArchitectsworkwithBAsanddesignahigh-levelstructureoftheapplicationsandcode,anddocumentitinawaythathelpsthedeveloperstofocusontheactualtaskstheyhavetoperform.Architectsarealsoresponsibleforthesolutiontousetechnologies,solutions,andstructureswhichfitthepurpose,arefutureproof,affordable,andsoon.Scrummateshelpthedevelopmentteamtofollowtheagilemethodologyandhelptheteamincontrollingtheadministrationandresolvingproblems.

TherearemanywaystogoasasoftwaredeveloperandIonlylistedsomeofthepositionsthatyoucanfindinanenterprisetoday.Astechnologydevelops,Icanimaginethatin20yearsfromtoday,softwaredeveloperswillteachandcurateartificialintelligencesystemsandthatwillbewhatwerefertoasprogrammingtoday.Whocantell?

Page 796:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)
Page 797:  · 2020. 1. 22. · About the Author Peter Verhas is a senior software engineer and software architect having electrical engineering and economics background from TU Budapest (MsC)

Summary

Goinginthisdirectionisagoodchoice.BeingaJavadeveloperandbecomingaprofessionalinitisaprofessionthatwillpaywellinthecoming10to20yearsforsureandperhapsevenlater.Atthesametime,Ipersonallyfindthistechnologyfascinatingandinteresting,andaftermorethan10yearsofJavaprogrammingandmorethan35yearsofprogramming,Istilllearnsomethingnewiniteveryday.

Inthisbook,youlearnedthebasicsofJavaprogramming.Fromtimetotime,Ialsomentionedissues,suggesteddirections,andwarnedyouaboutpitfallsthatarenotJava-specific.However,wealsodidthehomeworkoflearningtheJavalanguage,theinfrastructure,thelibraries,developmenttools,andnetworkinginJava.YoualsolearnedthemostmodernapproachesthatcameonlywithJava8and9,suchasfunctionalprogramminginJava,streams,andreactiveprogramming.IfyouknowallthatIhavewritteninthisbook,youcanstartworkingasaJavadeveloper.What'snext?Go,andfindyourtreasureinprogrammingandinJava!


Recommended