Maven: best practices per il processo di build e di rilascio dei progetti in Java

I parte: panoramica e filosofia d‘usodi

Dopo aver letto gli articoli dedicati alla presentazione del tool Ant, alcuni lettori potrebbero giungere all‘errata conclusione che Maven sia "solo" un altro strumento di build e/o che si tratti di una mera sostituzione di Ant. Anche se in ciò c‘è un fondo di verità, Maven è molto altro...
Maven, oltre a semplificare enormemente la gestione dei progetti, producendo grandi economie, favorisce la produzione di sistemi di maggiore qualità.

Introduzione

Obiettivo di questa serie di articoli è fornire un quadro, quanto più completo possibile, di Maven, framework di gestione dei progetti software Java rimandando poi ad altre fonti dedicate (quali, per il esempio, il relativo sito Apache cfr. [3], ed il testo di Vincent Massol e Jason Van Zyl, cfr. [5]), per trattazioni più approfondite.

Questo primo articolo è, essenzialmente, un‘introduzione di Maven corredata da un doveroso paragone con Ant, sebbene si tratti di strumenti diversi. Considerato il sempre maggiore successo che Maven sta riscuotendo è importante chiarire prima possibile di cosa si tratti, demandando poi agli articoli successivi l‘illustrazione di aspetti di maggiore dettaglio: Maven, per le diverse persone, risulta essere molte cose differenti.

Le tematiche trattate nell‘articolo saranno ulteriormente sviluppate nel capitolo 7 del libro "Java Quality Programming" [2] attualmente in preparazione e i cui primi capitoli possono già  essere scaricati dalla homepage di MokaByte.

Che cosa è Maven?

Maven, principalmente, è uno strumento completo per la gestione di progetti software Java, in termini di compilazione del codice, distribuzione, documentazione e collaborazione del team di sviluppo. Secondo la definizione ufficiale (cfr. [3]), si tratta di un tentativo di applicare pattern ben collaudati all‘infrastruttura del build dei progetti.

Si tratta di promuovere la comprensione e la produttività  del team coinvolto nello sviluppo, fornendo un percorso chiaro all‘utilizzo di best practice. Per questo motivo Maven è definito, sinteticamente, tool per la gestione e comprensione dei progetti. Maven è quindi contemporaneamente un insieme di standard, una struttura di repository e un‘applicazione che servono alla gestione e la descrizione di progetti software. Esso definisce un ciclo di vita standard per il building, il test e il deployment di file di distribuzione Java.

Nel libro "Better Builds With Maven" [5] è presente un‘interessante definizione destinata principalmente ai manager: "Maven è uno strumento dichiarativo per la gestione dei progetti Java che permette di ridurre il tempo totale di sviluppo dei progetti (time-to-market) attraverso un efficace utilizzo delle sinergie disponibili. Maven permette di ridurre il numero delle risorse umane e contemporaneamente permette di ottenere elevate efficienze operative".

Le caratteristiche di Maven fanno sଠche diverse persone, anche inizialmente estranee al progetto, possano lavorare insieme produttivamente senza dover trascorrere molto tempo per comprendere la struttura del progetto, il suo funzionamento, il processo di build, etc. Tutti coloro che si sono trovati, almeno una volta nella loro vita, a dover intervenire in progetti di grandi dimensioni in corso d‘opera, sicuramente conoscono la frustrazione causata da dover capire rapidamente l‘interazione delle varie parti del progetto, l‘ordine e le dipendenze del processo di build, etc.

Le aree prese in considerazione da Maven sono: build (sicuramente), documentazione, reportistica, gestione delle dipendenze, SCMs (Software Configuration Management), rilascio e distribuzioni di nuove versioni. In effetti tutti i progetti, indipendentemente dal loro dominio, dalla loro estensione e dalla tecnologia impiegata, presentano una serie di necessità  standard, quali ad esempio:

  • la conversione dei sorgenti in codici "eseguibili" (build)
  • la verifica (test)
  • l‘assemblaggio
  • la documentazione
  • eventualmente il "dispiegamento" e la relativa configurazione (deployment)

Breve storia di Maven

L‘idea iniziale, come spesso accade nel mondo dell‘Open Source è nata dall‘esigenza di risolvere un problema pratico, , in maniera analoga alla realizzazione di Ant. La realizzazione di Maven è partita nell‘ambito del progetto Jakarta Alexandria (attualmente abbandonato) e quindi è migrata al progetto Turbine (framework Servlet disegnato per la rapida produzione di applicazioni web). L‘obiettivo iniziale era di implementare un tool per semplificare, uniformare e automatizzare il processo di build di sistemi complessi: e quindi serviva sia creare un modello di progetto, sia una struttura di file system standard. Si doveva poi anche fare in modo che i diversi progetti Apache funzionassero in maniera analoga. Prima del rilascio di Maven, in effetti, ciascun progetto Apache, presentava differenti approcci alla compilazione, alla distribuzione e alla generazione del sito web relativo al progetto, creando evidenti problemi di allocazione delle risorse umane, di riutilizzo di script, di implementazione di best practice, e cosଠvia.

Questi problemi non erano di poco conto, visto il molto tempo frequentemente speso dagli sviluppatori per configurare i vari ambienti, per comprenderne il funzionamento e per mantenere i vari script di compilazione. Oltre a creare elementi di distrazione dal loro obiettivo principale (realizzare sistemi software di elevata qualità ), tutto ciò spesso finiva anche per far desistere nuovi potenziali collaboratori.

Dato l‘elevato livello di interdipendenza dei progetti open-source, la capacità  di Maven di standardizzare l‘ubicazione dei vari file (sorgenti, documentazione, distribuzione, etc.), di fornire una struttura comune per i vari progetti, di permettere il reperimento dei file di distribuzione attraverso un meccanismo di repository condiviso e di far sଠche il processo di build diventasse più agevole, trasparente e meno complesso, ha rappresentato un elemento chiave che ne ha assicurato il successo fin dalle prime versioni.

Già  Ant aveva risolto molti problemi relativi al processo di build; Maven permise di effettuare l‘ulteriore passo in avanti, risolvendo i rimanenti problemi presenti nello sviluppo di sistemi complessi basati su sottoprogetti interdipendenti:

  • eliminazione di diversi script di build da eseguire secondo un rigido ordine;
  • eliminazione della necessità  di copiare porzioni di file di script da un progetto a un altro (con la conseguente necessità  di doverne gestire una moltitudine);
  • rimozione della necessità  di copiare i vari file jar, soprattutto di quelli prodotti dai vari sotto-progetti;
  • risoluzione dei problemi relativi alla condivisione delle librerie (diverse versioni, mancanza di allineamento): Maven rende possibile disporre di un progetto "genitore" dal quale far ereditare sotto-progetti.

Dalla versione iniziale, Maven ha fatto molti progressi e ha contribuito enormemente a semplificare le quotidiane attività  del team di sviluppo. La versione al momento in cui viene scritto questo articolo è la 2.0.4.

Obiettivi primari di Maven

Gli obiettivi principali di Maven sono

  1. Semplificazione del processo di build dei sistemi Java. In particolare, Maven si fa carico di risolvere tutta una serie di dettagli senza ricorrere all‘utilizzo di file di script,
  2. Sviluppo di un ambiente uniforme di build. Maven gestisce progetti basati sul proprio modello a oggetti del progetto (POM, Project Object Model). Quantunque molti aspetti di Maven possano essere personalizzati, Maven dispone di una serie di "standard", studiati per essere efficacemente utilizzati per i vari progetti. Pertanto, una volta compreso il funzionamento di un progetto gestito da Maven è, si sa come gestire quasi ogni altro (a meno di forti personalizzazioni). Il che si traduce in un notevole risparmio di tempo, energie e frustrazione.
  3. Produzione di informazioni qualitative circa il progetto. Quantunque Maven non sia nà© uno strumento di documentazione nà© un generatore di siti web, rappresenta un‘ottima infrastruttura che permette di utilizzare tutta una serie di plug-in per la generazione di informazioni utili relative ai progetti. Per esempio, permette di generare documenti relativi alle variazioni effettuate (interagendo con i sistemi di source control), ai riferimenti incrociati dei sorgenti, alle mailing list, alle dipendenze, ai rapporti relativi alla copertura del codice da parte dei test, etc. Il tutto in maniera assolutamente trasparente e automatica.
  4. Erogazione di linee guida corredate da un opportuno supporto per l‘applicazione di best practice per lo sviluppo di sistemi. L‘esempio più evidente è relativo alla presenza esplicita, nel processo di build standard, della definizione, specifica ed esecuzione dei test di unità . Inoltre vi sono workflow necessari per il rilascio e la distribuzione di nuove release del sistema.
  5. Supporto alla migrazione, quanto mai trasparente, verso nuove feature.

Caratteristiche

Le principali caratteristiche offerte da Maven sono

  • setup semplificato dei progetti in rispetto alle best practices "implementate": preparare un nuovo progetto o estrapolare un modulo richiede un tempo inferiore al minuto;
  • utilizzo consistente indipendente dai singoli progetti, il che equivale a minimizzare la curva di apprendimento;
  • gestione avanzata delle dipendenze corredata da aggiornamento automatico e gestione delle dipendenze transitive (A -> B, B -> C => A -> C);
  • gestione simultanea di diversi progetti;
  • continua espansione della già  considerevole disponibilità  di plug-in, librerie e meta-dati da utilizzarsi per la gestione dei propri progetti: molti di questi elementi, inoltre, sono open-source e la relativa comunità  è molto attiva;
  • estensibilità , è possibile non solo modificare le impostazioni di default, ma anche scrivere propri plug-in;
  • immediato accesso alle nuove feature con minimo dispendio di tempo;
  • disponibilità  di task Ant per la gestione delle dipendenze e per il deployment esterno all‘ambiente Maven;
  • build basati su modello: Maven è in grado di eseguire il build di una serie di progetti e di includere le relative distribuzioni in appositi file .jar, .war etc. senza dover ricorrere ad nessuno script;
  • sito coerente di informazioni relative al progetto: a tal fine Maven utilizza gli stessi dati utilizzati dal processi di build; Maven, inoltre è in grado di generare rapporti in una serie di formati, incluso il PDF;
  • gestione del processo di rilascio di nuove versioni e pubblicazione dei file di distribuzione: ciò avviene in maniera quasi trasparente anche in presenza di sistemi di Control Managment come CVS e ClearCase;
  • gestione delle dipendenze: Maven incoraggia l‘utilizzo di repository sia locali sia remoti, per la memorizzazione dei file di distribuzione. Inoltre, dispone di una serie di meccanismi che permettono di eseguire il download, da un sito globale, di specifiche librerie richieste dal proprio progetto: questo semplifica il riutilizzo degli stessi file .jar da parte di diversi progetti, fornendo anche informazioni necessarie per gestire problemi relativi alla retrocompatibilità  (backward compatibility).

Vantaggi derivati dall‘utilizzo di Maven in un progetto

Date le caratteristiche di Maven evidenziate nei paragrafi precedenti, dovrebbero essere ormai chiari quali siano i vantaggi derivanti dall‘utilizzo nella gestione dei progetti software, specie in quelli non semplici. In particolare:

  • Coerenza: le varie organizzazioni possono standardizzare la gestione dei progetti Java utilizzando l‘insieme di best practice alla base di Maven. Accettando una serie di comodi standard, si accede a tutta una serie di servizi predefiniti. Il livello di qualità  dei vari progetti, inevitabilmente, si eleva; i progetti stessi diventano quindi più trasparenti, si minimizza il tempo necessario per comprendere i vari progetti e quindi si facilita il movimento delle risorse umane.
  • Riutilizzo: si tratta uno degli elementi alla base di Maven, il cui uso, di fatto è già  esso stesso un primo riutilizzo di best practice. Un ulteriore livello di riutilizzo è garantito dal fatto che la business logic è incapsulata in comodi moduli (plug-in);
  • Maggiore agilità : utilizzando Maven si semplifica il processo di generazione di nuovi componenti, di integrazione tra componenti, di condivisione di file eseguibili, inoltre, la curva di apprendimento di ciascun progetto viene incredibilmente ridotta, etc.
  • Semplificazione della manutenzione: non è più necessario investire tempo e risorse per manutenere gli ambienti e script di build, i quali, oltre ad essere standardizzati, sono gestiti da Maven.

I principi base di Maven

L‘idea base durante la progettazione di Maven era di creare un linguaggio condiviso per lo sviluppo di progetti software basati su Java. Ciò che Christopher Alexander (cfr.: [6]) ha formalmente definito pattern. Avere un linguaggio condiviso ad alto livello permette agli sviluppatori di trattare ad elevato livello di astrazione quei progetti la cui struttura sia fortemente standardizzata. Ne consegue una rete di comunicazioni più efficaci, una serie di servizi automatizzati e quindi un miglioramento della qualità  generale e della produttività  del progetto.

Definire un pattern per lo sviluppo dei progetti software richiedeva i seguenti principi base:

1. convenzioni sulla configurazione (convention over configuration) e in particolare:

1.1. organizzazione standard della directory dei progetti (ubicazione delle risorse del progetto, dei file di configurazione, di quelli generati, della documentazione, etc.);

1.2. definizione del vincolo base secondo cui un progetto Maven genera un solo output (file di distribuzione). Ciò porta naturalmente alla realizzazione di file pom.xml con un obiettivo limitato e ben definito, e quindi all‘applicazione del principio di separazione delle responsabilità ;

1.3. convenzione sui nomi;

2. esecuzione dichiarativa;

3. riutilizzo di logica di build;

4. organizzazione coerente delle dipendenze.

Per quanto concerne il primo punto, l‘idea base, molto semplice, è che se si accettano una serie di valide convenzioni (frutto di lungo studio ed esperienza), si ottiene una serie di vantaggi, non solo legati al fatto che lo stesso problema è già  stato ben analizzato e validamente risolto. Per esempio, se si organizza la struttura dei propri progetti in base allo standard Maven, quest‘ultimo è in grado di fornire automaticamente una serie di servizi, come la generazione dei file di progetto per i vari IDE, la compilazione automatica, etc. Quante volte si è assistito a persone che "nel tentativo di reinventare la ruota", implementavano ruote quadrate?

Maven, in più, oltre a fornire delle strategie predefinite, permette di modificarle, qualora sia proprio neceessario. Ciò, come logico attendersi, non è consiglaibile poichà© finisce per limitare molti dei benefici dello strumento.

Convention over configuration non è altro che la ripetizione di una serie di semplici regole di buon senso relative all‘applicazione di standard. In particolare, l‘applicazione di standard fa risparmiare tempo, semplifica la comunicazione, facilita il reperimento di risorse, permette di creare ulteriore valore aggiunto partendo da solide infrastrutture, permette di condividere il lavoro, e cosଠvia.

Per quanto riguarda l‘esecuzione dichiarativa (punto 2) basti dire che tutto in Maven ha una natura dichiarativa (che tuttavia, volendo, può essere alterata). L‘elemento base di Maven, il file pom.xml (la descrizione del progetto, lo vedremo nei prossimi articoli), è probabilmente l‘esempio più classico di struttura dichiarativa. A differenza di quanto avviene con Ant, con una decina di righe di carattere dichiarativo (e non procedurale), è possibile compilare, verificare, generare la documentazione e il file di distribuzione di semplici progetti.

Per quanto attiene il punto 3, Maven semplifica enormemente il riutilizzo del codice, incapsulando la business logic in appositi moduli: i plug-in, di cui esiste un insieme base (come quello per compilare, per eseguire i test, per creare file .jar, etc.) oltre a un insieme vastissimo di plug-in forniti da terze parti.

Per quanto riguarda poi l‘organizzazione coerente delle dipendenze (punto 4), questa è ottenuta attraverso una serie di meccanismi di repository. In primo luogo esiste una sezione all‘interno del file pom.xml, dedicata alla dichiarazione delle dipendenze. Una volta definita una nuova dipendenza nel pom.xml, non è necessario copiare il relativo file in un‘apposita directory del progetto, poichà© risiederà  in un repository. La presenza dei repository risolve una serie di problemi tipici concernenti l‘indicazione dei path, le diverse versioni delle librerie e cosଠvia.

Maven dispone di due tipi di repository: locale e remoto. Durante il normale funzionamento, Maven, interagisce con il repository locale; qualora però una dipendenza non sia presente all‘interno di tale repository, Maven si occupa di consultare i repository remoti ai quali ha accesso, al fine di risolvere la dipendenza mancante. Qualora non si definisca diversamente, l‘ultimo repository acceduto in ordine di tempo è il repository globale presso ibiblio (http://mirrors.ibiblio.org/pub/mirrors/maven2/). Questa consultazione serve per individuare, e quindi scaricare nei vari repository (dapprima quelli remoti e poi automaticamente in quelli locali) i file necessari per risolvere la dipendenza dichiarata (tipicamente degli archivi JAR).

Componenti principali

Nella figura 1 sono evidenziati i componenti principali di Maven. Li vedremo in dettaglio nel prossimo articolo ma ne forniamo già  una brevissima presentazione.

Figura 1 - I componenti principali di Maven.

  • File di progetto, pom.xml (POM, Project Object Model). Ã? la descrizione dichiarativa del progetto: i meta-dati del progetto. Il file di progetto include sezioni per il build, per la gestione delle dipendenze, per la gestione del progetto in generale, per i test, per la generazione della documentazione, e cosଠvia;
  • Goal: è un po‘ l‘equivalente Maven dei task Ant. In questo caso però si tratta di una funzione eseguibile che agisce su un progetto. I goal possono essere sia specifici per il progetto dove sono inclusi, sia riusabili. In termini programmativi, si può immaginare il progetto e i relativi meta-dati come le caratteristiche strutturali di un oggetto (attributi e relazioni), mentre i goal ne rappresentano le caratteristiche comportamentali, ossia i metodi che agiscono sull‘oggetto.
  • Jelly script: è un linguaggio XML di script: una sorta di combinazione tra Ant e una specie di tag JSTL non vincolate all‘ambiente servlet; Jelly script è utilizzato per descrivere i goal.
  • Plug-in: si tratta di goal riutilizzabili e cross-project.
  • Repository: si tratta di un meccanismo che permetto di memorizzare file di distribuzione. Una sorta di cartella strutturata per la gestione delle librerie; Maven permette di definire repository condivisi, remoti, e repository locali, aggiornati automaticamente dai primi.

Maven e Ant

Dalla lettura dei paragrafi precedenti e degli articoli dedicati ad Ant, dovrebbe essere chiaro che i due tool hanno diversi obiettivi e, soprattutto, un diverso livello di astrazione. Ant, essenzialmente è un tool cross-platform per il build di progetti Java, mentre Maven opera a un maggiore livello di astrazione "orchestrando" molti task Ant.

Tuttavia, giocoforza Maven finisce per "rimpiazzare" Ant nella gestione dei processi di grandi dimensioni. Si tratta tuttavia di un singolare rimpiazzamento dal momento che i "goal" Maven possono (e tipicamente lo fanno) invocare task Ant.

La tabella in figura 2 fornisce un confronto tra le principali caratteristiche dei due tool:

Figura 2 - Similitudini e differenze tra Maven e Ant.

Come evidenziato dalla figura 2, Maven utilizza Jelly (cfr. [4]). Brevemente, Jelly è un linguaggio di script basato su XML, o se si preferisce è uno strumento che permette di "trasformare tag XML in codice eseguibile". Pertanto, Jelly è sia un linguaggio di script, sia un motore di esecuzione. Ã? utilizzato in Maven come un front-end evoluto nei confronti di Ant.

Conclusioni

Questo primo articolo della serie dedicata a Maven è stato completamente dedicato a fornirne un‘iniziale introduzione. Maven è un uno strumento "intelligente" e di alto livello per la gestione dei progetti in termini di compilazione, assemblaggio, test, deployment, e cosଠvia.

Maven ed Ant possono essere confrontati, a dire il vero, in modo non molto rigoroso, dal momento che i due tool presentano una diversa natura. Ant è essenzialmente uno strumento di build, mentre Maven opera a più alto livello. Quindi, attingendo al mondo delle quattro ruote, si può dire che è come paragonare un motore con una automobile! Nonostante queste limitazioni, è importante avere una chiara visione della relazione che intercorre tra questi due validi strumenti, che presentano diverse aree di sovrapposizione.

Maven è un insieme di standard, un meccanismo di gestione delle librerie (repository), un framework. Inoltre, si tratta di un open source di grande successo, caratterizzato da una comunità  piuttosto attiva. Gli articoli successivi della serie tratteranno dettagliatamente i principali elementi di Maven.

Riferimenti

[1] Giovanni Puliti, "Ant, La Formica Operosa che beve Caffè", Mokabyte, 112 e 113.

[2] Luca Vetti Tagliati, "Java Quality Programming", capitolo 7

[3] Maven

http://maven.apache.org/

[4] Jelly

http://jakarta.apache.org/commons/jelly/

[5] Vincent Massol - Jason Van Zyl, "Better Builds With Maven", Mergere

http://www.mergere.com/m2book_download.jsp

[6] Christopher Alexander, "The Timeless Way of Building", 1979

Condividi

Pubblicato nel numero
114 gennaio 2007
Luca Vetti Tagliati ha conseguito il PhD presso il Birkbeck College (University of London) e, negli anni, ha applicato la progettazione/programmazione OO, Component Based e SOA in diversi settori che variano dal mondo delle smart card a quello del trading bancario, prevalentemente in ambienti Java EE. Dopo aver lavorato a…
Ti potrebbe interessare anche