Maven Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Maven Andrea Fornaia, Ph.D. Department of Mathematics and Computer Science University of Catania Viale A.Doria, 6 - 95125 Catania Italy fornaia@dmi.unict.it https://www.dmi.unict.it/fornaia/ A.A. 2020/2021
Compilare un progetto Java • Un progetto Java ha spesso diverse dipendenze (librerie in formato .jar), e questo può rendere la compilazione difficoltosa: – i .jar delle librerie in una data versione devono essere reperiti e scaricati in locale – il CLASSPATH deve essere modificato – il progetto può essere composto da più moduli dipendenti tra loro da compilare nel giusto ordine – La lista delle dipendenze dovrebbe essere condiviso assieme al codice sorgente • La creazione e la gestione di un progetto dovrebbe essere indipendente dall’IDE: – es. dovrei essere in grado di creare un progetto con Eclipse ed aprirlo facilmente con IntelliJ e viceversa • La compilazione di un’eseguibile (artefatto) richiede varie fasi da automatizzare quanto più possibile (pipeline): – compilazione, esecuzione test, creazione jar eseguibile… • Strumenti utili di reportistica dovrebbero poter essere aggiunti facilmente alla pipeline di compilazione: – Generazione automatica della documentazione – Misura della copertura del codice da parte dei test • Dovrebbe essere facile condividere versioni aggiornate ed eseguibili della nostra applicazione: – quando viene creata una nuova release, l’artefatto corrispondente (jar) dovrebbe essere caricato in un repository, permettendo così ad altre applicazioni, o sistemi, di ottenere facilmente la versione aggiornata
Maven • Software Project Management Tool per Java – Automatizzazione: • compilazione (con gestione dipendenze tramite file di configurazione) • testing (es. eseguiti prima del packaging) • packaging (es. creazione jar) • altro: (installazione in un repository locale, deploy in un repository remoto…) – Descrizione basata su file XML (pom.xml) – Basato su plugin per estenderne le funzionalità (es. deploy usando docker) – Utilizza repository remoto e locale (.m2) per fornire le dipendenze • Condivido il file di configurazione (pom.xml) non le librerie (jar) [https://zeroturnaround.com/rebellabs/maven-cheat-sheet/]
Maven Private Repository A pagamento, ma esiste la versoine open source: Artifactory OSS https://jfrog.com/open-source/ incluso nel repository gitlab
Artifactory OSS docker run --name artifactory -d -p 8081:8081 -p 8082:8082 docker.bintray.io/jfrog/artifactory-oss:latest Nota: non è necessario avere un repository remoto privato per poter usare Maven ma può rivelarsi un’esigenza in un contesto aziendale [https://www.jfrog.com/confluence/display/RTF6X/Installing+with+Docker]
pom.xml 4.0.0 com.example my-app 1.0-SNAPSHOT my-app UTF-8 1.8 1.8 junit junit 4.11 test
Struttura Standardizata • src: contiene tutti sorgenti e le risorse • main: per l’applicazione • java: sorgenti (packages) • resources: risorse, es. file .properties • test: per i test • java: sorgenti • resources: risorse per il testing • target: creata dopo la compilazione • classes: risultato compilazione file in main • test-classes: risultato compilazione file in test • app-1.0-SNAPSHOT.jar (dopo $ mvn package) • pom.xml: descrive dettagli del progetto (es. dipendenze, compilazione, testing)
Esempio Dipendenza: JUnit junit junit 4.11 test Repository locale
Maven risolve le dipendenze in maniera transitiva
Creare un progetto Controllare se maven è installato: $ mvn --version Creare un progetto da un template (archetype) mod. interattiva: $ mvn archetype:generate Creare un progetto da un template (archetype) mod. semi-interattiva $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 Creare un progetto da un template (archetype) mod. non interattiva $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DgroupId=com.mycompany.app -DartifactId=my-app -DinteractiveMode=false
Oppure tramite IDE (es. IntelliJ) 1 2
Altro esempio di pom.xml Riferimento ad un parent POM (implicito: Super POM) Artifact Cordinates Properties Dipendenze Dipendenze con scope (es. test) plugin per aggiungere funzionalità (goal) eseguibili su richiesta o in automatico durante una fase del lifecyle
Maven Plugin • Un plugin è un insieme di uno o più goal • Un goal è un task eseguibile (MOJO: Maven plain Old Java Object): – da command line (mvn plugin-prefix:goal) – in automatico, legandolo ad una fase del lifecycle • Tutti i progetti maven hanno dei plugin di default (core) e vengono messi a disposizione implicitamente dal Super POM • Spesso i goal hanno una fase di default a cui legarsi (es. surefire:test si lega alla fase test) • La fase a cui legarsi può essere ridefinita nel pom.xml Lista plugin del Maven Project: https://maven.apache.org/plugins/index.html (accanto: tab di VS Code)
Esempio di plugin-prefix:goal $ mvn dependency:tree - dependency è il prefix del plugin - tree è il goal messo a disposizione dal plugin nota: è un progetto Spring Boot “vuoto”…
Build lifecycle: fasi e goal • Un lifecycle è una sequenza di fasi • Ad una fase posso legare (bind) dei goal • Quando viene richiesta l’esecuzione di una fase (es. mvn test) vengono eseguite in automatico tutte le fasi precedenti nel lifecycle (es. compile) • Eseguendo una fase vengono eseguiti tutti I goal legati a quella fase (es. surefire:test) • Se invece di una fase richiedo l’esecuzione esplicita di un goal (es. surefire:test) viene eseguito solo quel goal (nota: può fallire se non ci sono le classi compilate)
Clean lifecycle: Mvn lifecycle • pre-clean — operazioni da eseguire prima del clean • clean — elimina la cartella target (risultato della compilazione precedente) • post-clean — operazioni da eseguire dopo il clean Default lifecycle (build) – riportati solo i più importanti • validate — valida il pom.xml • inizialize — es. caricamento agenti nella JVM per l’instrumentazione delle classi a runtime (code coverage) • compile — compila il codice in src, le classi vengono salvate in target/classes • test — esegue i test • package — prende il codice compilato e crea un package di distribuzione (JAR, WAR) • verify — esegue i controlli di verifica sul package, es. controlli di qualità • install — installa (copia) il package (artifact) nel repository locale ($HOME/.m2) • deploy — copia il package (artifact) nel repository remoto, se configurato (artifacts) Site lifecycle – riportati solo i più importanti • site — generazione documentazione (es. Javadoc) e reportistica (es. code coverage) • site-deploy — deploy della documentazione su un web server specificato
Esempi di comandi $ mvn clean $ mvn compile $ mvn test $ mvn test -Dtest=TestClass#testMethod $ mvn package $ mvn install $ mvn deploy $ mvn site $ mvn clean dependency:copy-dependencies package
Maven CI/CD Pipeline [https://www.bevuta.com/en/blog/continuous-delivery-with-gitlab-ci-and-ansible-part-2/]
Esempio di plugin: JaCoCo per la code coverage org.jacoco jacoco-maven-plugin 0.8.2 prepare-agent report test report $ mvn test • Esegue prepare-agent durante la fase inizialize (binding di default) • Esegue tutte le fasi fino a test (es. compile) • Esegue i test (surefire:test) e crea il report di copertura (jacoco:report)
Esempio di plugin: creare un jar-with-dependencies maven-assembly-plugin 2.6 jar-with-dependencies com.example.Main make-assembly package single $ mvn package (crea un jar eseguibile con tutte le dipendenze) $ java -jar target/my-app-1.0-SNAPSHOT.jar
Properties • Maven properties are value placeholder. • Their values are accessible anywhere within a POM by using the notation ${X}, where X is the property. • They can be used for version consistency of dependencies • Or they can be used by plugins as default values 1.8 1.8 UTF-8 UTF-8 4.11 value
Deploy configuration • Per poter usare “deploy” dobbiamo inserire nel pom.xml i riferimenti al repository • Si aggiunge il campo distributionManagement – repository: per il deploy degli artefatti di release (senza il suffisso –SNAPSHOT) – snapshotRepository: per il deploy degli artefatti di tipo snapshot (con il suffisso –SNAPSHOT) • Nell’esempio, ipotizziamo di aver creato un repository privato (es. con jfrog artifactory) su un server maven.mydomain.com my-private-repo my-private-repo-release http://maven.mydomain.com/artifactory/my-private-repo-release/ my-private-repo my-private-repo-snapshot http://maven.mydomain.com/artifactory/my-private-repo-snapshot/ • Add credentials to the $HOME/.m2/settings.xml (see next slide) • Run: mvn deploy
settings.xml: servers • The repositories for download and deployment are defined by the repositories and distributionManagement elements of the POM. • However, certain settings such as username and password should not be distributed along with the pom.xml. This type of information should exist on the build server in the $HOME/.m2/settings.xml my-user-name ************ my-private-repo ...
settings.xml: profiles • The profile element in the settings.xml can be used to set default values for all pom.xml • It consists of the activation, repositories, pluginRepositories and properties elements. • If a profile is active from settings, its values will override any equivalently ID’d profiles in a POM or profiles.xml file. • Es. this will enable profile artifactory by default for every project, adding the my-private-repo repository by default for artifacts download (the maven central repository will still be available) • This can also be activated on the command line: mvn -Partifactory ... deploy-on-my-private-repo my-private-repo my-private-repo-release http://maven.mydomain.com/artifactory/my-private-repo-release true deploy-on-my-private-repo
Multi-Modules project • Objectives: – reduce configuration duplication – build multiple projects in one shot • Maven supports inheritance from a parent pom • Each pom.xml file has an implicit parent POM called Super POM • These two files are merged by Maven and form the Effective POM • Submodules or subprojects are regular Maven projects that inherit from parent POM • To build or release our project in one shot, we have to declare our submodules explicitly in parent POM: our parent POM will be the parent as well as the aggregate POM • The reactor maven plugin will take care of multi module builds • E.g. it will find the build order for modules: if a module depends on another one, it will be built only after that module
Tutorial • Vogliamo creare un progetto con tre moduli: – parent: modulo aggregatore, contiene le configurazioni comuni sia a core che service, es. versione java da usare, dipendenza JUnit, plugin JaCoCo – core: che contiene delle funzionalità di base – service: che implementa un servizio, appoggiandosi al core come dipendenza
Creare il modulo parent e spostarsi nella cartella appena creata $ mvn archetype:generate -DgroupId=com.example -DartifactId=multi-module-parent $ cd multi-module-parent Eliminare la cartella src (non serve) ed aggiungere al pom: pom All’interno della cartella del modulo creare gli altri due moduli (nota: la stessa cosa può essere fatta con IntelliJ con File>New>Module settando opportunamente il campo Parent durante il wizard): $ mvn archetype:generate -DgroupId=com.example -DartifactId=multi-module-core $ mvn archetype:generate -DgroupId=com.example -DartifactId=multi-module-service Il plugin reactor capirà che vogliamo creare un multi-module project e modificherà automaticamente: • Il pom parent, aggiungendo i riferimenti ai moduli figli • I pom dei figli, aggiungendo il riferimento al modulo parent
Nel parent avremo: Nei figli avremo: Inoltre, nel parent avremo tutte le dipendenze in comune, così da evitarne la duplicazione nel pom dei figli: es. In questo modulo figlio (core), le dipendenze di JUnit o le proprietà sulla versione di java in uso vengono ereditate dal parent
Aggiungiamo la dipendenza dal core nel service
mvn install Nella cartella parent (multi-module-parent) eseguire mvn install Reactor capirà, in base alle dipendenze, l’ordine di compilazione da rispettare …
Riferimenti • Brian R Jackson: Maven: The Definitive Guide • https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html • https://maven.apache.org/guides/getting-started/ • https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html • https://www.baeldung.com/maven • https://www.baeldung.com/maven-multi-module • https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html • https://docs.gitlab.com/ee/user/packages/maven_repository/index.html • https://www.eclemma.org/jacoco/trunk/doc/maven.html • http://maven.apache.org/ref/3.6.3/maven-core/lifecycles.html • https://maven.apache.org/pom.html • https://maven.apache.org/settings.html • https://maven.apache.org/guides/mini/guide-multiple-repositories.html • https://stackoverflow.com/questions/24122382/how-to-configure-maven2-to-publish-to- artifactory • https://www.jfrog.com/confluence/display/RTF6X/Installing+with+Docker
Puoi anche leggere