Maven Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict

Pagina creata da Lorenzo Sacco
 
CONTINUA A LEGGERE
Maven Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
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
Maven Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
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 Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
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 Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
Maven Central Repository
Maven Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
Maven Private Repository

                    A pagamento, ma esiste la
                      versoine open source:
                          Artifactory OSS
                 https://jfrog.com/open-source/

                           incluso nel
                        repository gitlab
Maven Andrea Fornaia, Ph.D - Department of Mathematics and Computer Science University of Catania - DMI Unict
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