Iniciarse con Maven

Diciembre 2016


Maven es una herramienta de gestión de proyectos Java y Java EE, permite particularmente:
  • Crear una arborescencia estándar del código y de sus recursos.
  • Descargar, actualizar y configurar las bibliotecas necesarias para el proyecto.
  • Compilar el proyecto, efectuar pruebas unitarias sobre el código y empaquetar el resultado.

Advertencia: La utilización de Maven requiere un acceso a Internet así como espacio en el disco para conservar los archivos descargados.

El programa Maven es open source, está disponible gratuitamente en el sitio oficial de la fundación Apache bajo los nombres "binary.zip" para Windows y "binary.tar.gz" para Unix.

Una vez descargado, descomprima el contenido del archivo en un directorio del sistema ("C:\Program Files\Apache" por ejemplo), debes luego configurar la variable de entorno MAVEN_HOME correspondiente a este directorio y añadir el subdirectorio "\bin" a la variable de entorno PATH.

Si no instalaste JDK para editar el código Java, es el momento de hacerlo ingresando al sitio oficial de Java SE Development Kit 7 Downloads.

También debes configurar la variable JAVA_HOME que corresponde al directorio de instalación del JDK, así como añadir el directorio "\bin" a la variable de entorno PATH.

En resumen, deberías tener tres variables de entorno, con estos valores por ejemplo

JAVA_HOME   C:\Program Files\Java\jdk1.7.0_25
MAVEN_HOME  C:\Program Files\Apache\maven-3.1.0
PATH        %JAVA_HOME%\bin;%MAVEN_HOME%\bin;%PATH%


Para verificar que todo está bien instalado, puedes abrir una interfaz de línea de comandos y escribir:

mvn --version

Esto generará una visualización más o menos como esto, describiendo su configuración:

Apache Maven 3.1.0 (2013-06-28 04:15:32+0200)
Maven home: C:\Program Files\Apache\maven-3.1.0\bin\..
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.7.0_25\jre
Default locale: fr_FR, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

Para hacerlo simple vamos a crear un proyecto "Hello World" con Maven y a desmenuzar su funcionamiento. Crea para esto un directorio dedicado (la ubicación no tiene ninguna importancia).

Abre una interfaz de línea de comandos y desplázate hasta la carpeta que acabas de crear. A continuación vamos a explicarlo paso a paso.

Generación del archetype


Por el momento tenemos una carpeta vacía, vamos a pedirle a Maven crear solo (o casi) un proyecto de base ingresando el siguiente comando:

mvn archetype:generate

Maven debería conectarse al http://repo.maven.apache.org/ depósito central y comenzar a descargar un gran número de archivos POM (proyecto Object Model) y JAR (Java ARchiver) que te son útiles. Estos luego serán almacenados por defecto en la carpeta "Mis Documentos" en un directorio nombrado ".m2". Almacenando estos archivos en el disco duro, Maven ya no necesitará cargarlos en la próxima utilización y directamente irá a consultarlos en el directorio local.

Si trabajas en una empresa o una universidad por ejemplo, ésta posiblemente está equipada de un depósito de empresa que almacena en un servidor todos los archivos descargados por Maven en de la red y los redistribuye a los usuarios que lo necesitan sin tener que volver a pasar por el depósito central (salvo en un primer uso) lo que permite acelerar el acceso a los archivos.

Tus descargas deberían ahora terminar y Maven debe indicarte que va a generar el proyecto en modo interactivo.

Es decir que va a plantearte un cierto número de preguntas a las que es necesario responder, la mayoría de las veces entre una lista de elección.

Primera pregunta: escoger el tipo de proyecto. Aquí Maven propone varios cientos de tipos de modelos diferentes, he aquí un ejemplo de la visualización de las últimas líneas que podrías tener:

823: remote -> ru.nikitav.android.archetypes:release (-)
824: remote -> ru.nikitav.android.archetypes:release-robolectric (-)
825: remote -> se.vgregion.javg.maven.archetypes:javg-minimal-archetype (-)
826: remote -> sk.seges.sesam:sesam-annotation-archetype (-)
827: remote -> tk.skuro:clojure-maven-archetype (A simple Maven archetype for Clojure)
828: remote -> uk.ac.rdg.resc:edal-ncwms-based-webapp (-)

Elige un número o apply filter (formato: [groupId:] artifactId, compartimiento sensitivo contains): 294:

Las líneas 1 a 828 son todas las elecciones posibles de proyectos.

Observación: la lista de los proyectos puede variar en el transcurso del tiempo entonces posiblemente no tendrá 828, pero esto no tiene ninguna importancia. Aquí únicamente vamos a interesarnos por la elección por defecto propuesto (294 en este ejemplo). Esta es su descripción:
294: remote -> org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project.)


Entremos este valor por defecto con el fin de ordenar a Maven utilizar el archetype "quickstart".

Enseguida aparece la segunda pregunta que concierne a la versión del archetype que queremos utilizar. Allí todavía vamos a tomar el valor por defecto que corresponde en general a la última versión estable. Maven puede entonces descargar el proyecto. Pero hay que personalizarlo.

La pregunta siguiente es sobre el "groupId" que se trata del nombre de tu grupo, por ejemplo el de Maven es "org.apache.maven", aquí puedes poner lo que quieres a condición de respetar la sintaxis esperada, es decir letras minúsculas, sin acento ni espacio separados por puntos. Para el ejemplo voy a poner "org.ccm.maven".

Luego aparece el "artifactId", se trata simplemente del nombre del proyecto, pondría aquí "helloworld".

La pregunta siguiente es sobre la versión del proyecto. Maven utiliza mucho los números de versiones, pues es importante comprender que cada vez que generarás tu proyecto Maven, su número de versión es susceptible de ser incrementado. Precisando que se trata de una versión "snapshot" nos aseguramos que el proyecto será bien considerado como el que estará en proceso de desarrollo y cuya versión no será incrementada. Dejemos entonces este valor por defecto "1.0-SNAPSHOT".

Viene por fin la pregunta del package del proyecto, por defecto Maven propone el mismo nombre que para el groupId, "org.ccm.maven".

Aparece un pequeño resumen y una solicitud de confirmación con un "Y". Listo habrás creado tu primer proyecto Maven.

Observación: habría sido posible obtener el mismo resultado sin pasar por el modo interactivo, en este caso hay que precisar los diferentes parámetros obligatorios, Maven completa los parámetros que faltan con los valores por defecto. Lo que da:

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=org.ccm.maven -DartifactId=helloworld -DinteractiveMode=false

Arborescencia del proyecto


He aquí la arquitectura del proyecto como la generada con "maven-archetype-quickstart" y los valores de la configuración pasada en modo interactivo:

helloworld
| pom.xml
| src
| | main
| | | java
| | | | org
| | | | | ccm
| | | | | | maven
| | | | | | | App.java
| | test
| | | java
| | | | org
| | | | | ccm
| | | | | | maven
| | | | | | | AppTest.java

Tenemos 12 carpetas y 3 archivos, cuyo detalle:

helloworld/src/main/java/org/ccm/maven/App.java:

package org.ccm.maven;

/××
 × Hello world!
 ×/
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

Nada complicado hasta aquí, Maven nos completó fácilmente el código de un clásico Hello World.

helloworld/src/main/java/org/ccm/maven/App.java:

package org.ccm.maven;

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 );
    }
}

Aquí es un poco más complicado si no conoces a JUnit, se trata de una clase de prueba unitaria, esto permite hacer automáticamente algunas comprobaciones después de cada compilación para asegurarse que las modificaciones aportadas al código no perturban lo que ya funcionaba.

Observación: la prueba verifica simplemente que true vale true, lo que es evidentemente correcto.

Finalmente, he aquí el corazón de Maven, que contiene toda la configuración del proyecto:

helloworld/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>org.ccm.maven</groupId>
  <artifactId>helloworld</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>helloworld</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>

Encontramos particularmente los diferentes valores que configuramos, así como las dependencias en JUnit para permitir hacer las pruebas. Configurando esta dependencia en el pom, Maven sabe que deberá ir a descargar la biblioteca de JUnit y a asociarlo al proyecto con el fin de que funcione. No tienes que instalarlo.

También podemos ver la etiqueta de packaging, que es un jar. Esto significa que después de compilación el código será archivado en un archivo JAR.

Sin embargo, falta una pequeña cosa, en efecto este jar no es ejecutable. Por lo tanto, vamos a añadir el punto de entrada copiando este bloque en el pom.xml (por ejemplo entre el url y las propiedades).

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>org.ccm.maven.App</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>

Compilación y ejecución del programa


Ahora que nuestro código fuente está completo y que la configuración del proyecto está terminada, vamos a poder pedirle a Maven construir el proyecto. Para esto abre una interfaz de línea de comandos en la carpeta "helloworld" y entra este comando:
mvn package

Esto va a provocar diferentes acciones, como la validación del proyecto (que va particularmente a descargar todos los archivos que podrían faltar), la compilación del proyecto, la ejecución de las pruebas unitarias y la creación de los archivos jar.

Nota: si una de estas etapas es suspendida, entonces las siguientes no serán ejecutadas.

Una nueva carpeta apareció en su directorio helloworld, se trata de "target", ésta contiene las clases compiladas (en "classes" para el programa y "test-classes" para las pruebas unitarias), los informes de tests ("surefire-reports"), así como el archivo "helloworld-1.0-SNAPSHOT.jar" y propiedades de compilación (en "maven-archiver").

Puedes ahora lanzar el programa el comando:


java -jar target/helloworld-1.0-SNAPSHOT.jar



El resultado será como el previsto: Hello World!

Información adicional

  • La descripción del proyecto mediante el archivo "pom.xml" permite particularmente librarse de la instalación de las dependencias. Si quieres transferir tu proyecto de una máquina a otra, hay que sólo copiar las fuentes del proyecto. La regeneración del proyecto se hará entonces de manera idéntica sin problema de configuración.
  • Una vez que la compilación y el packaging haya terminado, Maven puede desplegar la aplicación directamente en el servidor y hacer pruebas de integridad con el fin de verificar que cohabita bien con otras aplicaciones de su entorno.
  • Maven es soportado por Eclipse y Netbeans, por lo tanto podrás ingresar a la interfaz de comandos y encontrar las funcionalidades de Maven directamente en tu IDE preferido.
  • "Ant" es un proyecto similar a Maven. Pueden encontrarse a veces asociados.

Consulta también :
El documento «Iniciarse con Maven» de CCM (es.ccm.net) se encuentra disponible bajo una licencia Creative Commons. Puedes copiarlo o modificarlo siempre y cuando respetes las condiciones de dicha licencia y des crédito a CCM.