Maven
Maven se encarga de gestionar y construir proyectos Java (Parafraseando a la Wikipedia, donde tienes toda la historia e información ampliada en español en http://es.wikipedia.org/wiki/Maven). Aquí no te lo voy a contar en formato enciclopedia (para eso está el artículo que te indiqué en la Wikipedia), sino que te daré toda una formación completa acelerada sobre Maven y ejemplos de su uso para que no te tengas que creerte nada, sino que lo puedas probar en el tiempo que tardes en leerte únicamente este artículo (no mires la diminuta barra de scroll, que casi todo son imágenes y una vez que lo entiendas tardarás cinco minutos en hacer esto 😉 ).
Hay quién llama a Maven como “Gestor de dependencias” (es decir, gestiona bibliotecas). No es del todo correcto, ya que es tan solo una de sus herramientas (es como decir que Eclipse es “un editor de texto”; lo es, pero también compila, ejecuta, tiene muchos botones que hacen cosas, etc). Maven hace mucho más que únicamente actuar de “Gestor de dependencias”. Algunas son:
- Construye nuestro código del proyecto (build)
- Ejecuta las pruebas (testing)
- Trabaja de gestor de dependencias: nos importa automáticamente las bibliotecas desde un repositorio remoto ¡Se acabó el importarlas manualmente! Y almacena (cachea) estas bibliotecas en un repositorio local para agilizar las importaciones posteriores de las bibliotecas que ya tiene
- Sube nuestro propio artefacto (proyecto) para que otros se lo descarguen: no tiene por qué ser a un sitio público. Si trabajas en una empresa imagina las posibilidades de tener un repositorio con todas las bibliotecas o proyectos que hemos creado para toda la empresa. O para trabajar con los amigos y que se puedan descargar nuestra biblioteca que hemos creado y utilizarla.
- Despliega el artefacto (proyecto) en un servidor.
- Descarga arquetipos (artefactos/proyectos que son plantillas): nos descarga proyectos que son plantillas, como la estructura de un sitio web para Java EE, para tener ya la estructura de carpetas creada, con las clases más usadas ya escritas e importados las bibliotecas que siempre se necesitan; arrebatándonos la tediosa tarea de tener que crear lo mismo una y otra vez nosotros cuando alguien ya lo ha hecho antes
- Crea y despliega una web con la documentación del artefacto (proyecto).
- Se integra perfectamente con JIRA, SVN, Git
Para que veas todo el poder de Maven, te pongo un ejemplo rápido de lo que hace Maven: queremos hacer una web con Java EE. Primero desarrollaríamos en local la web. Y crearíamos unos test para probar nuestro código. Estamos trabajando en local; sabemos que cuando subamos el proyecto al servidor real las cosas no funcionan siempre igual de bien. Para subir el proyecto al servidor real de producción (el que verán los clientes o usuarios) tenemos que realizar los siguientes pasos:
- Primero validaríamos y compilaríamos el proyecto (sino habrá que corregirlo en desarrollo)
- Luego pasaríamos las pruebas hasta que estén todas correctas (si falla alguna prueba, a desarrollo otra vez)
- Empaquetaríamos el proyecto en un archivo WAR (WAR es como JAR que sirve para distribuir una web, normalmente en Java)
- A continuación subiríamos al servidor real de pruebas/desarrollo el fichero WAR
- Desplegaríamos el fichero WAR
- Volveremos a pasar las pruebas de integración en el servidor (si falla, ya sabes, a desarrollo)
- Entonces el fichero WAR lo tenemos que subir al servidor de producción (o pre-producción, dependiendo de la arquitectura que sigas)
- Para terminar con desplegar el proyecto, que está en el fichero WAR, en el servidor de producción (o pre-producción, dependiendo de la arquitectura que sigas)
- Ya terminada la nueva versión del proyecto también nos interesará crear la página de documentación.
Son muchos pasos para hacerlos a mano uno a uno. ¡Gracias Maven por hacernos todos estos pasos de manera automática! 🙂 Salvo el código del desarrollo y las pruebas, ¡Maven todavía no lee la mente, puede que en la siguiente versión…!
Y todo esto escribiendo un par de palabras en la línea de comandos (y ya si usas Eclipse, pulsando un botón 😀 Lo explicaremos también)
La siguiente imagen te muestro la estructura típica de un artefacto en Maven. Si has trabajado con Java verás que no difiere mucho de un proyecto Java de los de toda la vida (podrás comprobar que la captura es de un proyecto de Eclipse):
Ya que he introducido el termino Artefacto (Artifact): es simplemente un proyecto (un proyecto de Eclipse por ejemplo) gestionado por Maven, simplemente que en Maven llaman a un proyecto como “artefacto”. Otra diferencia con un simple proyecto Java, es que con Maven va a tener un archivo que se llama “pom.xml”.
El fichero POM (Viene de “Project Object Model”, o como diríamos en español: “Un modelo de objeto para un proyecto”) o “pom.xml”: Es un fichero XML fundamental en Maven que contiene información sobre el proyecto y la configuración (si eres un programador avanzado quizá te sirva que te diga que es como un Manifesto, AndroidManifest.xml, etc). Lo describiremos en profundidad un poco más adelante.
No nos adelantemos a la teoría sin poder probar las cosas, y empecemos por lo necesario: instalemos Maven.
Nota para los que no usen Windows: aunque aquí muestro un ejemplo funcional de como trabajar con Maven sobre Windows. Los comandos de Maven funcionan igual en todos los sistemas operativos. Otra opción es que pases directamente de la línea de comandos, e instales directamente un IDE como Eclipse que te cuento en este otro artículo. De cualquier manera, lee la teoría y obvia las ventanas de Windows si trabajas sobre cualquier otro sistema operativo (salvo los ejemplos con comandos Maven, que son iguales para todos los sistemas operativos). Este artículo no deja de ser una muestra de como trabajar con Maven y la teoría se entiende igual trabajes sobre Windows o no 😉
Instalar Maven
Vamos a instalar Maven. Antes de nada tenemos que tener instalado es el JDK de Java. Si no lo tienes instalado puedes ver como se instala en otros tutoriales de esta web como en este de Eclipse.
Tenemos que descargar Maven desde la página oficial http://maven.apache.org/ y vamos al apartado “Download” (o podemos ir directamente al apartado de descargas en http://maven.apache.org/download.cgi). Ahí descargamos un archivo binario (da igual cual. Por ejemplo, si tienes Windows el que termina en “zip” y así no tienes que instalar nada para descomprimirlo):
Descargado el archivo lo descomprimimos. Es recomendable descomprimirlo directamente en la unidad del sistema operativo (por ejemplo en la unidad C).
Ahora solo queda que la consola de Windows reconozca los comandos de Maven. Están sencillo como ir a las “variables de entorno del sistema” (puedes buscar esto con el buscador de Windows).
En la ventana que se nos abre vamos a la pestaña “Opciones avanzadas” y elegimos “Variables de entorno…”. Empezaremos creando una nueva variable de entorno pulsando “Nueva…”.
La llamaremos en “Nombre de la variable” MAVEN_HOME por ejemplo. Y le pondremos de “Valor de la variable” la ruta exacta a donde estén los ficheros de Maven descomprimidos (puedes entrar en la carpeta descomprimida de Maven, copiar la ruta y pegarla en este campo). Terminamos pulsando sobre “Aceptar”.
Ahora seleccionamos la variable del sistema que se llama “Path” y pulsaremos sobre el botón “Editar…”. Se nos abrirá la ventana para editarla. En el campo “Valor de la variable”, al final del todo pondremos (Nota importante: las rutas de este campo tienen que estar separadas por un punto y coma “;”):
;%MAVEN_HOME%/bin
Ya debería funcionar Maven. Vamos a probarlo realizando una prueba muy sencilla: veremos la versión de Maven que hemos instalado. Además, lo siguiente ya nos servirá para probar el resto de comandos.
Para ello abrimos la consola de comandos. En Windows la puedes encontrar buscando “cmd” en el buscador y abriendo el “Símbolo de sistema”.
En la consola probaremos el comando:
mvn --version
Este comando principalmente consta de dos partes:
- mvn: le decimos al sistema operativo que queremos utilizar Maven, que la busque en la variable de entorno que antes le indicamos. Esta primera palabra del comando la utilizaremos siempre que queramos hacer algo con Maven.
- –version: simplemente es la llamada a una función llamada “–version” para que nos muestre la versión de Maven e información variada recopilada por Maven
Si nos muestra la información: ¡Enhorabuena! Ya tienes configurado Maven. Ahora crearemos nuestro primer proyecto.
Crear un proyecto con Maven desde la consola de comandos
Vamos a crear un espacio de trabajo en algún lado. Por ejemplo, yo voy a crear una carpeta en el Escritorio llamada “proyectosMaven”, donde voy a tener todos mis proyectos Maven (tú créala donde quieras, yo la hago en el Escritorio para el ejemplo).
Ahora vamos a dirigirnos a este espacio de trabajo en la consola. Para ello tenemos que utilizar el comando “cd”. En mi caso bastará con poner la siguiente ruta (tendrás que poner la ruta hasta tu espacio de trabajo):
cd C:\Users\<mi usuario de Windows>\Desktop\proyectosMaven
Para generar un proyecto simple de Maven tan solo tendremos que poner el siguiente comando:
mvn archetype:generate
Y se descargar el proyecto simple de Maven. A mitad nos hará una serie de preguntas.
1. La primera pregunta será si queremos filtrar por un tipo de artefacto u otro. Por defecto está el 510 (lo que sea seguido de dos puntos significa por defecto). Nos gusta el que está por defecto por lo que no introducimos nada y pulsamos la tecla “Enter”.
2. Nos preguntará por la versión que queremos. Por defecto ya está seleccionada la última, la 6. Pues no hacemos más que pulsar “Enter”.
3. Nos pedirá el “groupId” que no es más que un identificador único para crear nuestro artefacto (proyecto). Se suele poner el mismo que el pondríamos en un paquete de Java. En este ejemplo voy a escribir: com.jarroba.ejemplo
4. El nombre del proyecto lo introducimos cuando nos pide “artifactId”. Para este ejemplo voy a escribir como nombre del proyecto: nombreDeMiProyecto
5. En la “version” de momento no escribimos nada. Pulsamos directamente “Enter”
6. Y en “package” nos sugerirá por defecto el mismo que pusimos en “groupId”. Como hemos dicho este es el nombre del paquete Java. Nos bastará con pulsar “Enter”.
7. Para terminar nos pedirá que confirmemos los datos. Pulsamos “Enter” si estamos contentos con los datos que introducimos.
Después se nos generará el proyecto. Es importante que nos ponga en grande las letras “BUILD SUCCESS”, que significará que nos ha creado correctamente el proyecto Maven.
Aquí dejo la captura completa de todas las preguntas y las respuestas que yo le he dado. Y la creación con éxito de mi proyecto Maven.
Si miramos en nuestro Espacio de trabajo comprobaremos que efectivamente se ha creado nuestro proyecto Maven.
Si entramos veremos la clara estructura Maven (y Java, porque es Java claro):
- Ficheros de código en la carpeta “src” con la estructura del paquete que definimos antes. Donde tendremos dos carpetas la “main” de Java y la “test” de pruebas; cada una con “Hello Word!” de regalo.
- Fichero “pom.xml”
Ya podremos empezar a trabajar con nuestro proyecto. Ahora solo hace falta conocer cómo funciona Maven, sus más profundos secretos.
Fases de construcción (Build phases):
Una fase es un paso en el ciclo de vida de un proyecto Maven.
A continuación expongo las tablas con todas las fases y la descripción de cada una. Caprichoso soy de recomendarte que te las saltes y vayas directamente al siguiente punto “Ciclo de vida de construcción (build)”. Luego si eso ya vuelves a estas tablas; será mucho más revelador, y ya verás cómo es tan fácil que mosquea ¿ok?
Fases del ciclo de vida por defecto (Default Lifecycle)
validate | Valida el proyecto si es correcto y si toda la información necesaria está disponible |
initialize | Inicializa el estado de construcción (build). Por ejemplo, establece las propiedades o crea directorios |
generate-sources | Genera cualquier código para incluirlo en la compilación |
process-sources | Procesa el código. Por ejemplo, para filtrar cualquier valor |
generate-resources | Genera los recursos para incluirlos en el paquete |
process-resources | Copia y procesa los recursos del directorio de destino (los ficheros que están en la carpeta “src”), los prepara para el empaquetado |
compile | Compila el código del proyecto |
process-classes | Post-procesa los ficheros generados por la compilación. Por ejemplo: mejorar el bytecode de clases Java |
generate-test-sources | Genera todas las pruebas (tests) del código para incluirlo en la compilación |
process-test-sources | Procesa las pruebas (tests) del código. Por ejemplo: filtrar cualquier valor |
generate-test-resources | Crea los recursos para probar (testing) |
process-test-resources | Copia y procesa los recursos que están dentro del directorio de destino de pruebas (los ficheros que están en la carpeta “test”) |
test-compile | Compila el código de prueba (test) del directorio de pruebas (carpeta “test”) |
process-test-classes | Post-procesa los ficheros generados por la compilación. Por ejemplo: mejorar el bytecode de clases Java |
test | Ejecuta las pruebas utilizando un Framework apropiado para los test unitarios (por ejemplo “JUnit”). Estas pruebas no deben requerir que el código esté empaquetado (packaged) o desplegado (deployed) |
prepare-package | Realizar todas las operaciones necesarias para preparar un paquete antes del empaquetado (package) actual. Esto suele resultar en una no empaquetado (unpacked), versión procesada del paquete |
package | Empaquetar el código compilado en un formato distribuible, como en un JAR, WAR, EAR, EJB, POM, MAVEN-PLUGIN |
pre-integration-test | Realizar acciones que requieran la ejecución de pruebas de integración. Esto debería implicar cosas como configurar el entorno necesario |
integration-test | Procesar (process) y desplegar (deploy) el paquete si fuera necesario en un entorno donde se puedan ejecutar pruebas de integración |
post-integration-test | Realizar acciones requeridas después de ejecutar las pruebas de integración. Esto debería incluir limpiar el entorno. |
verify | Ejecutar todas las comprobaciones para verificar la validez del paquete y que cumpla con los criterios de calidad |
install | Instala el paquete en un repositorio local, para poder utilizarse como dependencia en otros proyectos locales |
deploy | Realizar en un entorno de integración o de producción (release), copia el proyecto final al repositorio remoto para compartirlo con otros desarrolladores y proyectos |
Fases del ciclo de vida de limpieza (Clean Lifecycle)
pre-clean | Ejecuta los procesos necesarios antes de ejecutar el proyecto de limpieza |
clean | Elimina todos los ficheros generados por construcciones (build) anteriores |
post-clean | Ejecuta los procesos necesarios para finalizar el proyecto de limpieza |
Fases del ciclo de vida de documentación (Site Lifecycle)
pre-site | Ejecuta los procesos necesarios antes de ejecutar de generación de la página (o sitio) web de documentación |
site | Genera la página web de documentación del proyecto |
post-site | Ejecuta el proceso necesario para finalizar la generación de la página web de documentación, y prepara para desplegar el sitio |
site-deploy | Despliega la página web de documentación generado en el servidor web especificado |
Traducción de las tablas de http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference, cortesía de www.Jarroba.com
Ciclo de vida de construcción (build)
El ciclo de vida es una secuencia de fases que Maven ejecutará en orden. Se llama “de construcción” porque se encargan de construir nuestro proyecto.
Existen tres ciclos de vida:
- Por defecto (default): Controla el despliegue del proyecto
- Limpieza (clean): Controla la limpieza del proyecto
- Documentación (site): Controla la creación del sitio de documentación del proyecto
El ciclo de vida por defecto (Default Lifecycle) completo del proyecto es (no hay que saberse todos, los destacados en azul son los más útiles. Es más, no te tienes que saber ninguno, para eso están en esta web, para recordarlos siempre que se necesiten y explicados en las anteriores tablas :D. Sí que te recomiendo que los entiendas y al menos eches un vistazo rápido al ciclo de vida):
Cuando trabajemos con un proyecto Maven no tenemos que estar llamando todo el rato a todas las fases de un ciclo de vida.
Imaginemos por un momento que hemos desarrollado un proyecto Java con pruebas (con “test”). Queremos ejecutar las pruebas. Basta con llamar a:
mvn test
Nos ejecutará hasta la fase indicada, incluida ésta:
Por lo que cada vez que llames a una fase, recuerda que siempre se van a hacer las anteriores en su ciclo de vida.
Seguro que ya sabrás que hacer para llamar a todas las fases –con ello al ciclo de vida al completo. Habría que ejecutar:
mvn deploy
Entendido lo anterior, presento el ciclo de vida de limpieza (Clean Lifecycle), es:
Y el ciclo de vida de documentación (Site Lifecycle), es:
Muchos más cortos y sencillos que el primer ciclo de vida.
Y un regalo, todos los ciclos de vida de Maven en un PDF: Click aquí para descargar el PDF de los ciclos de vida de Maven
Realmente los que más se utilizan durante el desarrollo son el ciclo de vida por defecto y el de limpieza (el de documentación se suele utilizar al terminar el proyecto). Ambos se pueden combinar como sigue:
mvn clean test
Funciona en orden de izquierda a derecha, ejecutando primero el primer ciclo de vida (el de limpieza) y luego el segundo (el por defecto).
Para ahorrar trabajo, para limpiar y hacer algo a la vez, se utiliza mucho la combinación:
mvn clean [fase del ciclo de vida por defecto]
Ejemplo funcional:
Haz la prueba. Entra en la consola de comandos a la carpeta del proyecto (dentro del proyecto que está dentro del espacio de trabajo que creamos antes). Prueba el ciclo de vida, con cualquier fase, no pasa nada, estamos probando. La fase más simple es la de validate (como ya vimos, digo que es la más simple porque no se ejecutan más fases después, ya que es la primera), como el siguiente ejemplo que nos validará el proyecto:
mvn validate
Plugin de objetivos (Plugin Goals)
Es una tarea específica (más pequeña que una fase de construcción), que contribuye a la construcción y gestión del proyecto. Uno de estos objetivos (goals) se puede unir a alguna de las fases. Poniendo de ejemplo de comparación a la programación tradicional; podríamos decir que la fase es una función vacía que hay que llenar de algo de código, y ese algo código son los objetivos. Y estos objetivos vienen en plugins.
Podría darse el caso de que un objetivo no estuviera unido a ninguna fase y se ejecutara fuera del ciclo de vida; por ejemplo, mediante una llamada directa.
Un objetivo (goal) lo encontraremos definido como:
[nombre del plugin]:[función del plugin a ejecutar]
Un ejemplo de llamar a un objetivo directamente después de realizar la limpieza (y a su ciclo de vida de limpieza) y antes de hacer el empaquetado (y a su ciclo de vida por defecto):
mvn clean dependency:copy-dependencies package
Tranquilo que de principio no creo que los utilices directamente. Pero sí indirectamente.
Imaginemos ahora que tenemos un proyecto que queremos crear una biblioteca “jar” (o un proyecto para desplegar “war”, en este caso el ejemplo nos vale igual, salvo que donde en la imagen pone “jar:jar” habría que sustituir por el objetivo “war:war”). Ahora que remos desplegar el proyecto, por lo que se ejecutaríamos:
mvn deploy
Y nos realizaría el siguiente ciclo de vida, donde algunas fases tienen ligados algunos objetivos (destacados en naranja):
Los objetivos son el contenido de las fases. Realmente las fases vacías no ejecutan nada, pues no tienen nada que ejecutar. Por lo que realmente ejecutaría lo siguiente:
Esto lo hace Maven sólo. Con lo que no nos tendríamos que preocupar de estos; aunque no está de más que lo entendamos por si algún día tuviéramos que añadir algún objetivo nuevo. Si tienes más curiosidad de cuáles son los objetivos ligados te invito a visitar http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Built-in_Lifecycle_Bindings
El fichero POM (pom.xml)
“POM” viene de “Project Object Model”, o como diríamos en español: “Un modelo de objeto para un proyecto”.
Como describe la documentación de Maven, que libremente traduzco:
El fichero “pom.xml” es el núcleo una configuración de un proyecto en Maven. Simplemente es un fichero de configuración, que contiene la mayoría de la información necesaria para construir (build) un proyecto de la manera en la que tú quieras. El POM es enorme e intimida su complejidad, no siendo necesario comprender todos sus entresijos para utilizarlo de manera eficaz.
Dicho de una manera para entendernos: Maven hará lo que escribas en el “pom.xml”. Y lo de enorme es verdad aunque tiene un “pero”, vamos a trabajar con una fracción muy pequeña, tan pequeña que quiero que abras el “pom.xml” del arqueotipo que antes descargamos.
<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>com.jarroba.ejemplo</groupId> <artifactId>nombreDeMiProyecto</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>nombreDeMiProyecto</name> <url>https://jarroba.com/</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>
¿A qué no es tan grande? Puede que no entiendas todavía que hace cada línea, pero son solo 25 miserables líneas de XML (Realmente lo que dice la teoría de la página oficial como grande se llama “effective POM”, aunque de momento es algo que no requerimos para trabajar).
Desgranemos qué es cada parte.
Primero tenemos la etiqueta <project> que engloban a todo el POM (es la que empieza y termina el archivo). Aquí simplemente -como en todo XML- tendremos los espacios de nombres reservados para el fichero XML. Esta etiqueta no tiene más misterio.
<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">
</!-- Contenido del proyecto del POM -->
</project>
Después tenemos una serie de datos que definen el artefacto.
La primera etiqueta es <modelVersion>. Es la versión del POM, para que funcione en Maven 2 y 3 requiere ser la versión “4.0.0”, ni más ni menos; por lo que mejor no cambiarlo y olvidar esta etiqueta, pues es obligatorio que esté ahí.
<modelVersion>4.0.0</modelVersion>
Las etiquetas que seguramente ya nos suenen (los introdujimos nosotros mismos al crear el proyecto), son los llamados básicos que requiere un proyecto Maven. Como pueden ser:
- <groupId>: como ya pusimos es un nombre único que suele ser el nombre o la web de la organización. Aunque no es necesario que tenga puntos de separación en Maven, se recomienda para actúe como paquete de Java.
- <artifactId>: El nombre del proyecto
- <version>: La versión de nuestro proyecto, para sepáralas en el repositorio. Por defecto se suele poner “0.0.1-SNAPSHOT”, aunque no pasa nada si ponemos de versión “1.0” o “3.0.1”, como queramos hacer nuestro sistema de versiones.
- <packaging>: cuando Maven construya nuestro proyecto, como queremos que sea empaquetado. Si por ejemplo ponemos “jar” (que es lo que pone por defecto Maven) se nos creará una biblioteca típica de Java. Otro ejemplo sería si ponemos “war”, que sería un empaquetado web para desplegar en un servidor. O también podremos empaquetar el proyecto como “pom”, lo que querrá indicar que es un módulo Maven para proyectos multi-módulo (lo veremos en otro tutorial). Lo que necesitemos.
<groupId>com.jarroba.ejemplo</groupId> <artifactId>nombreDeMiProyecto</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>
Luego tenemos etiquetas de información del proyecto como <name> y <url>. Son todas opcionales, así que si no quieres poner ninguna pues no pongas ninguna; aunque sé que las querrás poner, son muy útiles para describir nuestro proyecto. Algunas etiquetas son:
- <name>: nombre del proyecto. Se puede poner con espacios, solo es informativa
- <url>: pues un vínculo a tu web por ejemplo.
- <description>: una descripción sobre el proyecto, o de lo que queramos.
- <organization>: el nombre de la empresa.
- <developers>: los desarrolladores implicados.
- <contributors>: los contribuidores que nos ayudaron.
- <inceptionYear>: el año en que empezamos con el proyecto.
- <licenses>: las licencias.
<name>nombreDeMiProyecto</name> <url>https://jarroba.com/</url>
Luego tenemos una etiqueta <properties> que engloba un conjunto de etiquetas (en este caso <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>). Lo que esté dentro de la etiqueta <properties> se puede decir que son variables globales que se podrán poner en otras partes del fichero POM (del tipo <nombre.de.mi.variable>valor de la variable</nombre.de.mi.variable>). El arqueotipo que descargamos nos regala una variable global que se llama “project.build.sourceEncoding” con el valor “UTF-8”. Que ¿Por qué nos dan una variable que no se usa? Pues porque son majos, y porque algunos plugins la utilizan para saber en que formato de texto se ha de codificar el fichero (en este caso «UTF-8»), por lo que recomiendo mantenerla para que todos nuestros ficheros del proyecto tengan esta codificación de caracteres (además, esta variable previene que cada plataforma ponga el tipo de codificación que le da la gana obligando a que siempre sea «UTF-8»; por ejemplo, si trabajamos con el IDE Eclipse sobre Windows por defecto guarda la codificación de caracteres «Cp1252», que nos haría un destrozo en los acentos y «Ñ» al aparecer símbolos extraños, si previamente el fichero se ha creado con otra codificación como pudiera ser el mismo «UTF-8»). ¿Para qué se suelen utilizar? Pues igual que se suelen utilizar las variables globales, para poner un valor en varios sitios a la vez sin tener que buscar cada uno de esos sitios; vamos para optimizar y no olvidar.
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
Si quisiera utilizar el valor anterior es tan simple como utilizar la sintaxis: ${nombre.de.mi.variable}. Un ejemplo sería:
<un_tag>${project.build.sourceEncoding}</un_tag>
Nos queda la mejor etiqueta de Maven, donde Maven tiene todo su poder: las relaciones.
Las relaciones pueden venir de varios tipos: por dependencias, por herencia, o por agregación de módulos (proyectos multi-módulo Maven). En este tutorial veremos la relación por dependencias, el resto de relaciones lo iremos viendo en artículos posteriores.
Relación por dependencias <dependencies>: Es la que tenemos en el ejemplo. Engloba todas las dependencias, por ello tendremos cada dependencia separada por <dependency> (notar que es singular). Una dependencia es una biblioteca de Java. Aquí será donde nos ahorremos buscar en Google una biblioteca, descargarla, importarla, etc. Maven nos lo facilita más vamos a hacer un ejemplo rápido. Descarguemos la biblioteca “JUnit” para realizar las pruebas con Java (ya sé que es la que está ya, la dependencia que viene de regalo; pero para que veas de dónde salen las cosas).
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies>
Vamos a la web del repositorio oficial de Maven en http://mvnrepository.com/. Buscamos la biblioteca que queramos importar que es “JUnit”.
Elegimos la versión de “JUint” que queramos, preferiblemente si no es “beta” (¡Mira que guay tenemos una versión superior a la que nos regalaba el arqueotipo, que para mí era la “3.8.1” y ahora voy a tener la “4.12”! 😀 )
Tan solo nos queda ir a la pestaña “Maven” y copiar el código -que feliz mente nos proporciona la web ya formateado a como Maven le gusta en el POM.
Y pegarlo en el POM, dentro de la etiqueta <dependencies>. De modo que mi POM quede:
<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>com.jarroba.ejemplo</groupId> <artifactId>nombreDeMiProyecto</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>nombreDeMiProyecto</name> <url>https://jarroba.com/</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
Si te fijas dentro de la dependencia aparte de las etiquetas <gropuId>, <artifactId> y <version> necesarias para identificar la biblioteca y la versión; le he añadido una etiqueta más que se llama <scope> (el alcance), esta sirve para indicar a Maven cuando queremos que utilice una biblioteca u otra. Por ejemplo, si pongo «test» le decimos a Maven que esta bilbioteca solo sirve para cuando se hagan pruebas; es decir, en desarrollo, en producción no nos interesa que esta biblioteca ocupe sitio, por lo que Maven no la incorporará allí (otro puntazo de Maven). Obviamente nos interesará que las bibliotecas estén también en producción si son necesarias (pues si no están dará error el programa cuando se ejecute, al faltar bibliotecas necesaria); como Junit solo nos sirve para hacer pruebas en desarrollo, en producción no nos interesan.
Los posibles valores de <scope> son (no te entretengas mucho leyéndolos, a medida que los necesites los vas a ir usando, los pongo aquí por comodidad):
- compile: es la que está por defecto si no ponemos la etiqueta <scope>. Compila dependencias para que estén disponibles en todas las rutas de las clases (classpaths). Por otra parte, esas dependencias se propagan a los proyectos dependientes.
- provided: similar a “compile”, salvo que necesita un JDK o un contenedor para proveer de tiempo de ejecución. Solo disponible en los classpath de compilación y de pruebas, no es transitivo.
- runtime: indica que la dependencia no se requiere para compilar, sino que se necesita en tiempo de ejecución. Estará en los classpaths de tiempo de ejecución y pruebas, pero no en el de compilación.
- test: indica que la dependencia no se requiere para un uso normal de la aplicación, y solo estará disponible para la compilación de las pruebas y las fases de ejecución.
- system: similar a “provided”, excepto que requiere que le importes el JAR manualmente. El artefacto estará siempre disponible y no se buscará en el repositorio
Ya solo nos queda ejecutar la parte del ciclo de vida por defecto que necesitemos. Por ejemplo podemos hacer “install”, para que además de compilar, probar, etc, nos descargue también la biblioteca.
mvn install
Si quieres saber más sobre el POM puedes mirar en http://maven.apache.org/pom.html
Has aprendido un montón de cosas sobre Maven. Es muy recomendable que utilices algún IDE que nos ayude a desarrollar con Maven. Ahorra mucho trabajo. Por ejemplo Eclipse, que puedes leer en este artículo dedicado a Maven en Eclipse.
Muy buen aporte!!
Gracias por tomarte el tiempo de explicarlo tan bien.
Hola uso proxy y no logro que maven conecte con el repositorio me ayudas. He tratado de modificar el fichero settings para que accepte mi proxy pero me sigue dando el siguiente error. Si pudieras ayudarme.
Error al ejecutar mvn archetype:generate
[INFO] Scanning for projects…
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-clean-plugin:2.5: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.5
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-install-plugin:2.4: Plugin org.apache.maven.plugins:maven-install-plugin:2.4 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-install-plugin:jar:2.4
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-deploy-plugin:2.7: Plugin org.apache.maven.plugins:maven-deploy-plugin:2.7 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-deploy-plugin:jar:2.7
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-site-plugin:3.3: Plugin org.apache.maven.plugins:maven-site-plugin:3.3 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-site-plugin:jar:3.3
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-antrun-plugin:1.3: Plugin org.apache.maven.plugins:maven-antrun-plugin:1.3 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-antrun-plugin:jar:1.3
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5: Plugin org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-assembly-plugin:jar:2.2-beta-5
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-dependency-plugin:2.8: Plugin org.apache.maven.plugins:maven-dependency-plugin:2.8 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-dependency-plugin:jar:2.8
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-release-plugin/2.3.2/maven-release-plugin-2.3.2.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-release-plugin:2.3.2: Plugin org.apache.maven.plugins:maven-release-plugin:2.3.2 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-release-plugin:jar:2.3.2
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml
[WARNING] Could not transfer metadata org.apache.maven.plugins/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): Failed to transfer file: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml. Return code is: 405 , ReasonPhrase:Method Not Allowed.
[WARNING] Could not transfer metadata org.codehaus.mojo/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): Failed to transfer file: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml. Return code is: 405 , ReasonPhrase:Method Not Allowed.
[WARNING] Failure to transfer org.apache.maven.plugins/maven-metadata.xml from https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer metadata org.apache.maven.plugins/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): Failed to transfer file: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml. Return code is: 405 , ReasonPhrase:Method Not Allowed.
[WARNING] Failure to transfer org.codehaus.mojo/maven-metadata.xml from https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer metadata org.codehaus.mojo/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): Failed to transfer file: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml. Return code is: 405 , ReasonPhrase:Method Not Allowed.
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 0.722 s
[INFO] Finished at: 2018-01-04T18:28:38-03:00
[INFO] Final Memory: 10M/114M
[INFO] ————————————————————————
[ERROR] No plugin found for prefix ‘archetype’ in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (C:\Users\yuniel.acosta\.m2\repository), central (https://repo.maven.apache.org/maven2)] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoPluginFoundForPrefixException
Hay algo que no está bien configurado, podrían ser también puertos o antivirus bloqueando.
Asegúrate que el proxy está bien configurado: https://maven.apache.org/guides/mini/guide-proxies.html
Prueba a abrir desde el navegador la url: https://repo.maven.apache.org/maven2 para descartar. Tienes que ver un listado de links a los repositorios.
Excelente tutorial!!! sigo mucho esta pagina… gracias por los aportes!!!
¿Puedes elaborar una publicación (Post) sobre Gradle?
Gracias por la sugerencia. Lo tendremos en cuenta para siguientes artículos.
Saludos, tengo un inconveniente no me deja crear el proyecto no entiendo por que realice todos los pasos , por ahi averigue que puede ser por el proxy
pero no uso proxy
el error siguiente es :
C:\Users\COMPAQ\Desktop\ProyectoMaven>mvn archetype:generate
[INFO] Scanning for projects…
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-clean-plugin/2.5/maven-clean-plugin-2.5.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-clean-plugin:2.5: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or on
e of its dependencies could not be resolved: Failed to read artifact descriptor
for org.apache.maven.plugins:maven-clean-plugin:jar:2.5
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-install-plugin/2.4/maven-install-plugin-2.4.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-install-plugin:2.4: Plugin org.apache.maven.plugins:maven-install-plugin:2.4 o
r one of its dependencies could not be resolved: Failed to read artifact descrip
tor for org.apache.maven.plugins:maven-install-plugin:jar:2.4
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-deploy-plugin:2.7: Plugin org.apache.maven.plugins:maven-deploy-plugin:2.7 or
one of its dependencies could not be resolved: Failed to read artifact descripto
r for org.apache.maven.plugins:maven-deploy-plugin:jar:2.7
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-site-plugin/3.3/maven-site-plugin-3.3.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-site-plugin:3.3: Plugin org.apache.maven.plugins:maven-site-plugin:3.3 or one
of its dependencies could not be resolved: Failed to read artifact descriptor fo
r org.apache.maven.plugins:maven-site-plugin:jar:3.3
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-antrun-plugin:1.3: Plugin org.apache.maven.plugins:maven-antrun-plugin:1.3 or
one of its dependencies could not be resolved: Failed to read artifact descripto
r for org.apache.maven.plugins:maven-antrun-plugin:jar:1.3
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-assembly-plugin:2.2-beta-5: Plugin org.apache.maven.plugins:maven-assembly-plu
gin:2.2-beta-5 or one of its dependencies could not be resolved: Failed to read
artifact descriptor for org.apache.maven.plugins:maven-assembly-plugin:jar:2.2-b
eta-5
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-dependency-plugin:2.8: Plugin org.apache.maven.plugins:maven-dependency-plugin
:2.8 or one of its dependencies could not be resolved: Failed to read artifact d
escriptor for org.apache.maven.plugins:maven-dependency-plugin:jar:2.8
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-release-plugin/2.3.2/maven-release-plugin-2.3.2.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:mave
n-release-plugin:2.3.2: Plugin org.apache.maven.plugins:maven-release-plugin:2.3
.2 or one of its dependencies could not be resolved: Failed to read artifact des
criptor for org.apache.maven.plugins:maven-release-plugin:jar:2.3.2
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-metadata.xml
Downloading: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metada
ta.xml
[WARNING] Could not transfer metadata org.apache.maven.plugins/maven-metadata.xm
l from/to central (https://repo.maven.apache.org/maven2): Connect to repo.maven.
apache.org:443 [repo.maven.apache.org/151.101.56.215] failed: Connection timed o
ut: connect
[WARNING] Could not transfer metadata org.codehaus.mojo/maven-metadata.xml from/
to central (https://repo.maven.apache.org/maven2): Connect to repo.maven.apache.
org:443 [repo.maven.apache.org/151.101.56.215] failed: Connection timed out: con
nect
[WARNING] Failure to transfer org.apache.maven.plugins/maven-metadata.xml from h
ttps://repo.maven.apache.org/maven2 was cached in the local repository, resoluti
on will not be reattempted until the update interval of central has elapsed or u
pdates are forced. Original error: Could not transfer metadata org.apache.maven.
plugins/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2
): Connect to repo.maven.apache.org:443 [repo.maven.apache.org/151.101.56.215] f
ailed: Connection timed out: connect
[WARNING] Failure to transfer org.codehaus.mojo/maven-metadata.xml from https://
repo.maven.apache.org/maven2 was cached in the local repository, resolution will
not be reattempted until the update interval of central has elapsed or updates
are forced. Original error: Could not transfer metadata org.codehaus.mojo/maven-
metadata.xml from/to central (https://repo.maven.apache.org/maven2): Connect to
repo.maven.apache.org:443 [repo.maven.apache.org/151.101.56.215] failed: Connect
ion timed out: connect
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 03:24 min
[INFO] Finished at: 2016-09-29T17:55:42-05:00
[INFO] Final Memory: 5M/15M
[INFO] ————————————————————————
[ERROR] No plugin found for prefix 'archetype' in the current project and in the
plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the
repositories [local (C:\Users\COMPAQ\.m2\repository), central (https://repo.mave
n.apache.org/maven2)] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit
ch.
Saludos..
Parece que algo te está bloqueando. Si no tienes proxy, comprueba que no sea el antivirus o el firewall, o puede que desde donde estés intentando la conexión te esté bloqueando. Por otro lado, si has cambiado el settings.xml restauralo para probar.
Mi agradecimiento y felicitaciones, no habia encontrado un buen tutorial, simple y objetivo.
Gracias
Gracias por este gran tutorial. Muy sencillo de seguir y bien explicado! Te felicito.
Excelente articulo claro y preciso, me sirvio de mucho.
""En este tutorial veremos la relación paor dependencias, el resto de relaciones lo iremos viendo en artículos posteriores."""
Para no morir por lo bueno que esta el tutorial, por el punto mencionado anteriormente y sobre todo para darle mas "profundidad Obscura" como dices, necesito la continuación!!!, es tal vez lo de ya entrando a Eclipse para conocer mas a maven??
Es que inicie practicas con html-servlets-dao-dto-bd(en principio un xml manejado con DOM luego Mysql)-hibenate-un poco de IOC con spring-jsp con jstl.
Luego practique conocer struts 2, parar ver el framewrk pero, todo siempre a mano, me ha tenido mal Maven, creo con eso puedo incluso apuntar o arrancar con Spring mvc-hibernate-BD – algo de IOC, y AOP, gestión de versión con git y algo de Front que no es mi fuerte, pero todo con MAVEN….
Acepto y ruego recomendaciones de cualquier tipo, índole, punto nombrado o no… de lo que busco o incluso de lo que debería buscar en cuanto a una practica eficaz y tirando hacia lo profesional.
Excelente, gracias.
Hola César. Muchas gracias por los ánimos 🙂
Sí, el tutorial de Eclipse es el siguiente http://jarroba.com/maven-en-eclipse/, donde explico más sobre Maven. De cualquier manera estamos trabajando en más artículos sobre Maven para un futuro.
Excelente aporte!!!
Algo para aportar, tuve que configurar el setting.xml para la parte del proxy (ver http://stackoverflow.com/questions/30861293/maven-not-working-when-mvn-package-command-is-run).
Muchas gracias!!!
Un saludo.
Gracias Gabriel por el aporte, seguro le servirá a muchos desarrolladores 🙂
¡Muchos ánimos!
Gracias por el trabajo , me ha sido de gran ayuda. Saludos , seguire y compartire tu web .
Muy buen trabajo, felicidades !!! y Gracias me ha ayudado mucho.
Saludos
gracias por tu aporte a la sociedad, es de gran ayuda …..
Buen trabajo. Gracias.
Excelente tutorial. Felicitaciones y muchas gracias!
Amigo, muchas gracias por estas intrucciones tan bien explicadas. Me sirvio mucho y fue realmente facil de entender
Te deseo muchos exitos
Saludos!