Organizziamoci con Maven – Parte II

Pubblicato da Gianni Amendola in Java, Tutorial

Nel precedente articolo abbiamo introdotto Apache Maven e ne abbiamo visto le basi, nonché abbiamo creato alcuni progetti. Il tutto è stato affrontato lavorando con Maven come tool da riga di comando ed effettivamente lo è…
Tuttavia abbiamo bisogno di integrare questo tool con un IDE che nel nostro caso è Eclipse. Vediamo come possiamo rendere i nostri progetti compatibili con l’IDE?
Basta semplicemente lanciare uno dei seguenti comandi nella directory principale del progetto (cioè allo stesso livello del file pom.xml):

Se si tratta di un progetto Java (cioè creato mediante il template maven-archetype-quickstart), il comando è:

mvn eclipse:eclipse

Invece se si tratta di un progetto web (cioè creato mediante il template maven-archetype-webapp), allora il comando diventa:

mvn eclipse:eclipse -Dwtpversion=2.0

A questo punto siete pronti per importare i vostri progetti su Eclipse. Per questi progetti singoli è sufficiente:

File -> Import… -> General -> Existing Projects into Workspace -> select root directory>  (select Project) -> Finish

Per importare invece progetti modulari su Eclipse le cose si complicano ed è necessaria una procedura piuttosto complessa, pertanto vi rimando a questa guida sulla documentazione ufficiale, dalla quale potete estrapolare la procedura che ci serve.
I guai non finiscono quì, infatti ci occorre un modo per eseguire i comandi (anche se possiamo farlo sempre da riga di comando). Possiamo farlo usando Maven da external tool, come descritto in questo articolo postato su mkyong.com.
Se questo vi sembra troppo oneroso per arrivare ad utilizzare Maven con il vostro IDE preferito, sappiate che esiste un plugin di Eclipse che ci semplifica notevolmente la vita. Sto parlando di…

m2e

m2e (precedentemente chiamato m2eclipse) è un plugin per sfruttare la potenza di Maven in Eclipse e senza ricorrere all’istallazione di Maven sul computer, così come abbiamo visto nell’articolo precedente.
Per disporre di m2e su Eclipse, occorre cercarlo sul marketplace ed installarlo, oppure procedere come segue:

Help → install new software -> add, aggiungo il segurnte url

http://download.eclipse.org/technology/m2e/releases

e selezionare Maven integration for Eclipse, poi Next e ancora Next fino al Finish.

Una volta istallato possiamo procedere alla creazione di un nuovo progetto con Eclipse che per ragioni di completezza sarà un progetto modulare. :)

File -> New -> Project, nel wizard per il New Project, selezioniamo Maven -> Maven Project:

Nella prima pagina del wizard selezioniamo Create a simple project e poi click su Next. Nella successiva pagina scegliamo il Group id e l’Artifact id, come nella sottostante figura. Impostiamo il valore di packaging a pom e clicchiamo su Finish.

Aggiungiamo due moduli al progetto, per primo creiamo un progetto Java: New -> Maven Module.
In questo caso impostiamo Module Name che sarà javaOnEclipse e Parent Project che sarà mavenOnEclipse. Poi ancora Next.

Nella successiva pagina selezioniamo maven-archetype-quickstart e andiamo avanti con Next

Di seguito scegliamo il Group id, l’Artifact id, versione e package come in figura. Poi clicchiamo su Finish.

Creiamo il secondo modulo, che è un progetto Web: New -> Maven Module. Il processo è analogo al precedente:
impostiamo Module Name che sarà webOnEclipse e Parent Project come il precedente mavenOnEclipse, poi avanti con Next. Nella successiva pagina selezioniamo maven-archetype-webapp e andiamo avanti con Next.
Di seguito scegliamo Group id, Artifact idversion e package impostando i medesimi valori, poi clicchiamo su Finish… E ci siamo!

Adesso dovremmo avere il nuovo progetto su Eclipse con la medesima struttura già vista per i progetti modulari con Maven, così come descritto nel precedente articolo.
Facciamo ora in modo che la web application usi il modulo Java (javaOnEclipse). Per impostare questa dipendenza fra i due moduli usiamo il comando Maven -> Add dependency disponibile nel menù contestuale del progetto web.

Sempre con questo comando possiamo aggiungere le librerie che si vogliono utilizzare di cui Maven scaricherà i jar e tutte le loro dipendenze, provvedendo poi ad aggiungerle nel classpath.

Adesso siamo pronti per lanciare tutti i goals che vogliamo, in particolare siamo pronti per compilare.
Con il tasto destro sul progetto mavenOnEclipse selezioniamo Run As ->Maven build… specificando package nel campo Goals e clicchiamo su Run.

Al termine della compilazione nella cartella target del progetto web troveremo il war pronto per essere usato, con il progetto Java già incluso nel war stesso. Esattamente come abbiamo visto per il caso di progetti modulari nell’articolo precedente.

A proposito dei progetti modulari, cambiamo completamente argomento e vediamo qualcosa di simile, cioè di un’altra tipologia di relazione tra progetti Maven. Parliamo di…

Ereditarietà

Un’altra caratteristica molto potente e unica di Maven è la possibilità di relazionare tra loro i progetti con legami di ereditarietà, un po’ come avviene con le classi Java.
In Maven l’ereditarietà permette di creare nuovi POM file che ereditano le relazioni definite in un altro POM genitore detto super POM. I progetti genitori e, come abbiamo visto, quelli esclusivamente aggregabili devono specificare il valore pom all’interno del campo packaging. Questo campo serve in generale per indicare la natura del prodotto finale: jar, war, ear, ma anche Maven-plugin, rar, etc… A meno che il valore non corrisponda a pom, nel qual caso si indicano progetti “genitore” o aggregabili.
Gli elementi ereditabili dai discendenti che si possono specificare in un POM genitore sono:

  • dipendenze
  • lista degli sviluppatori e contributori
  • esecuzioni dei plugin con id corrispondenti
  • configurazione dei plugin
  • risorse

Qualora si intenda ereditare da un altro file pom.xml le relative coordinate di questo genitore (groupId, artifactId, version), esse vanno specificate all’interno della sezione project, che dispone di un ulteriore campo non obbligatorio, denominato relativePath. Questo indica il path in cui cercare il progetto genitore specificato, prima di accedere al repository locale e a quello remoto.
Vediamo un esempio di relazione di ereditarietà (si noti che il file in questione non riporta i campi groupId e version in quanto ereditati dal POM genitore):

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>it.cosenonjaviste</groupId>
        <artifactId>Padre</artifactId>
        <version>1</version>
    </parent>
    <artifactId>Figlio</artifactId>
</project>

I POM genitore sono in grado di definire informazioni relative alle dipendenze utilizzate nei progetti discendenti, ad esempio nel definire una dipendenza da una particolare versione di log4j, dichiarata attraverso le relative coordinate (groupId, artifactId, version). Qualora si decidesse di utilizzare questa caratteristica, i file POM discendenti potrebbero limitarsi a definire, nella propria lista di dipendenze, solo il campo groupId e artifactId per log4j. La versione sarebbe invece ottenuta dal file POM genitore. E così facendo avrei un solo punto dove tenere aggiornata la versione, qualora dovesse occorrere modificarla.

Conclusioni

Come abbiamo visto, Maven fra le altre cose consente di:

  • automatizzare tutte le fasi del build
  • eseguire dei test durante il ciclo di build
  • gestire le dipendenze con efficacia
  • creare lo scheletro del progetto tramite dei template

Grazie all’elevato grado di standardizzazione globale, che Maven porta nel processo di creazione e realizzazione di un progetto, si avrà così per il progetto stesso una struttura meglio formata, piu riusabile e sicuramente più comprensibile da terzi.
Inoltre Maven incoraggia anche pratiche di sviluppo di tipo Test driven grazie al testing integrato nel processo di building.
Purtroppo Maven è un sistema piuttosto complesso che può fare tante altre cose oltre a quelle qui viste, ma la documentazione reperibile sul sito ufficiale a mio avviso non è delle migliori. E per questo, se volete approfondire l’argomento, vi suggerisco i seguenti articoli e riferimenti:

  • Ste

    Molto interessante il tutorial! Mi interesserebbe sapere se ci sia il modo, una volta creato il war, di automatizzare le fasi di deploy/publish dell’artefatto sul Tomcat integrato in eclipse. In pratica vorrei gestire con Maven il classico comando “Run as”–>”Run on server”.

    • Gianni Amendola

      Se usi Eclipse una volta compilato e creato il war puoi avviare il server proprio  con il classico “Run as”–>”Run on server”.
      Altrimenti potresti usare il plugin tomcat-maven-plugin, di seguito ti posto un link che mostra come http://www.avajava.com/tutorials/lessons/how-do-i-deploy-a-maven-web-application-to-tomcat.html

  • Roberto Simoni

    Interessante. Aggiungo che è anche possibile configurare Maven per fare TDD su codice Javascript di una webapp già esistente. Ho scritto un post a riguardo:

    http://rsimoni.blogspot.it/2012/11/configurare-maven-per-far-tdd-con.html

    • Gianni Amendola

      Molto interessante :)

  • Pingback: Maven: Site generation e reportistica, generare il sito web di un progetto con Maven e i report per analizzare il codice | Cose Non Javiste

  • Pingback: Organizziamoci con Maven – Parte I | Cose Non Javiste

  • http://www.facebook.com/filiano.d.maria Filiano Di Maria

    Ciao la guida è molto interessante e soprattutto molto chiara. Avrei comunque bisogno di un aiutino… premetto che sto utilizzando m2e. Vorrei aggiungere un repository (quello di geotool).Inserisco i tag repositories e repository, solo che non mi trova gli artifactId…credo di saltare quache passaggio. c’è una scorciatoia da eclipse?

  • Dave

    Grazie per i due articoli, sei stato molto gentile quando scrivi che la documentazione ufficiale non e’ molto chiara….. direi che e’ una chiavica! sia la 5 minuti che la 30 minuti, quel che non mi era chiaro era come definire i goal…