Skip to content

3. Strumenti utilizzati nel presente documento

Gli esempi riportati in questo documento sono stati testati con i seguenti strumenti:

  • NetBeans versioni da 6.8 a 7.1.2. L'installazione di NetBeans è descritta in [rif. 3] alla sezione 1.3.1.
  • WampServer versione 2.2. L'installazione di WampServer è descritta in [rif. 3] alla sezione 1.3.3;
  • Maven è integrato in NetBeans. Descriveremo ora questo strumento.

3.1. Maven

3.1.1. Introduzione

Maven è disponibile all'indirizzo [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 chiave che Maven affronta:

  • Semplificare il processo di compilazione
  • Fornire un sistema di compilazione uniforme
  • Fornire informazioni di qualità sul progetto
  • Fornire linee guida sulle migliori pratiche di sviluppo
  • Consentire una migrazione senza soluzione di continuità alle nuove funzionalità

Maven è integrato in NetBeans e lo useremo solo per una delle sue funzionalità: la gestione delle librerie di un progetto. Queste consistono in tutti i file JAR che devono essere nel classpath del progetto. Possono essercene un gran numero. Ad esempio, i nostri progetti futuri utilizzeranno l'ORM (Object-Relational Mapper) Hibernate. Questo ORM è costituito da dozzine di file JAR. Il vantaggio di Maven è che ci libera dal doverli conoscere tutti. Dobbiamo semplicemente specificare nel nostro progetto che abbiamo bisogno di Hibernate fornendo tutte le informazioni necessarie per individuare il file JAR principale di questo ORM. Maven scarica quindi anche tutte le librerie richieste da Hibernate. Queste sono chiamate dipendenze di Hibernate. Una libreria richiesta da Hibernate può a sua volta dipendere da altri archivi. Anche questi verranno scaricati. Tutte queste librerie vengono collocate in una cartella chiamata repository locale di Maven.

Un progetto Maven è facilmente condivisibile. Se lo trasferisci 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], seleziona la categoria [Maven] e il tipo di progetto [Java Application],
  • in [3], specificare la directory principale per il nuovo progetto,
  • in [4], assegnare un nome al progetto,
  • in [5], il progetto generato.

Esaminiamo i componenti del progetto e spieghiamo il ruolo di ciascuno di essi.

  • in [1]: i diversi rami del progetto:
    • [Pacchetti sorgente]: le classi Java del progetto;
    • [Pacchetti di test]: le classi di test del progetto;
    • [Dipendenze]: gli archivi .jar richiesti dal progetto e gestiti da Maven;
    • [Dipendenze di test]: i file .jar richiesti per i test del progetto e gestiti da Maven;
    • [Dipendenze Java]: i file .jar richiesti dal progetto e non gestiti da Maven;
    • [File di progetto]: file di configurazione di Maven e NetBeans,
  • in [3], il ramo [Pacchetti sorgente],

Questo ramo contiene il codice 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 il codice sorgente delle classi di test del progetto,
  • in [5], la libreria JUnit 3.8 necessaria per eseguire i 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);
    }
}

Questo è un test JUnit 3.8. Più avanti useremo i test JUnit 4.x.

  • In [6], la sezione [Dipendenze] è vuota qui,

Questa sezione mostra tutte le librerie richieste dal progetto e gestite da Maven. Tutte le librerie elencate qui vengono scaricate automaticamente da Maven. Questo è il motivo per cui un progetto Maven richiede l'accesso a Internet. Le librerie scaricate verranno memorizzate localmente. Se un altro progetto necessita di una libreria già presente localmente, questa non verrà scaricata. Vedremo che questo elenco di librerie, così come i repository in cui si trovano, sono definiti nel file di configurazione del progetto Maven.

  • In [7], le librerie richieste dal progetto ma non gestite da Maven,
  • in [7], il file di configurazione [pom.xml] del progetto Maven. POM è l'acronimo di Project Object Model. Dovremo modificare direttamente 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'artefatto Java che verrà creato dal progetto Maven. Queste informazioni provengono dalla procedura guidata utilizzata durante la creazione del progetto:

Un artefatto Maven è definito da quattro proprietà:

  • [groupId]: informazione simile al nome di un pacchetto. Ad esempio, le librerie del framework Spring hanno groupId=org.springframework, mentre quelle del framework JSF hanno groupId=javax.faces,
  • [artifactId]: il nome dell'artefatto Maven. Nel gruppo [org.springframework] troviamo i seguenti artifactID: spring-context, spring-core, spring-beans, ... Nel gruppo [javax.faces] troviamo l'artifactId jsf-api,
  • [version]: il numero di versione dell'artefatto Maven. Pertanto, l'artefatto org.springframework.spring-core ha le seguenti versioni: 2.5.4, 2.5.5, 2.5.6, 2.5.6.SECO1, ...
  • [packaging]: il formato dell'artefatto, più comunemente war o jar.

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

Le righe 17–24 elencano le dipendenze del progetto Maven, ovvero l'elenco delle librerie richieste dal progetto. Ogni libreria è definita da quattro informazioni (groupId, artifactId, version, packaging). Quando le informazioni sul packaging mancano, come in questo caso, viene utilizzato il packaging jar. Viene aggiunta un'altra informazione: scope, che specifica in quali fasi del ciclo di vita del progetto è necessaria la libreria. Il valore predefinito è compile, che indica che la libreria è necessaria per la compilazione e l'esecuzione. Il valore test significa che la libreria è necessaria durante il test del progetto. Questo è il caso della libreria JUnit 3.8.1. Se questa libreria non è presente nel repository locale sul computer, viene scaricata.

3.1.2. Esecuzione del progetto

Eseguiamo il progetto:

In [1], il progetto Maven viene compilato e quindi eseguito [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 at 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 at 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 è la riga 23. Possiamo notare che, anche in questo semplice caso, Maven ha scaricato alcune dipendenze (righe 17 e 20).

3.1.3. Il file system di un progetto Maven

  • [1]: Il file system del progetto si trova nella scheda [Files],
  • [2]: i sorgenti Java si trovano nella cartella [src/main/java],
  • [3]: i sorgenti di test Java si trovano nella cartella [src/test/java],
  • [4]: la cartella [target] viene creata dalla compilazione del progetto,
  • [5]: Qui, la compilazione del progetto ha creato un archivio [mv-example-1.0-SNAPSHOT.jar].

3.1.4. Il repository Maven locale

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

  • in [1], selezionare l'opzione [Finestra / Altro / Browser repository Maven],
  • in [2] si apre una scheda [Maven Repositories],
  • in [3], contiene due rami, uno per il repository locale e l'altro per il repository centrale. Quest'ultimo è enorme. Per visualizzarne il contenuto, è necessario aggiornare il suo indice [4]. Questo aggiornamento richiede diverse decine di minuti.
  • In [5], le librerie nel repository locale,
  • in [6], troverete un ramo [istia.st] che corrisponde al [groupId] del nostro progetto,
  • in [7], puoi accedere alle proprietà del repository locale,
  • in [8], vedete il percorso del repository locale. È utile saperlo perché a volte (raramente) Maven non utilizza più l’ultima versione del progetto. Apportate delle modifiche e notate che non vengono applicate. Potete quindi eliminare manualmente il ramo nel repository locale corrispondente al vostro [groupId]. Questo costringe Maven a ricreare il ramo dall’ultima versione del progetto.

3.1.5. Ricerca di un artefatto con Maven

Ora impariamo come cercare un artefatto con Maven. Iniziamo con l'elenco delle dipendenze attuali nel 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 versioni più recenti delle librerie.

Per prima cosa, rimuoviamo 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], aggiungiamo una dipendenza al progetto;
  • in [2], dobbiamo specificare le informazioni relative all'artefatto che stiamo cercando (groupId, artifactId, version, packaging (Type) e scope). Iniziamo specificando il [groupId] [3],
  • in [4], premiamo [spazio] per visualizzare l'elenco dei possibili artefatti. Qui, [junit] e [jnit-dep]. Scegliamo [junit],
  • in [5], seguendo la stessa procedura, selezioniamo la versione più recente. Il tipo di packaging è jar,
  • in [6], selezioniamo l'ambito test per indicare che la dipendenza è necessaria solo per il 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] mostrata in [6]. Questo perché si tratta di una dipendenza di JUnit 4.10 e non del progetto stesso. Ciò è indicato 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) e questo è tutto ciò che sappiamo. Possiamo quindi andare sul sito [http://mvnrepository.com/]:

In [1], è possibile inserire delle parole chiave. Digita hibernate ed esegui la ricerca.

  • In [2], selezionare [groupId] org.hibernate e [artifactId] hibernate-core,
  • In [3], selezionare 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 scarica quindi le nuove dipendenze. Il progetto si evolve come segue:

  • in [5], la dipendenza [hibernate-core-4.1.2-Final]. Nel repository in cui è stata trovata, questo [artifactId] è descritto anche da un file [pom.xml]. Questo file è stato letto e Maven ha scoperto che l'[artifactId] aveva delle dipendenze. Le scarica anche quelle. Lo farà per ogni [artifactId] scaricato. Alla fine, in [6] troviamo dipendenze che non abbiamo richiesto direttamente. Sono indicate da un'icona diversa da quella dell'[artifactId] principale.

In questo documento, utilizziamo Maven principalmente per questa funzionalità. Questo 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, ci assicuriamo che ogni sviluppatore stia effettivamente utilizzando le stesse librerie.

Negli esempi che seguono, forniremo semplicemente il file [pom.xml] utilizzato. Il lettore dovrà solo utilizzarlo per replicare le condizioni descritte nel documento. Inoltre, i progetti Maven sono supportati dai principali IDE Java (Eclipse, NetBeans, IntelliJ, JDeveloper). Pertanto, il lettore può utilizzare il proprio IDE preferito per testare gli esempi.