Dopo aver dedicato l‘articolo precedente alla presentazione di una panoramica di Maven, con questo articolo si avvia la descrizione dei vari componenti a partire dalla struttura standard delle directory, denominata archetipo.
Introduzione
Abbiamo dedicato l–articolo precedente all–introduzione del framework Maven, strumento che consente di applicare pattern ben collaudati all–infrastruttura del build dei progetti, e promuove la comprensione e la produttività del team coinvolto allo sviluppo. L‘articolo di questo numero comincia a presentare i principali componenti di Maven. In particolare, l‘attenzione è focalizzata sulla struttura standard dei progetti, denominata archetype (archetipo), la quale ci permette di avviare la descrizione di alcuni comandi base di Maven.
L–archetipo di Maven
Una delle caratteristiche particolarmente apprezzate di Maven è quella di fornire un insieme di standard che rendono possibile l–applicazione di tutta una serie di “buone pratiche”. Uno di questi standard è costituito dalla struttura della directory del progetto, denominata archetype (archetipo). Coerentemente con l–impostazione di Maven, applicare tale standard non è obbligatorio, sebbene sia consigliabile: Maven fornisce una serie di strumenti che permettono di utilizzare strutture diverse e, in casi molto particolari, è anche possibile non conformarsi agli standard. Ma occorre comunque ricordare che deviare dalle impostazioni standard tende a invalidare, o comunque a ridurre, la portata di tutta una serie di vantaggi, quali quelli tipici derivanti dal fatto che si tratti di uno –standardâ?Â:
i vari servizi di Maven sono predisposti per funzionare con questa struttura e quindi nessuna ulteriore operazione è richiesta per farli funzionare;
- tale standard permette di uniformare i vari progetti presenti all–interno di un–organizzazione;
- tale struttura semplifica l–apprendimento dei progetti e quindi favorisce lo spostamento del personale;
- si evitano inutili perdite di tempo legate a discussioni relative alla struttura del progetto (“dove posizioniamo il file X ?”), alla necessità di creare nuove directory per memorizzare determinati file, e così via.
Non va dimenticato poi che ci sono vantaggi legati al fatto che l–archetipo è il risultato di un attento e prolungato studio. Quindi, invece di cercare di inventarsi l–ennesima struttura, con il rischio peraltro di ottenere risultati modesti o addirittura problematici, è decisamente più facile e conveniente beneficiare di un disegno derivante da una lunga esperienza che include anche l–uso di plug-in e di svariati tool. Pertanto, l‘utilizzo della struttura standard elimina alla radice il rischio di utilizzare un‘organizzazione delle cose poco adatta all‘uso di importanti tool di sviluppo/plug-in.
La figura 1 mostra l‘organizzazione generale della struttura Maven standard. Questa può essere creata manualmente (chiaramente non tutte le sub-directory sono necessarie e altre sono richieste da specifici plug-in) o, in alternativa, è possibile delegare questo compito direttamente a Maven. A tal fine (una volta correttamente installato Maven) è necessario eseguire il seguente comando:
mvn archetype:create -Dgroupid=com.mokabyte.finance -DartifcatId=PriceBlotter
Figura 1 – Struttura standard di Maven
I comandi Maven presentano la seguente struttura standard (figura 2):
Figura 2 – Struttura comandi Maven
L–esecuzione del comando visto in precedenza genera, essenzialmente, due azioni:
- la creazione della directory con il nome dell–applicazione (PriceBlotter), con la relativa struttura base (questa include la directory per i file sorgenti e per i corrispondente file di test);
- la generazione del file pom.xml base.
La presenza del file pom.xml nella directory principale di un progetto è il –marchioâ? che si tratta di un progetto gestito da Maven, in quanto, come vedremo nel prossimo articolo, contiene la descrizione dichiarativa del progetto.
La struttura presentata in figura 1 non dovrebbe presentare grosse novità , ma ne riportiamo una breve spiegazione onde evitare ogni possibile fraintendimento.
Nella directory principale vanno ubicati i file: pom.xml, profile.xml, LICENSE.txt e README.txt. Il primo contiene la descrizione dichiarativa del progetto, mentre profile.xml è utilizzato per definire valori che permettono di configurare diversi elementi dell–esecuzione di Maven. Questo file non dovrebbe contenere configurazioni relative a specifici progetti, nà© dovrebbe essere distribuito. Esempi di elementi che si possono trovare in questo file sono l–indirizzo del respository locale e di quello remoto, e informazioni relative all–autenticazione. I restanti due file contengono, rispettivamente, il testo della licenza e informazioni relative al progetto, utili per gli sviluppatori.
La directory src, come lecito attendersi è destinata a ospitare i file sorgenti in senso ampio. L–attenzione quindi non è limitata ai soli file Java che, una volta compilati, andranno a formare il file di distribuzione (dopo essere stati spostati nella directory target/classes), bensì include anche file di test, eventuali file di script, comandi SQL, etc.
La prima sottodirectory di src è main, destinata a ospitare i sorgenti Java (java), i file di test (test), i sorgenti scritti in eventuali altri linguaggi e la configurazione per il sito (site). Come da standard Sun, la directory src/main/java rappresenta la root dei sorgenti Java; pertanto è necessario introdurne altre necessarie per specificare in maniera univoca il progetto e i relativi file. Ciò si ottiene creando, in cascata, le seguenti directory: tipo dell‘organizzazione (com, org, etc.), l–azienda, il dipartimento, eventualmente il sotto-dipartimento, il nome del progetto, e così via (p.e. commokabytefinancepriceblotter). La directory src/main/resources memorizza eventuali file di risorse java, come per esempio i file properties, file xml, da copiare nella directory target/classes. La regola è che Maven include nel file di distribuzione tutti i file e le directory contenuti in src/main/resources con la stessa struttura con cui sono memorizzati.
La directory site contiene informazioni utilizzate per generare la documentazione relativa al progetto (a tale fine si deve utilizzare il comando mvn site) copiate nella directory target/site. Il framework utilizzato per la generazione delle informazioni è Doxia (http://maven.apache.org/doxia/book/index.html).
La directory target, infine, ospita i vari file prodotti a partire da quelli presenti nella direcory src. Per esempio, le classi Java, i JavaDoc, la documentazione del progetto, il file di distribuzione, e così via.
La compilazione: primo semplice esempio di applicazione dei principi base di Maven
Qualora si chieda a Maven di creare la directory del progetto, esso si occupa anche di generare un file pom.xml base. Questo viene inserito nella directory principale del progetto con il contenuto riportato di seguito:
4.0.2
com.mokabyte.finance
PriceBlotter
jar
1.0-SNAPSHOT
Maven Quick Start Archetype
http://maven.apache.org
junit
junit
3.8.1
3.8.1
Sebbene l–illustrazione del file pom.xml sia argomento del prossimo articolo, è importante notare che una volta specificato, in termini dichiarativi (e non implementativi come invece avviene per Ant), il contenuto del progetto, Maven è in grado di eseguire tutta una serie di compiti. Per esempio, per compilare i file sorgenti, è sufficiente eseguire il seguente comando dall–interno della directory del progetto:
mvn compile
L–esecuzione di questo comando permette di evidenziare la consistente applicazione dei quattro principi base di Maven:
- convenzione sulla configurazione;
- riutilizzo della logica di build;
- esecuzione dichiarativa;
- coerente organizzazione delle dipendenze.
Per quanto concerne il primo punto, come si può notare, non è necessario specificare tutta una serie di informazioni, quali la directory in cui sono localizzati i file sorgenti, quella in cui memorizzare i file compilati (.class), e così via. Accettando la –convenzione sulla configurazioneâ? (convention over configuration) proposta, Maven è in grado di utilizzare le impostazioni di default: file sorgenti ubicati in src/main/java, file compilati nella directory target/classes, e così via. Queste impostazioni sono memorizzate in un –super pomâ? ereditato da tutti i file pom. Quindi anche i file pom.xml più semplici ereditano automanticamente informazioni come la posizione dei vari file.
Per quanto attiene al secondo punto, la compilazione dei sorgenti è stata eseguita attraverso un plug-in standard di Maven, utilizzato in un gran numero di progetti.
L–esecuzione dichiarativa è ottenuta attraverso lo stesso file pom.xml, nel quale è dichiarato il progetto che sia l–engine di Maven, sia i vari plug-in utilizzano per la proprio esecuzione.
Per quanto riguarda la coerente organizzazione delle dipendenze, questa è ottenuta sia attraverso un–opportuna sezione specificata direttamente nel file pom.xml (dependencies), sia da alcuni meccanismi presenti all–interno di Maven stesso. Per esempio, l–esecuzione del comando di compilazione richiede l–esecuzione del relativo plug-in. Da notare che Maven, dopo essere stato installato, non possiede “nativamente” alcun plug-in: questi plug-in vengono scaricati su richiesta. Quindi, la prima volta che si richiede l–esecuzione della compilazione, Maven si occupa di scaricare il plug-in (inclusi eventualmente quelli da cui questo deriva) e quindi di eseguirlo. Per le volte successive, chiaramente, è possibile eseguire direttamente il plug-in senza ulteriori operazioni.
I comandi base di Maven
La tabella di figura 3 riporta un quadro riassuntivo dei principali comandi di Maven, con una breve spiegazione.
Figura 3 – Comandi base di Maven
Conclusioni
In questo articolo si è avviata la descrizione di uno dei componenti principali di Maven: l‘archetipo. Si tratta della struttura standard della directory per i progetti Java e non solo. La presenza di questa struttura, oltre a eliminare alla base una serie di discussioni poco costruttive (dove ubicare i file X, dove inserire i file Y, come produrre i file di distribuzione, e così via), permette di accedere a una base conoscitiva sviluppatasi in anni di realizzazione di importanti progetti. Questa esperienza, maturata negli ambienti Apache, tiene conto di molti fattori, come l‘utilizzo di plug-in, di tool, etc. Ciò fa si che si eliminino alla base, o quantomeno si minimizzino, problemi di incompatibilità nell‘utilizzo di IDE, tools, e pug-in.
Pertanto, anche qualora non si intenda utilizzare Maven, è fortemente consigliato tenere in considerazione l‘archetipo proposto.
Riferimenti
[1] Luca Vetti Tagliati, –Java Quality Programmingâ?Â
[2] Maven
http://maven.apache.org/
[3] Jelly
http://jakarta.apache.org/commons/jelly/
[4] Vincent Massol – Jason Van Zyl, –Better Builds With Mavenâ?Â, Mergere http://www.mergere.com/m2book_download.jsp
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 lungo nella City di Londra per le più importanti banche di investimento (Goldman Sachs, Lehman, Deutsche Bank, UBS, HSBC) ricopre attualmente l'incarico di Senior Lead Global Architect per importanti gruppi bancari nel sud della Svizzera. Ha collaborato attivamente con John Daniels (coautore del libro "UML components") e Frank Armour (coautore del libro "Advanced Use Case Modeling"). È autore del libro "UML e ingegneria del software", pubblicato nel 2003 da HOPS/Tecniche Nuove, di "Java Best Practice: i migliori consigli per scrivere codice di qualità", pubblicato nel 2008 dal medesimo editore, e dell'ebook "Verso Java 8. Appunti per lo sviluppatore in Java SE 7" pubblicato da MokaByte e scaricabile dal nostro sito. È stato invitato a Los Angeles e Boston per presentare i suoi paper in convegni inerenti Software Engineering & Architecture. Nel 2015 ha ricevuto il prestigioso ICMG Award.