Skip to content

3. Gli strumenti del documento

Gli esempi del documento sono stati testati con i seguenti strumenti:

  • NetBeans dalla versione 6.8 alla versione 7.1.2. L’installazione di NetBeans è descritta in [ref3] al paragrafo 1.3.1.
  • Wampserver versione 2.2. L'installazione di WampServer è descritta in [ref3] al paragrafo 1.3.3;
  • Maven è integrato in NetBeans. Descriviamo ora questo strumento.

3.1. Maven

3.1.1. Introduzione

Maven è disponibile su URL [http://maven.apache.org/index.html ]. Secondo i suoi creatori:

L'obiettivo principale di Maven è consentire a uno sviluppatore di comprendere lo stato completo di un progetto di sviluppo nel minor tempo possibile. Per raggiungere questo obiettivo, ci sono diverse aree di interesse che Maven cerca di affrontare:

  • Semplificare il processo di compilazione
  • Fornire un sistema di compilazione uniforme
  • Fornire informazioni di qualità sul progetto
  • Fornire linee guida per le migliori pratiche di sviluppo
  • Consentire una migrazione trasparente alle nuove funzionalità

Maven è integrato in NetBeans e lo useremo per una sola delle sue funzionalità: la gestione delle librerie di un progetto. Queste sono costituite dall'insieme degli archivi jars che devono trovarsi nella cartella Classpath del progetto. Possono essere molto numerose. Ad esempio, i nostri progetti futuri utilizzeranno l’Object Relational Mapper Hibernate (ORM). Questo ORM è composto da decine di archivi jar. Il vantaggio di Maven è che ci evita di doverli conoscere tutti. È sufficiente indicare nel nostro progetto che abbiamo bisogno di Hibernate, fornendo tutte le informazioni utili per individuare l’archivio principale di questo ORM. Maven scarica quindi anche tutte le librerie necessarie a Hibernate. Queste sono chiamate dipendenze di Hibernate. Una libreria necessaria a Hibernate può a sua volta dipendere da altri archivi, che verranno scaricati a loro volta. Tutte queste librerie vengono collocate in una cartella denominata repository locale di Maven.

Un progetto Maven è facilmente condivisibile. Se lo si trasferisce da un computer all’altro e le dipendenze del progetto non sono presenti nel repository locale del nuovo computer, verranno scaricate.

Maven può essere utilizzato da solo o integrato in un IDE (Integrated Development Environment) come NetBeans o Eclipse.

Creiamo un progetto Maven in NetBeans:

  • in [1], creare un nuovo progetto,
  • in [2], selezionare la categoria [Maven] e il tipo di progetto [Java Application],
  • in [3], specificare la cartella principale della cartella del nuovo progetto,
  • in [4], assegnare un nome al progetto,
  • in [5], il progetto generato.

Esaminiamo gli elementi del progetto e spieghiamo il ruolo di ciascuno.

  • in [1]: i diversi rami del progetto:
    • [Source packages]: le classi Java del progetto;
    • [Test packages]: le classi di test del progetto;
    • [Dependencies]: gli archivi .jar necessari al progetto e gestiti da Maven;
    • [Test Dependencies]: gli archivi .jar necessari per i test del progetto e gestiti da Maven;
    • [Java Dependencies]: gli archivi .jar necessari al progetto e non gestiti da Maven;
    • [Project Files]: file di configurazione di Maven e NetBeans,
  • in [3], il ramo [Source Packages],

Questo ramo contiene i codici sorgente delle classi Java del progetto. NetBeans ha generato una classe predefinita:


package istia.st.mvexemple;

/**
 * Hello world!
 * 
 */
public class App {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
  • in [4], il ramo [Test Packages] che contiene i codici sorgente delle classi di test del progetto,
  • in [5], la libreria JUnit 3.8 necessaria per l'esecuzione dei test,

NetBeans ha generato una classe predefinita:


package istia.st.mvexemple;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest extends TestCase {
    /**
     * Create the test case
     * 
     * @param testName
     *          name of the test case
     */
    public AppTest(String testName) {
        super(testName);
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite() {
        return new TestSuite(AppTest.class);
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp() {
        assertTrue(true);
    }
}

Si tratta di un test JUnit 3.8. In seguito utilizzeremo i test JUnit 4.x.

  • in [6], il ramo [Dependencies] è qui vuoto,

Questo ramo mostra tutte le librerie necessarie al progetto e gestite da Maven. Tutte le librerie qui elencate vengono scaricate automaticamente da Maven. Ecco perché un progetto Maven necessita di una connessione a Internet. Le librerie scaricate verranno archiviate in locale. Se un altro progetto necessita di una libreria già presente in locale, questa non verrà scaricata. Vedremo che questo elenco di librerie, così come i repository in cui sono disponibili, sono definiti nel file di configurazione del progetto Maven.

  • in [7], le librerie necessarie al progetto e non gestite da Maven,
  • in [7], il file [pom.xml] di configurazione del progetto Maven. POM sta per Project Object Model. Dovremo intervenire direttamente su questo file.

Il file [pom.xml] generato è il seguente:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
  • le righe 5-8 definiscono l’oggetto (artefatto) Java che verrà creato dal progetto Maven. Queste informazioni provengono dalla procedura guidata utilizzata durante la creazione del progetto:

Un oggetto Maven è definito da quattro proprietà:

  • [groupId]: un'informazione che assomiglia a un nome di pacchetto. Pertanto, le librerie del framework Spring hanno groupId=org.springframework, quelle del framework JSF hanno groupId=javax.faces,
  • [artifactId]: il nome dell’oggetto Maven. Nel gruppo [org.springframework] si trovano quindi i seguenti artifactId: spring-context, spring-core, spring-beans, ... Nel gruppo [javax.faces] si trovano artifactId e jsf-api,
  • [version]: numero di versione dell’artifact Maven. Pertanto, l'artifact org.springframework.spring-core presenta le seguenti versioni: 2.5.4, 2.5.5, 2.5.6, 2.5.6.SECO1, ...
  • [packaging]: il formato dell'artifact, solitamente war o jar.

Il nostro progetto Maven genererà un [jar] (riga 8) nel gruppo [istia.st] (riga 5), denominato [mv-exemple] (riga 6) e con versione [1.0-SNAPSHOT] (riga 7). Queste quattro informazioni devono definire in modo univoco un artefatto Maven.

Le righe 17-24 elencano le dipendenze del progetto Maven, ovvero l'elenco delle librerie necessarie al progetto. Ogni libreria è definita da quattro informazioni (groupId, artifactId, versione, packaging). Quando l’informazione packaging è assente, come in questo caso, viene utilizzato il file JAR packaging. A queste si aggiunge un’altra informazione, lo scope, che stabilisce in quali fasi del ciclo di vita del progetto è necessaria la libreria. Il valore predefinito è «compile», che indica che la libreria è necessaria sia per la compilazione che per l’esecuzione. Il valore «test» significa che la libreria è necessaria durante i test del progetto. È il caso, in questo esempio, della libreria JUnit 3.8.1. Se questa libreria non è presente nel repository locale del computer, viene scaricata.

3.1.2. Esecuzione del progetto

Eseguiamo il progetto:

In [1], il progetto Maven viene compilato e successivamente eseguito in [1]. I log nella console di NetBeans sono i seguenti:

Scanning for projects...
...

------------------------------------------------------------------------
Building mv-exemple 1.0-SNAPSHOT
------------------------------------------------------------------------

[resources:resources]
[debug] execute contextualize
Using 'UTF-8' encoding to copy filtered resources.
skip non existing resourceDirectory D:\data\istia-1112\netbeans\glassfish\mv-pam\00\mv-exemple\src\main\resources

[compiler:compile]
Compiling 1 source file to D:\data\istia-1112\netbeans\glassfish\mv-pam\00\mv-exemple\target\classes

[exec:exec]
Downloading: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.pom

Downloaded: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.pom (8 KB a 113,5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.jar

Downloaded: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.jar (49 KB a 763,6 KB/sec)
Hello World!
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 4.040s
Finished at: Thu Jun 21 10:10:40 CEST 2012
Final Memory: 13M/122M

Il risultato è alla riga 23. Si nota che anche in questo semplice caso, Maven ha scaricato alcuni elementi (righe 17 e 20).

3.1.3. Il sistema di file di un progetto Maven

  • [1]: il sistema di file del progetto si trova nella scheda [Files],
  • [2]: i sorgenti Java si trovano nella cartella [src / main / java],
  • [3]: i sorgenti Java dei test si trovano nella cartella [src / test / java],
  • [4]: la cartella [target] viene creata durante la compilazione (build) del progetto,
  • [5]: in questo caso, la compilazione del progetto ha creato un archivio denominato [mv-exemple-1.0-SNAPSHOT.jar].

3.1.4. Il repository Maven locale

Abbiamo detto che Maven scarica le dipendenze necessarie al progetto e le memorizza localmente. È possibile esplorare questo repository locale:

  • in [1], si seleziona l’opzione [Window / Other / Maven Repository Browser],
  • in [2], si apre una scheda [Maven Repositories],
  • in [3], contiene due rami, uno per il repository locale e l’altro per quello centrale. Quest’ultimo è enorme. Per visualizzarne il contenuto, è necessario aggiornare il relativo indice [4]. Questo aggiornamento richiede diverse decine di minuti.
  • in [5], le librerie del repository locale,
  • in [6], si trova un ramo [istia.st] che corrisponde al [groupId] del nostro progetto,
  • in [7], si accede alle proprietà del repository locale,
  • in [8], si ha il percorso del repository locale. È utile conoscerlo perché a volte (raramente) Maven non utilizza più l’ultima versione del progetto. Si apportano delle modifiche e si nota che non vengono prese in considerazione. È quindi possibile eliminare manualmente il ramo del repository locale corrispondente al nostro [groupId]. Questo costringe Maven a ricreare il ramo a partire dall’ultima versione del progetto.

3.1.5. Cercare un artefatto con Maven

Impariamo ora a cercare un artefatto con Maven. Partiamo dall’elenco delle dipendenze attuali del file [pom.xml]:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Le righe 17-23 definiscono le dipendenze che modificheremo per utilizzare le librerie nella loro versione più recente.

Per prima cosa, eliminiamo le dipendenze attuali [1]. Il file [pom.xml] viene quindi modificato:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies></dependencies>
</project>

Riga 17: la dipendenza rimossa non compare più in [pom.xml]. Ora cerchiamola nei repository Maven.

  • in [1], si aggiunge una dipendenza al progetto,
  • in [2], è necessario specificare le informazioni relative all’artefatto ricercato (groupId, artifactId, versione, packaging (Tipo) e ambito). Iniziamo specificando [groupId] [3],
  • in [4], digitiamo [espace] per visualizzare l'elenco degli artefatti possibili. In questo caso [junit] e [jnit-dep]. Scegliamo [junit],
  • poi [5]; procedendo allo stesso modo, scegliamo la versione più recente. Il tipo di pacchetto è jar,
  • e [6]; scegliamo l’ambito «test» per indicare che la dipendenza è necessaria solo per i test.

In [6], le dipendenze aggiunte compaiono nel progetto. Il file [pom.xml] riflette queste modifiche:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
      <type>jar</type>
    </dependency>
  </dependencies>
</project>

Si noti che il file [pom.xml] non menziona la dipendenza [hamcrest-core-1.1] che vediamo in [6]. Questo perché si tratta di una dipendenza di JUnit 4.10 e non del progetto stesso. Ciò è segnalato da un'icona diversa nel ramo [Dependencies]. È stata scaricata automaticamente.

Supponiamo ora di non conoscere il [groupId] dell’artefatto che desideriamo. Ad esempio, vogliamo utilizzare Hibernate come ORM (Object Relational Mapper) ed è tutto ciò che sappiamo. Si può quindi visitare il sito [http://mvnrepository.com/]:

In [1] è possibile digitare delle parole chiave. Digitiamo hibernate e avviamo la ricerca.

  • in [2], scegliamo [groupId], org.hibernate e [artifactId], hibernate-core,
  • in [3], scegliamo la versione 4.1.2-Final,
  • in [4], otteniamo il codice Maven da incollare nel file [pom.xml]. Procediamo.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>4.1.2.Final</version>
    </dependency>
  </dependencies>
</project>

Salviamo il file [pom.xml]. Maven avvia quindi il download delle nuove dipendenze. Il progetto si evolve come segue:

  • in [5], la dipendenza [hibernate-core-4.1.2-Final]. Nel repository in cui è stato trovato, anche questo [artifactId] è descritto da un file [pom.xml]. Questo file è stato letto e Maven ha rilevato che il file [artifactId] presentava delle dipendenze. Le scarica anch'esse. Lo farà per ogni file [artifactId] scaricato. Alla fine, nel file [6] si trovano delle dipendenze che non erano state richieste direttamente. Queste sono segnalate da un'icona diversa da quella del file principale [artifactId].

In questo documento utilizziamo Maven principalmente per questa caratteristica. Ciò ci evita di dover conoscere tutte le dipendenze di una libreria che vogliamo utilizzare. Lasciamo che sia Maven a gestirle. Inoltre, condividendo un file [pom.xml] tra gli sviluppatori, si ha la certezza che ogni sviluppatore utilizzi effettivamente le stesse librerie.

Negli esempi che seguiranno, ci limiteremo a fornire il file [pom.xml] utilizzato. Il lettore dovrà semplicemente utilizzarlo per trovarsi nelle stesse condizioni descritte nel documento. Inoltre, i progetti Maven sono supportati dai principali ambienti di sviluppo Java (Eclipse, NetBeans, IntelliJ, JDeveloper). Il lettore potrà quindi utilizzare il proprio IDE preferito per testare gli esempi.