OrangedeSpringàSpringBootlebuildd'unprojetavecMaven
septembre2020
sommaire
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–introduction–fichierdeconfigurationpom.xml–gestiondesdépendances–repositories–plugins–profils–architecturesdeprojets–résumédesbonnespratiques
introductionproblèmesrencontréssansMavenChaqueprojetasaproprearborescence,d'oùlanécessitédedéfinirexplicitementleprocessusdeconstructiondel'application:
Problèmesfréquentsrencontrés?
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–oùsontlessources?–quefaut-ilcompiler?–oùmettrelesexécutables?–ya-t-ildestests?Où?
–quellesdépendancesmesontréellementutiles,dansquellesversions?-souvent:copier/collergénéralàpartird'unautreprojet,ycomprisleslibrairies
–descyclesdedépendancespeuventêtrebiencachés:-classeA->classeB->classeC->classeD->classeA
–oublid'incrémenterlesversionsaucoursdelavieduprojet.
introductionsolutionsapportéesparMavenMavenestunoutild'automatisationdebuildetgestiondeprojetsJava,aucoeurduprocessusd'intégrationcontinue.
Mavens'appuiesurdesmécanismesinternesetlanotiondeconventionoverconfigurationpour:
Mavensaitcommentunprojetdoitêtreconstruit(commentcompiler,créerunjar...).
Leprojetvadéfinirquoiconstruire(uneapplicationwebwar,unelibrairiejar,lalistedesdépendancesdirectesavecleursversions...).
Parconséquent,toutpousseàadapterleprojetàMaven,plutôtquel'inverse.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–éviterunmaximumdeconfigurationpourbuilderunprojet–définiruncycledebuilddesprojets–gérernativementlesversions–centraliserleslibrairiessousformederepository–gérerlesdépendancesdirectesettransitives–intégrerdespluginspourétendresescapacités.
introductionfonctionnalités
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
introductionarborescencedesprojetsMavenimposel'arborescencedesfichiersauseind'unprojet:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
fichierdeconfigurationpom.xmlUnfichiercentralpom.xml(ProjectObjectModel)permetdedécrireunprojetMaven.
Ilvacontenir:
<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion>...</project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–l'identificateurduprojet–letypedepackagingsouhaité–despropriétés–lesdépendancesnécessaires–lespluginsnécessaires–leséventuelssous-projets(modules)–unéventuelprojetparent–...
fichierdeconfigurationpom.xmlidentificationduprojetUnprojetMavenestidentiféselon3paramètres:
ChaqueprojetMavenneproduitqu'unseulartefactnommé[artifactId]-[version].[extension].
<project...>...<groupId>com.orange.monprojet</groupId><artifactId>monprojet-consumer-jpa</artifactId><version>1.5.3</version>...</project>
Danscetexemple:monprojet-consumer-jpa-1.5.3.jar
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–groupId:familledecomposants(engénéral,deniveauprojet)–artifactId:nomducomposant–version:versionducomposant
fichierdeconfigurationpom.xmlversionsduprojetMavenimposelamiseenplaced'unegestionrigoureusedesversionsduprojet:
Lepluginreleasepermetdetageruneversion(N)-SNAPSHOTenversionrelease(N),etdepasserenversion(N+1)-SNAPSHOT.
Certainsframeworks(Spring,Hibernate...)ajoutentunsuffixe(.RELEASE,.Final...)àleursversionsrelease.
exemples:spring-core-4.1.7.RELEASE.jar,hibernate-jpa-2.1-api-1.0.0.Final.jar
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–versionsRelease:[versionmajeure].[ajoutdefonctionnalité].[correctiondebug]-uneversionreleaseestfixedansletemps
exemple:1.7.5
–versions-SNAPSHOT:[versionmajeure].[ajoutdefonctionnalité].[correctiondebug]-SNAPSHOT-uneversionsnapshotestencoursdedéveloppement-elleseraprobablementmodifiéedansletemps
exemple:1.7.6-SNAPSHOT(futureversionrelease1.7.6)
fichierdeconfigurationpom.xmlpackagingduprojetIndiquerlepackagingfinalsouhaité(lequoi)pourleprojet(war,jar...).Grâceàsesconventions,Mavensaitcommentfairepourcréerl'artefactvoulu.
<project...>...<packaging>jar</packaging>...</project>
Ilexisteuntypedepackagingparticulier(nousyreviendrons)quipermetdespécifierqueceprojetestseulementunpomtechnique(iln'yapasdecodeàcompiler,etc...).
<project...>...<packaging>pom</packaging>...</project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
gestiondesdépendances
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
gestiondesdépendancesUnedépendancereprésenteunartefactnécessaireàunprojet(généralementunelibrairiexxx.jar).
Seuleslesdépendancesdirectessontspécifiéesdansleprojet,grâceàleuridentificateur(groupId,artifactId,version).
Mavenvalestéléchargerdepuisdesdépôtspublicsouprivés,ainsiquelesdépendancestransitives.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
gestiondesdépendancesscopesdedépendancesPlusieursscopesdéfinissentl'usage,laportéed'unedépendance:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–compile(scopepardéfaut):-dépendanceutiliséepourlacompilationetl'exécution-dépendanceajoutéeauwardéployésurleserveurd'applications
–runtime:-dépendanceutiliséepourl'exécution,maispaspourlacompilation-dépendanceajoutéeauwardéployésurleserveurd'applications
–test:-dépendanceutiliséeseulementpourlestests-dépendancenonajoutéeauwardéployésurleserveurd'applications
–provided:-dépendanceutiliséepourlacompilationetl'exécution-dépendancenonajoutéeauwardéployécarfournieparleserveurd'applications
–import:-importdesdependencyManagementd'unpom.xmldansunautrepom.xml
gestiondesdépendancesSeulelesdépendancesdirectesd'unprojetsontàdéfinirdanslepom.xml.Ilfautspécifierpourchacuned'ellessongroupId,sonartifactId,saversionetsonscope(compileestfacultatifcarc'estlescopepardéfaut).
<project...>...<dependencies>...<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.30</version><scope>compile</scope></dependency>...</dependencies>...</project>
Attention:pouruneversionreleaseduprojet,ilnefautjamaisdépendredelibrairiesenversion-SNAPSHOT!
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
gestiondesdépendancespropriétésIlarrivesouventquepourunmêmeframework(parexemple),ilsoitnécessaired'ajouterplusieursdépendancesquionttouteslamêmeversion.
Ilestpossiblededéfinirdespropriétés(dontlenomdebaliseestlibre)danslepom.xml,etd'yfaireréférenceautantdefoisquel'onveutdanslepom.xml.Ainsi,ilsuffitdemodifiercettepropriétépourchangertouteslesversionsdelibrairiesd'unmêmeframework.
Ilestconseilléderegroupersousformedepropriétéstouteslesversionsdesdépendancesduprojet:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–pourmutualiserladéclarationdesversionsdecomposantsquiformentunensemblecohérent(commelesframeworks)–pouravoirunevisiond'ensembledetouteslesdépendancesdirectesutilisées.
gestiondesdépendancespropriétés<project...>...<properties><springsecurity.version>3.2.4.RELEASE</springsecurity.version>...</properties>...<dependencies><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>${springsecurity.version}</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>${springsecurity.version}</version></dependency>...</dependencies>...</project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
repositories
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
repositoriesrecherched'artefactIlestsimpled'utiliserlesidentificateursdesartefactsgérésparsonprojetcaronlesconnaît.
Commentfairepourconnaîtreceuxdeslibrairiesexternes?
exemple:MVNRepository:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–surEclipse,lepluginm2Eclipsepermetd'indexerdesrepositories–surinternet,viaunmoteurderechercheMaven.
–permetsurtoutd'obtenirlesidentificateurs(fournitureducodeàcopier/collerdanssonpom.xml)–n'hébergepaslesartefactsenquestion.
repositoriesPourquoiutiliserdesrepositories?Poursimplifierlaréutilisabilitédescomposants.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
repositoriesstockagedesartefactsDansunrepository,unartefacteststockédansunrépertoire(cheminbasésursonidentificateur)contenantplusieursfichiers:
<groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.30</version>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–l'artefactlui-même(généralementun.jar)–lessourcesdel'artefact(un.jar)–lepom.xmldel'artefact(définissantsonidentificateuretéventuellementsespropresdépendancesdirectes)–lefichierdehashage(.sha1)dechacundecesfichiers(pours'assurerdel'intégritédeleurtéléchargement).
repositories
LesdépôtssontdéfinisdanslefichierdeconfigurationMavensettings.xml.Localisationpardéfautdurepositorylocal(propriétélocalRepository):
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–sousLinux:~/.m2/repository–sousWindows:C:\DocumentsandSettings\utilisateur\.m2\repository
repositoriesinconvénientsdesdépôtsdistantssurinternetLetéléchargementdesartefactspeutêtrefastidieux:
Lesartefactspeuventneplusêtredisponiblesdansletemps.Lareproductibilitédubuildpeutnepasêtreassurée.
Certainsprojetsontbesoind'artefactspropriétairesnonprésentssurlesrepositoriespublics.
exemples:librairiesOracle...
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–débitslimités–serveursencombrés–téléchargementsnombreuxenprovenancedechaqueposteutilisantMaven
repositoriessolutionduMavenRepositoryManager2modesd'utilisation:
Avantages:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–hosted:dépôtMavenhébergeantlesartefacts(projetsetlibrairiesinternes,propriétairesettoutautreartefactMaven)dontonmaîtriselecontenu–proxy:pointesurplusieursdépôtspublicspourtéléchargeruneuniquefoislesartefactsqu'iln'hébergepasencore.
–économiedebandepassante:téléchargementuniquedesartefactsdepuislesdépôtspublics–simplificationdelaconfiguration:agrégationdetouslesdépôtspublicssousuneseuleURL–travailcollaboratif:mutualisationdesdépôtssurlegestionnaire–gaindetemps:miseàdispositionsurleréseauinternedecesartefacts(meilleurdébit)–sécurité:contrôlesd'accès.
repositoriessolutionduMavenRepositoryManager
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
repositoriesconfigurationduproxyd'entreprisePourutiliserleproxyd'entreprise,ilfautspécifier(surleposteclient)lesmiroirsappropriésdanslefichiersettings.xml,quiredirigentlesrequêtesversle(s)proxy(ies)Maven:
<mirrors>...<mirror><id>artifactory.proxy.central</id><mirrorOf>central</mirrorOf><name>ArtifactoryProxymirroringcentral(maven2)repository</name><url>renseigner_url</url></mirror>
<mirror><id>orange.central.mirror</id><name>OrangeCentralMirror</name><mirrorOf>central</mirrorOf><url>renseigner_url</url></mirror>...</mirrors>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
repositoriesgainssurlagestiondeconfigurationTraditionnellement,chaqueprojetdevaitgérerenconfiguration(git,svn...)toutesleslibrairiesqu'ilutilisepourchaqueversionduprojet.Lesmêmeslibrairiesdanslesmêmesversionset/oudansdesversionsdifférentessontdoncstockéesplusieursfoispourchaqueprojet.
Exemples:engestiondeconfigurationpourleprojet"toto":
projet"titi":idem,avecbeaucoupdelibrairiescommunesaussiauprojet"toto".
Sachantquedansuneversiondeprojet,leratiocodesource/librairiesexternesnedoitpasdépasserles5%(grandmax),onimaginel'espacedisqueénormequiestgâchépourdupliquerceslibrairiessurlesserveurs.Deplus,celanuitauxperformancesdelagestiondeconfiguration.
AvecMavenetlerepositoryd'entreprise,chaquelibrairievaêtrestockéeen1et1seulexemplaire.Leprojetnegèrequesesvraiessourcesenconfiguration(pom.xml+code).
LeslibrairiesserontrécupéréesdepuisledépôtMaven(localoud'entreprise)lorsdubuild.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–v1.0:slf4j_1.6.2,junit_4.8,spring_3.0.1_RELEASE...–v1.1:slf4j_1.6.2,junit_4.8,spring_3.2.8_RELEASE...–v2.0:slf4j_1.7.6,junit_4.8,spring_4.1.1_RELEASE...
plugins
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
pluginsextensibilitédeMavenDansMaven,toutestpluginoupresque.LenoyaudeMavennesertqu'àappelerdesplugins,quiréalisentlesactionsnécessaireslorsdubuild.
Lespluginspermettentdefairetoutcequ'onpeutfaireenJava:
Grâceauxplugins,ilestpossibledecréerdenouvellesactionsoud'adaptercellesexistantes.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–générerducode–compilerdessources–manipulerdesfichiers–créerdesrapports–manipulerlagestiondeconfiguration–lancementdeserveursd'applications–...
pluginsextensibilitédeMavenIlexistedespluginsdebase:
Beaucoupdenouveauxpluginsontétécréésparleséditeurspourrépondreàdesbesoinsparticuliers:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–compiler:compilerdessources–surefire:exécuterdestests–install:déploiementd'artefactdansunrepositoryMaven–clean:suppressiondesfichiersgénérés–...
–eclipse:générationdefichiersprojetspourEclipse–cargo:déploiement(war...)surunserveurapplicatif–swagger:générationdecodeàpartird'uneAPIjsonSwagger–cxf:générationdecodeàpartird'unWSDL–...
pluginsdéclarationdanslepom.xmlCommepourlesdépendances,lespluginssontidentifiésparles3paramètresgroupId,artifactIdetversion,etsontregroupésdansunesectiondupom.xmlquileurestpropre.
Parconvention,l'artifactIdd'unpluginestengénéraldelaformemaven-[nomPlugin]-plugin(exemple:maven-compiler-plugin).
Enlignedecommande,pourlancerunplugin,ilsuffitdetaper:mvn[nomPlugin](exemple:mvncompiler).
Deplus,ilyasouventlapossibilitédeparamétrercesplugins:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–pourpointerversunfichierparticulier–pourchangerlenommagepardéfautdespackageslorsdelagénérationdecode....
pluginsdéclarationdanslepom.xmlParexemple:
<build><plugins>...<plugin><groupId>org.springdoc</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.3</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin>...</plugins>...</build>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
pluginsgoalsUnpluginpossèdeunouplusieursgoals,quieffectuentconcrètementlesactions.
Parexemple:
maven-compiler-pluginpossède2goals:
maven-surefire-pluginpossède1goal:
Ungoalpeutêtreappelédirectementvialacommande:mvn[nomPlugin]:[nomGoal]
Exemple:mvncompiler:compile
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–compile:compilelessourcesjavadesrc/main/java–testCompile:compilelessourcesjavadetestdesrc/test/java
–test:exécutelestestsunitairesdesrc/test/java
pluginscycledevieMavendéfinitplusieurscycledevie(lifecycle)permettantd'ordonnancerdesphasesprédéfinies:
Quandondemandel'exécutiond'unephaseducycledevie(mvn[nomPhase]),touteslesphasesprécédentessontautomatiquementlancéesdanslebonordre,etdonctouslesgoalsdetouslespluginsliésàcesphaseslà.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–standard:enchaînementdesphasesliéesaubuilddel'application,pouvantvariersuivantletyped'artefactàproduire(jar,war...)–clean:suppressiondesfichiersgénérésdans/target,pournegarderquelessources–site:générationdusitewebduprojet(analysesdecode,résultatdestests...).
pluginscycledeviestandard(simplifié)
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
pluginscycledevieParexemple,lacommandemvninstallva:
Remarque:normalement,àpartirdessourcesd'unprojetMaven,ilestdoncpossibledeconstruireuneapplication,mêmesanslaconnaître.
Celaéviteleslignesdecommandesinterminablesoùtouslespluginsetleursgoalsdoiventêtrementionnés,danslebonordre:
Exemple:mvncompiler:compilecompiler:testcompilesurefire:testjar:jarinstall:install
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–récupérerleslibrairiesnécessairesàlacompilation–compilerlessources–compileretexécuterlestestsunitaires–packagerl'artéfactetledéployerdanslerepositoryMavenlocal.
pluginscycledevieAchaquephaseestassociéeunpluginpardéfaut,pourréaliserlesactions(vialesgoals)liéesàcettephase.
Lesgoalssegreffentsurlesphasesducycledevie.
Ilestpossibled'ajouterdesactionsàn'importequellephasegrâceàdesplugins(etdoncdesgoals)spécifiques.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–lelancementdelaphase2exécutelesgoalsdanscetordre:-Goal1,Goal3,Goal2
–lelancementdelaphase4exécutelesgoalsdanscetordre:-Goal1,Goal3,Goal2,Goal3
pluginscycledevieLaliaisondugoald'unpluginàunephaseducycledeviesefaitdansladéclarationduplugin,danslapartie<executions>:
<plugin>...<configuration>...</configuration><executions><execution><id>swagger-generate</id><phase>generate-sources</phase><goals><goal>generate</goal></goals></execution></executions></plugin>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–id:identifiantdelaliaison–phase:phaseducycledevie–goal:goaldupluginàappeler.
pluginsdocumentationDeuxprincipalessourcesd'informationssurlesplugins:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–lesiteofficieldeMaven,partieplugins–lesitedelafondationMojoHaus,partieplugins
pluginsdocumentationLadocumentationsurlespluginsseprésentegénéralementsouslaformedesitegénéréparMaven.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–Goals:descriptiondesdifférentsgoalsduplugin–Usage:commentutiliserleplugin–FAQ:principauxcasd'utilisationouproblèmesrencontrés–Examples:exemplesd'utilisationparticulièreoupoussée
pluginsdocumentationLesdescriptionsdespluginsetdesgoalssontdisponibleségalementenlignedecommande:mvnhelp:describe–DgroupId=[groupId]-DartifactId=[plugin]-Dversion=[version]
exemple:mvnhelp:describe-DgroupId=org.apache.maven.plugins-DartifactId=maven-compiler-plugin-Dversion=3.3
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
profils
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
profilsdéclarationdesprofilsLes<profiles>permettentdepersonnaliserunbuildselondifférentscasdefigure(environnementdedéploiementcibleparexemple).
Chaque<profile>peutsurchargerlesvaleurspardéfautdéclaréesdanslepom.xml:
<profiles><profile><id>tomcat-test</id><!--surchargedeconfiguration-->...</profile></profiles>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–desproperties–desdépendances–despluginspoursurchargerleurconfiguration–...
profilsactivationdesprofilsLorsdubuild,ilestpossibledechoisirleprofilquel'onsouhaiteactiver:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–enlignedecommande:mvncleaninstall-P<idProfile>–oudansl'IDE(dansEclipse:RunAs\Mavenbuild...).
projetsmulti-modules
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-modulesdécoupagedesprojetsSuivantlatailleetl'architecturedesprojets(ausensapplications),ilspeuventêtre(ounon)découpésenmodules,dépendantslesunsdesautres.Cesmodulespeuventêtresoit:
L'intérêtdecesmodules,c'estd'améliorerlamaintenabilitéetl'évolutivitédel'applicationenisolantdesparties.
Parexemplecelapermetdechangerlacoucheproviderd'unetechnologieversuneautre(SOAP->REST),sansavoiràretoucherleresteduprojet.
Note:danslecadredemicroservices,chaquemicroservicereprésenteunprojetMavensimpledéveloppéindépendammentdesautresmicroservices,sansutilisationdemodulesàproprementparler.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–descomposantsfonctionnels–descouchesdel'application(provider,consumer,business...)–unmélangedes2.
projetsmulti-modulesdécoupagedesprojetsPourMavenunmodule:
1projetMavenmulti-modulesestdoncuneagrégationdeplusieursmodules,définisdansunpomagrégateur,permettantd’ordonnancerlaconstructiondechaquemoduleselonleursdépendances.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–est1sous-projetMaven(chacunayantsonpom.xml)appartenantàunemêmearborescencedeprojetsMaven–produitunartefact(engénéralunjar).
projetsmulti-modulesagrégationdesmodulesLepomagrégateur:
Unefoiscesinformationsdéfiniesdanslepom.xml,Maven:
<project>...<packaging>pom</packaging>...<modules><module>moduleA</module><module>moduleB</module></modules></project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–aunpackagingdetypepom–listelesmodulesfaisantpartied'unemêmeapplication,pourlesrassemblersousunseulprojet.
–exécuteunephasedebuildsurtouslesmodules–résoutlesdépendancesentremodulespourdéterminerl'ordredebuild.
projetsmulti-modulesagrégationdesmodules
Ordredeconstructiondesmodules:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-modulesagrégationdesmodulesLagestiondesdépendances(etdesplugins)surplusieursmodulesamènecertainsinconvénients:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–uneconfigurationredondante:dépendancescommunesrépétéesdanschaquemodule–unehomogénéitédifficileàmaintenir:àchaquemodificationd'unedépendance(version...),penseràmodifierchacundespom.xmldesmodules–uneconfigurationdispersée:difficiled'avoirunevisiond'ensembledesdépendancesutiliséesparunprojet,avecleurversion(etdétecterd'éventuelsconflits).
projetsmulti-moduleshéritageentremodulesIlconvientdemutualiserdanslepomparent(ayantunpackagingdetypepom)dumoduleparentlesinformationscommunesdesdifférentsmodules,pourqueceux-cipuissentenhériter:
Lessous-modulesdoiventpréciserquelestleurparent:
<project>...<parent><groupId>com.orange.monprojet</groupId><artifactId>agregateur</artifactId><version>2.0</version><relativePath>../pom.xml</relativePath></parent>...</project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–groupId–version–lesdépendances–lespluginsetleurconfiguration–propriétés.
projetsmulti-moduleshéritageentremodules
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritageentremodules
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritageentremodules
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritageentremodules
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritagedesdépendancesDéfinirunedépendancedanslepomparentprovoque:
Orcettedépendancen'estpasforcémentnécessairedanstouslesmodules.D'ailleurs,certaineslibrairiesdevraientêtreinterditesd'utilisationsuivantlesmodules(accèsàunebasededonnéesdepuisunmoduleproviderREST...).
Pourgérerplusfinementlesdépendances,toutengardantl'avantagedelamutualisationdanslepomparent,ilexistelabalise<dependencyManagement>,quisignifieque:
Ilestimportantdecentraliserladéfinitiondesversionsdesdépendancesdanslepomparententantque<dependencyManagement>.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–sonhéritagedanstouslessous-modules–l'inclusionautomatiquedecettedépendance(jar)danslewarfinal.
–aumoinsunmoduledevraitnormalementutilisercettedépendance–chaquemodulequivoudral'utiliserdevralespécifierexplicitement(sanslaversion)–siaumoinsunmodulel'utilise,elleseraeffectivementtéléchargéeetinclusedanslewar–siaucunmodulen'enfaitlademande,elleseraignorée.
projetsmulti-moduleshéritagedesdépendancesDanslepomparent:
<project...>...<dependencyManagement><dependencies>...<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>${springdata.version}</version></dependency>...</dependencies></dependencyManagement>...</project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritagedesdépendancesLepomdumodulenereprécisequelegroupIdetl'artifactIdd'unedépendancequidoitêtredéclaréedansle<dependencyManagement>dupomparent.
Danslepom.xmldumodule:
<project...>...<dependencies>...<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId></dependency>...</dependencies>...</project>
Laversiondeladépendanceesthéritée,etdoncmutualisée.Chaquemodulequienaurabesoinutiliseralamême.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritagedesdépendances:résolutiondesconflitsParmitouteslesdépendances(directesoutransitives),ilsepeutquecertainesentrentenconflit.
Danscecas,ilestpossibledelesrésoudreenlançantdeslignesdecommandes:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–mvndependency:tree:permetdeconnaîtrel'ensembledesdépendancesdevotreprojet–mvndependency:analyze:permetderepérerlesdépendancesinutilisées–ilestpossibled'exclurelesdépendancesnonutilespourrésoudrelesconflits.
projetsmulti-moduleshéritagedesdépendances:scopeimportCescopen'estutilisablequedanslasectiondependencyManagementetpourdesdépendancesdetypepom.Ilpermetd'importerlesdependencyManagementdéfinisdansunautrepom.
<project...><groupId>com.monprojet</groupId><artifactId>monprojetA</artifactId><version>1.0.0</version><packaging>jar</packaging>
<dependencyManagement><dependencies><dependency><groupId>com.monprojet</groupId><artifactId>pomB</artifactId><version>1.0.0</version><scope>import</scope><type>pom</type></dependency></dependencies></dependencyManagement></project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritagedesdépendances:scopeimportCeprojetpomB(packagingpom)possèdeunedépendanceversspring-coreentantquedependencyManagement.CettedépendanceseraimportéedansleprojetmonprojetA.
<project...><groupId>com.monprojet</groupId><artifactId>pomB</artifactId><version>1.0.0</version><packaging>pom</packaging>
<dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.0.1.RELEASE</version></dependency></dependencies></dependencyManagement></project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritagedesdépendances:scopeimportAufinal,lesdépendancesdedependencyManagementduprojetpomBsontcopiées/colléesdanscellesduprojetmonprojetA:
<project...><groupId>com.monprojet</groupId><artifactId>monprojetA</artifactId><version>1.0.0</version><packaging>jar</packaging>
<dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.0.1.RELEASE</version></dependency></dependencies></dependencyManagement></project>
Attention:lesdependencyManagementnesontpastransitifs.
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
projetsmulti-moduleshéritagedesdépendances:notiondeBOMLeBOM(BillofMaterials)estunpomtechniquequivapermettred'exploiterlescopeimport:
L'intérêtvaapparaîtresurlesgrosprojetsoulesensemblesdeprojets.
GrâceauBOM,onpeutdéfinirplusieurspomtechniques,chacunspécialisédanscertainesfonctionnalités(etdoncnécessitantcertainesdépendances).EtchaqueprojetvapouvoirchoisirquelssontlesBOMàincluredanssesdépendances.
Celapermetd'avoirunehomogénéitédesdépendancessurungroupedeprojets(oumêmeauniveaud'uneentreprise).
SpringBoots'appuiesurceprincipe.IlfournitdesBOMspécialisésdanslagestiondesbasesdedonnées,d'autresdanslesAPIREST...
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–ilnecomportequ'unesectiondependencyManagementcentralisantlesversionsquel'onvautiliserdansleprojet–ilsertd'annuairededépendancesetleursversions.
projetsmulti-moduleshéritagedespluginsLemêmeprincipede<dependencyManagement>aétéappliquésurlespluginspourrépondreauxmêmesproblématiques,maisaveclabalise<pluginManagement>.
<project...>...<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version></plugin>...</plugins></pluginManagement>...</build>...</project>
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
bonnespratiques
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
bonnespratiquesorganisationnellesAvecunprojetMaven,ilestimportantderépartirlesrôlesdefaçonjudicieusedansunprojet:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–responsabletechnique:-garantdelasolutiontechnique,deschoixd'architectureetd'évolutions-assurelacohérencedespom.xml:cohérenceglobaledestechnologiesutiliséesetdeslicences
–développeurs:-sipossible,undéveloppeurparmodule,afind'éviterlesmergeengestiondeconfiguration-fairevalidertoutemodificationd'unpom.xml(d'unmodule,ouparent)auprèsduresponsabletechnique.
bonnespratiquesarchitecturalesSuivantletypedeprojet,leschoixd'architectureentermedeprojetMavenpeuventvarier:
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–quandutiliserunprojetsimple?-trèspetiteapplication-unseuldéveloppeur-composantutilitairetransverseauxprojets
–quandutiliserunprojetmulti-modules?-besoind'uneséparationdescouchesoudescomposants-besoind'assemblage-équipedeplusieursdéveloppeurs.
bonnespratiquesarchitecturalesEngénéral,lesprojetsoptentpourunearchitecturehiérarchique(commeexpliquéjusqu'ici):
D'autresarchitecturessontpossibles(cfannexes).
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–regroupanttoutcequialemêmecycledeviequeleprojet(entermedeversionetlivraison)–projetdepetiteoumoyennetaille–équipetravaillantsurl'intégralitéduprojet–lesmodulespeuventêtreeux-mêmesdesprojetsmulti-modules.
documentation
deSpringàSpringBoot-lebuildd'unprojetavecMaven(Orangeinternal)
–SiteMaven–SiteMojoHaus:plugins–SiteMVNRepository:recherchededépendances
merci
annexesarchitecturesdesprojetsmulti-modules
deSpringàSpringBoot-SpringFramework:lamécaniquedebase(Orangeinternal)
projetsmulti-modulesagrégationethéritageLesprojetsMavenmulti-modulesreposentdoncsur2notionsmajeures:
Laséparationdecesnotionsestpossible:
Remarque:unmodulepeutlui-mêmeêtreunprojetmulti-modules!
deSpringàSpringBoot-SpringFramework:lamécaniquedebase(Orangeinternal)
–agrégation:-pomagrégateuroupomchapeau-contientlesbalises<modules><module>...</module></modules>
–héritage:-pomparent-mutualiselesdépendancesetlespluginscommunsauxmodules-lesmoduleshéritentdupomparentvialabalise<parent>...</parent>
–pomagrégateuretpomparentpeuventêtredifférents–3architecturestypessontpossibles
-architectureàplat(cfAnnexes)-architecturehiérarchique-architecturemixte(cfAnnexes)
projetsmulti-modulesarchitectureàplat(flat)v1Avantages:
Inconvénients:
deSpringàSpringBoot-SpringFramework:lamécaniquedebase(Orangeinternal)
–mutualisationdesdépendances,despluginsetdesversionsdeAetB–buildordonné
–l'ensembledessourcesduprojetsontnécessairespourtravaillersurunmodule–architectureincompatibleaveclepluginrelease
projetsmulti-modulesarchitectureàplat(flat)v2Avantages:
Inconvénients:
deSpringàSpringBoot-SpringFramework:lamécaniquedebase(Orangeinternal)
–mutualisationdesdépendances,despluginsetdesversionsdeAetB–indépendancedudéveloppementdechaquemodule
–sidépendanceentreAetB,ordonnerlebuildmanuellement–architectureincompatibleaveclepluginrelease
projetsmulti-modulesarchitecturehiérarchique(àprivilégier)Avantages:
Inconvénients:
deSpringàSpringBoot-SpringFramework:lamécaniquedebase(Orangeinternal)
–mutualisationdesdépendances,despluginsetdesversionsdeAetB–buildordonné–utilisationpossibledupluginrelease
–l'ensembledessourcesduprojetsontnécessairespourtravaillersurunmodule
projetsmulti-modulesarchitecturemixteAvantages:
Inconvénients:
deSpringàSpringBoot-SpringFramework:lamécaniquedebase(Orangeinternal)
–mutualisationdesdépendances,despluginsetdesversionsdeAetB–utilisationpossibledupluginrelease–indépendancedudéveloppementdechaquemodule
–gestionséparéedesversionsdel'agrégateuretduparent:synchronisationmanuelle