Skip to content

3. Las herramientas del documento

Los ejemplos del documento se han probado con las siguientes herramientas:

  • NetBeans, desde la versión 6.8 hasta la 7.1.2. La instalación de NetBeans se describe en [ref3], en el apartado 1.3.1.
  • Wampserver, versión 2.2. La instalación de WampServer se describe en [ref3], en el apartado 1.3.3;
  • Maven está integrado en NetBeans. A continuación describimos esta herramienta.

3.1. Maven

3.1.1. Introducción

Maven está disponible en URL [http://maven.apache.org/index.html ]. Según sus creadores:

El objetivo principal de Maven es permitir que un desarrollador comprenda el estado completo de un proyecto de desarrollo en el menor tiempo posible. Para alcanzar este objetivo, hay varias áreas de interés que Maven intenta abordar:

  • Facilitar el proceso de compilación
  • Proporcionar un sistema de compilación uniforme
  • Proporcionar información de calidad sobre el proyecto
  • Proporcionar directrices sobre las mejores prácticas de desarrollo
  • Facilitar la migración transparente a nuevas funcionalidades

Maven está integrado en NetBeans y lo vamos a utilizar solo para una de sus funciones: la gestión de las bibliotecas de un proyecto. Estas están formadas por el conjunto de archivos jars, que deben encontrarse en el directorio Classpath del proyecto. Pueden ser muy numerosas. Por ejemplo, nuestros futuros proyectos utilizarán el ORM (mapeador objeto-relacional) Hibernate. Este ORM está compuesto por decenas de archivos jar. La ventaja de Maven es que nos libera de la necesidad de conocerlos todos. Basta con indicar en nuestro proyecto que necesitamos Hibernate, proporcionando toda la información necesaria para localizar el archivo principal de este ORM. Maven descarga entonces también todas las bibliotecas necesarias para Hibernate. A esto se le llama las dependencias de Hibernate. Una biblioteca necesaria para Hibernate puede depender a su vez de otros archivos. Estos también se descargarán. Todas estas bibliotecas se colocan en una carpeta denominada «repositorio local de Maven».

Un proyecto de Maven se puede compartir fácilmente. Si se transfiere de un equipo a otro y las dependencias del proyecto no están presentes en el repositorio local del nuevo equipo, se descargarán.

Maven se puede utilizar de forma independiente o integrado en un EDI (entorno de desarrollo integrado) como NetBeans o Eclipse.

Creemos un proyecto Maven en NetBeans:

  • En [1], crear un nuevo proyecto,
  • en [2], selecciona la categoría [Maven] y el tipo de proyecto [Java Application],
  • en [3], seleccionar la carpeta principal de la carpeta del nuevo proyecto,
  • en [4], asignar un nombre al proyecto,
  • en [5], el proyecto generado.

Analicemos los elementos del proyecto y expliquemos la función de cada uno.

  • en [1]: las diferentes ramas del proyecto:
    • [Source packages]: las clases Java del proyecto;
    • [Test packages]: las clases de prueba del proyecto;
    • [Dependencies]: los archivos .jar necesarios para el proyecto y gestionados por Maven;
    • [Test Dependencies]: los archivos .jar necesarios para las pruebas del proyecto y gestionados por Maven;
    • [Java Dependencies]: los archivos .jar necesarios para el proyecto y no gestionados por Maven;
    • [Project Files]: archivos de configuración de Maven y NetBeans,
  • en [3], la rama [Source Packages],

Esta rama contiene el código fuente de las clases Java del proyecto. NetBeans ha generado una clase por defecto:


package istia.st.mvexemple;

/**
 * Hello world!
 * 
 */
public class App {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
  • en [4], la rama [Test Packages], que contiene el código fuente de las clases de prueba del proyecto,
  • en [5], la biblioteca JUnit 3.8 necesaria para la ejecución de las pruebas,

NetBeans ha generado una clase por defecto:


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

Se trata de una prueba JUnit 3.8. Posteriormente utilizaremos pruebas JUnit 4.x.

  • En [6], la rama [Dependencies] está vacía aquí,

Esta rama muestra todas las bibliotecas necesarias para el proyecto y gestionadas por Maven. Todas las bibliotecas que aparecen aquí son descargadas automáticamente por Maven. Por eso un proyecto Maven necesita acceso a Internet. Las bibliotecas descargadas se almacenarán localmente. Si otro proyecto necesita una biblioteca que ya está presente localmente, esta no se descargará. Veremos que esta lista de bibliotecas, así como los repositorios donde se pueden encontrar, se definen en el archivo de configuración del proyecto Maven.

  • en [7], las bibliotecas necesarias para el proyecto y que no gestiona Maven,
  • en [7], el archivo [pom.xml] de configuración del proyecto Maven. POM significa «Project Object Model». Tendremos que intervenir directamente en este archivo.

El archivo [pom.xml] generado es el siguiente:


<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>
  • Las líneas 5-8 definen el objeto (artefacto) Java que va a crear el proyecto Maven. Esta información procede del asistente que se utilizó al crear el proyecto:

Un objeto Maven se define mediante cuatro propiedades:

  • [groupId]: una información que se asemeja a un nombre de paquete. Así, las bibliotecas del marco Spring tienen groupId=org.springframework, las del marco JSF tienen groupId=javax.faces,
  • [artifactId]: el nombre del objeto Maven. En el grupo [org.springframework] se encuentran, por tanto, los siguientes artifactId: spring-context, spring-core, spring-beans, ... En el grupo [javax.faces] se encuentra el artifactId jsf-api,
  • [version]: número de versión del artefacto de Maven. Así, el artefacto org.springframework.spring-core tiene las siguientes versiones: 2.5.4, 2.5.5, 2.5.6, 2.5.6.SECO1, ...
  • [packaging]: el formato que adopta el artefacto, normalmente war o jar.

Nuestro proyecto Maven generará un [jar] (línea 8) dentro del grupo [istia.st] (línea 5), denominado [mv-exemple] (línea 6) y con la versión [1.0-SNAPSHOT] (línea 7). Estos cuatro datos deben definir de forma única un artefacto de Maven.

Las líneas 17-24 enumeran las dependencias del proyecto Maven, es decir, la lista de bibliotecas necesarias para el proyecto. Cada biblioteca se define mediante cuatro datos (groupId, artifactId, versión, empaquetado). Cuando falta la información packaging, como en este caso, se utiliza el archivo JAR packaging. Se añade otra información, el «scope», que determina en qué momentos del ciclo de vida del proyecto se necesita la biblioteca. El valor por defecto es «compile», lo que indica que la biblioteca es necesaria para la compilación y la ejecución. El valor «test» significa que la biblioteca es necesaria durante las pruebas del proyecto. Este es el caso aquí con la biblioteca JUnit 3.8.1. Si esta biblioteca no está presente en el repositorio local del equipo, se descarga.

3.1.2. Ejecución del proyecto

Ejecutamos el proyecto:

En [1], se compila el proyecto Maven y, a continuación, se ejecuta [1]. Los registros de la consola de NetBeans son los siguientes:

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/seg)
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/seg)
Hello World!
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 4.040s
Finished at: Thu Jun 21 10:10:40 CEST 2012
Final Memory: 13M/122M

El resultado se encuentra en la línea 23. Se observa que, incluso en este caso sencillo, Maven ha descargado algunos elementos (líneas 17 y 20).

3.1.3. El sistema de archivos de un proyecto Maven

  • [1]: el sistema de archivos del proyecto se encuentra en la pestaña [Files],
  • [2]: los códigos fuente de Java se encuentran en la carpeta [src / main / java],
  • [3]: los códigos fuente Java de las pruebas se encuentran en la carpeta [src / test / java],
  • [4]: la carpeta [target] se crea durante la compilación del proyecto,
  • [5]: en este caso, la compilación del proyecto ha creado un archivo [mv-exemple-1.0-SNAPSHOT.jar].

3.1.4. El repositorio local de Maven

Ya hemos dicho que Maven descarga las dependencias necesarias para el proyecto y las almacena localmente. Podemos explorar este repositorio local:

  • en [1], seleccionamos la opción [Window / Other / Maven Repository Browser],
  • en [2], se abre una pestaña [Maven Repositories],
  • en [3], contiene dos ramas, una para el repositorio local y otra para el repositorio central. Este último es gigantesco. Para visualizar su contenido, hay que actualizar su índice [4]. Esta actualización dura varias decenas de minutos.
  • en [5], las bibliotecas del repositorio local,
  • en [6], encontramos una rama [istia.st] que se corresponde con el [groupId] de nuestro proyecto,
  • en [7], se accede a las propiedades del repositorio local,
  • en [8], tenemos la ruta del repositorio local. Es útil conocerla porque, en ocasiones (aunque sea raro), Maven deja de utilizar la última versión del proyecto. Realizamos modificaciones y observamos que no se tienen en cuenta. En ese caso, podemos eliminar manualmente la rama del repositorio local correspondiente a nuestro [groupId]. Esto obliga a Maven a volver a crear la rama a partir de la última versión del proyecto.

3.1.5. Buscar un artefacto con Maven

Ahora vamos a aprender a buscar un artefacto con Maven. Partamos de la lista de dependencias actuales del archivo [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>

Las líneas 17-23 definen las dependencias que vamos a modificar para utilizar las bibliotecas en su versión más reciente.

En primer lugar, eliminamos las dependencias actuales [1]. A continuación, se modifica el archivo [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></dependencies>
</project>

En la línea 17, la dependencia eliminada ya no aparece en [pom.xml]. Ahora, busquémosla en los repositorios de Maven.

  • En [1], se añade una dependencia al proyecto,
  • en [2], hay que especificar información sobre el artefacto buscado (groupId, artifactId, versión, empaquetado (tipo) y ámbito). Empezamos especificando el [groupId] [3],
  • en [4], escribimos [espace] para que se muestre la lista de artefactos posibles. Aquí aparecen [junit] y [jnit-dep]. Elegimos [junit],
  • en [5], siguiendo el mismo procedimiento, elegimos la versión más reciente. El tipo de empaquetado es jar,
  • y [6]; elegimos el ámbito «test» para indicar que la dependencia solo es necesaria para las pruebas.

En [6], las dependencias añadidas aparecen en el proyecto. El archivo [pom.xml] refleja estos cambios:


<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>

Cabe señalar que el archivo [pom.xml] no menciona la dependencia [hamcrest-core-1.1] que vemos en [6]. Esto se debe a que se trata de una dependencia de JUnit 4.10 y no del propio proyecto. Esto se indica mediante un icono diferente en la rama [Dependencies]. Se ha descargado automáticamente.

Supongamos ahora que no conocemos el [groupId] del artefacto que deseamos. Por ejemplo, queremos utilizar Hibernate como ORM (mapeador objeto-relacional) y eso es todo lo que sabemos. En ese caso, podemos ir a la página web de [http://mvnrepository.com/]:

En [1], podemos introducir palabras clave. Escribamos hibernate y iniciemos la búsqueda.

  • En [2], seleccionemos [groupId], org.hibernate y [artifactId], hibernate-core;
  • en [3], elegimos la versión 4.1.2-Final,
  • en [4], obtenemos el código Maven que hay que pegar en el archivo [pom.xml]. Lo hacemos.

<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>

Guardamos el archivo [pom.xml]. A continuación, Maven comienza a descargar las nuevas dependencias. El proyecto evoluciona de la siguiente manera:

  • a [5], la dependencia [hibernate-core-4.1.2-Final]. En el repositorio donde se ha encontrado, este [artifactId] también se describe mediante un archivo [pom.xml]. Este archivo se ha leído y Maven ha detectado que el [artifactId] tiene dependencias. También las descarga. Hará lo mismo con cada [artifactId] descargado. Al final, en el archivo [6] encontramos dependencias que no habíamos solicitado directamente. Se identifican mediante un icono diferente al del archivo principal [artifactId].

En este documento, utilizamos Maven principalmente por esta característica. Esto nos evita tener que conocer todas las dependencias de una biblioteca que queremos utilizar. Dejamos que Maven se encargue de gestionarlas. Además, al compartir un archivo [pom.xml] entre desarrolladores, nos aseguramos de que todos utilicen las mismas bibliotecas.

En los ejemplos que siguen, nos limitaremos a proporcionar el archivo [pom.xml] utilizado. El lector solo tendrá que utilizarlo para encontrarse en las mismas condiciones que el documento. Además, los proyectos Maven son compatibles con los principales entornos de desarrollo Java (Eclipse, NetBeans, IntelliJ, JDeveloper). De este modo, el lector podrá utilizar su IDE favorito para probar los ejemplos.