Diferencia entre revisiones de «Primeros pasos con Maven»

De Wiki de EGC
Saltar a: navegación, buscar
Línea 56: Línea 56:
  
 
=Plugins y objetivos=
 
=Plugins y objetivos=
Un concepto clave de Maven son los plugins. Toda la funcionalidad de Maven se realiza a través de plugins. Hay plugins encargados de gestionar las dependencias, plugins encargados de compilar código Java, plugins encargados de ejecutar pruebas de JUnit, plugins encargados de empaquetar el código en un fichero JAR, etc. Los plugins ofrecen su funcionalidad a través de lo que se conoce como objetivos. Por ejemplo, el plugin encargado de la compilación de código ([https://maven.apache.org/plugins/maven-compiler-plugin/ compiler]) tiene dos goals:
+
Un concepto clave de Maven son los plugins. Toda la funcionalidad de Maven se realiza a través de plugins. Hay plugins encargados de gestionar las dependencias, plugins encargados de compilar código Java, plugins encargados de ejecutar pruebas de JUnit, plugins encargados de empaquetar el código en un fichero JAR, etc. Los plugins ofrecen su funcionalidad a través de lo que se conoce como objetivos (goals). Por ejemplo, el plugin encargado de la compilación de código ([https://maven.apache.org/plugins/maven-compiler-plugin/ compiler]) tiene dos objetivos:
 
* compiler:compile que compila el código fuente del proyecto, que está en la carpeta main/src/java
 
* compiler:compile que compila el código fuente del proyecto, que está en la carpeta main/src/java
 
* compiler:testCompile que compila el código de las pruebas del proyecto, que está en la carpeta main/src/test
 
* compiler:testCompile que compila el código de las pruebas del proyecto, que está en la carpeta main/src/test
  
Otro ejemplo puede ser el plugin encargado de crear un paquete JAR ([https://maven.apache.org/plugins/maven-jar-plugin/ jar]), que tiene también dos goals:
+
Otro ejemplo puede ser el plugin encargado de crear un paquete JAR ([https://maven.apache.org/plugins/maven-jar-plugin/ jar]), que tiene también dos objetivos:
 
* jar:jar que crea un fichero jar con el código del proyecto y el contenido de la carpeta src/main/resources
 
* jar:jar que crea un fichero jar con el código del proyecto y el contenido de la carpeta src/main/resources
 
* jar:test-jar que crea un fichero jar con el código de las pruebas del proyecto y el contenido de la carpeta src/test/resources
 
* jar:test-jar que crea un fichero jar con el código de las pruebas del proyecto y el contenido de la carpeta src/test/resources
  
Los plugins se pueden configurar en el fichero pom.xml del proyecto y los goals de un plugin se pueden invocar por línea de comandos de la siguiente forma:
+
Los plugins se pueden configurar en el fichero pom.xml del proyecto y los objetivos de un plugin se pueden invocar por línea de comandos de la siguiente forma:
  
 
<source lang="bash">
 
<source lang="bash">
Línea 70: Línea 70:
 
</source>
 
</source>
  
Los goals se ejecutan siguiendo el orden en que son invocados. Por tanto se podría hacer:
+
Los objetivos se ejecutan siguiendo el orden en que son invocados. Por tanto se podría hacer:
  
 
<source lang="bash">
 
<source lang="bash">
Línea 99: Línea 99:
 
En [https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference Lifecycles] se recogen todas las fases definidas en cada ciclo de vida y una breve descripción de cada una de ellas.
 
En [https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference Lifecycles] se recogen todas las fases definidas en cada ciclo de vida y una breve descripción de cada una de ellas.
  
Aunque cada fase es responsable de un paso específico en el ciclo de vida al que corresponda, la manera en la que se realizan esas responsabilidades puede variar en función del tipo de proyecto (ej. si es un proyecto web, una aplicación de consola, una librería, una aplicación de móviles...), del tipo de empaquetado utilizado (ej. si es WAR, JAR, EAR...), etc. Para configurar qué se hace en cada fase, se enlazan goals de plugins con las fases del ciclo de vida. De este modo, ejecutar una fase del ciclo de vida equivale a ejecutar los goals de plugins vinculados a esa fase. Dependiendo del tipo de packaging del proyecto, cada fase está vinculada a diferentes goals de plugins. Además, esa vinculación se puede configurar a través del fichero pom.xml.
+
Aunque cada fase es responsable de un paso específico en el ciclo de vida al que corresponda, la manera en la que se realizan esas responsabilidades puede variar en función del tipo de proyecto (ej. si es un proyecto web, una aplicación de consola, una librería, una aplicación de móviles...), del tipo de empaquetado utilizado (ej. si es WAR, JAR, EAR...), etc. Para configurar qué se hace en cada fase, cada fase se enlaza con uno o más objetivos de plugins. De este modo, ejecutar una fase del ciclo de vida equivale a ejecutar los objetivos de plugins vinculados a esa fase. Algunas fases tienen ya vinculadas objetivos de plugins por defecto. Esta vinculación varía dependiendo del tipo de packaging del proyecto. Por ejemplo, para un packaging jar, las fases con objetivos de plugin vinculados son las siguientes (puedes ver la lista completa en [https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Built-in_Lifecycle_Bindings Built-in Lifecycle Bindings]):
 +
 
 +
{| class="wikitable"
 +
| '''Fase'''
 +
| '''Plugin:objetivo'''
 +
|-
 +
| process-resources
 +
| resources:resources
 +
|-
 +
| compile
 +
| compiler:compile
 +
|-
 +
| process-test-resources
 +
| resources:testResources
 +
|-
 +
| test-compile
 +
| compiler:testCompile
 +
|-
 +
| test
 +
| surefire:test
 +
|-
 +
| package
 +
| jar:jar
 +
|-
 +
| install
 +
| install:install
 +
|-
 +
| deploy
 +
| deploy:deploy
 +
|}
 +
 
 +
Además, esa vinculación se puede configurar a través del fichero pom.xml.
 +
 
 +
Un ciclo de vida no se ejecuta directamente por línea de comandos, sino que lo que se ejecuta esa una fase del ciclo de vida. La forma de ejecutarlo es igual que los objetivos de plugins:
 +
 
 +
<source lang="bash">
 +
mvn fase1..faseN
 +
</source>
 +
 
 +
Cuando se ejecuta una fase, se ejecutan también todas las fases previas definidas en el ciclo de vida. Por tanto, si ejecutamos:
 +
 
 +
<source lang="bash">
 +
mvn package
 +
</source>
 +
 
 +
Se ejecutaran todas las fases del ciclo de vida default desde la primera, que es validate, hasta package, incluyendo por tanto: validate, initialize, generate-sources, process-sources, generate-resources, '''process-resources''', '''compile''', process-classes, generate-test-sources, process-test-sources, generate-test-resources, '''process-test-resources''', '''test-compile''', process-test-classes, '''test''', prepare-package, '''package'''.
 +
 
 +
Todas las fases que no tengan objetivos de plugins vinculados (por defecto, todas las que no están en negrita) simplemente se ignoran durante la ejecución.
 +
 
 +
En una misma llamada a Maven es posible mezclar fases con objetivos de plugins. Como siempre, el orden en que se ejecutan es el que aparecen en línea de comandos. Por ejemplo:
  
 
<source lang="bash">
 
<source lang="bash">
mvn fase1..faseN plugin1:objetivo1..pluginN:objetivoN
+
mvn clean dependency:copy-dependencies package
 
</source>
 
</source>
*Las fases se ejecutan en el orden en que son invocados. Todas las fases previas definidas en el lifecycle, son ejecutadas también.
 
* (cf. [https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference Lifecycles]). Estas son las posibles fases:
 
  
 +
Lo que hace es:
 +
# Invocar a la fase clean del ciclo de vida clean, que limpia el directorio del proyecto de todos los ficheros generados durante la construcción del mismo.
 +
# Invocar al objetivo copy-dependencies del plugin dependency, que lo que hace es copiar los JAR de los que depende del proyecto a una carpeta dentro del mismo.
 +
# Invocar a la fase package del ciclo de vida default, que compila, prueba y empaqueta el proyecto.
  
 +
=Ejercicio=
  
=Compilar el proyecto=
+
==Compilar el proyecto==
  
 
<source lang=bash>
 
<source lang=bash>
Línea 116: Línea 168:
 
Buscará los fuentes en src/main
 
Buscará los fuentes en src/main
  
=Modificar el proyecto=
+
==Modificar el proyecto==
*Introdir método en la clase App.java
+
*Introducir método en la clase App.java
 
<source lang=bash>
 
<source lang=bash>
 
static int getVal(){
 
static int getVal(){
Línea 133: Línea 185:
 
</source>
 
</source>
  
=Testear el proyecto=
+
==Testear el proyecto==
  
 
<source lang=bash>
 
<source lang=bash>
Línea 140: Línea 192:
 
Buscará los fuentes en src/test
 
Buscará los fuentes en src/test
  
=Introducir error en el test y tratar de generar el .jar en la carpeta target=
+
==Introducir error en el test y tratar de generar el .jar en la carpeta target==
 
<source lang=bash>
 
<source lang=bash>
 
mvn package
 
mvn package
 
</source>
 
</source>

Revisión del 08:42 24 nov 2017

Descarga e instala Maven

Descargue Maven y siguen las instrucciones de instalación. Tras instalar, ejecute

mvn --version

Si todo está correcto, debería observar algo como lo que sigue:

Apache Maven 3.3.3
Maven home: C:\...\apache-maven-3.3.3\bin\..
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_25\jre
Default locale: es_ES, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos"

Cambiar la configuración de usuario del repositorio local para no contener espacios (opcional)

Hay tres niveles de configuración: instalación (mavenInst/conf/settings.xml), usuario (userHome/.m2/settings.xml), proyecto (projectHome/pom.xml)

Por defecto, el repositorio local está en ${user.home}/.m2/repository. Si se desea cambiar (para no contener espacios), en la carpeta ${user.home}/.m2 crear un archivo settings.xml con el siguiente contenido.

<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
  <localRepository> nuevaRuta </localRepository>
</settings>

Generar el primer proyecto. El archetype utilizado por defecto es el maven-archetype-quickstart

mvn -B archetype:generate -DgroupId=es.egc.app -DartifactId=proy1

ó

mvn -B archetype:generate -DgroupId=es.egc.app -DartifactId=proy1 -DarchetypeArtifactId=maven-archetype-quickstart

La carpeta generada debido al arquetipo seleccionado tendrá el siguiente contenido:

  • src/main contiene el código fuente
  • src/test contiene el código para testeo
  • Dentro del pom.xml
    • El packing por defecto es jar.
    • Se incluye la dependencia a JUnit

Maven utiliza la convención de ficheros para encontrar los diferentes elementos del proyecto (cf. Ficheros). De este modo, todos los proyectos que usan maven deben seguir la misma estructura. Esto es conveniente pues asegura que cualquier desarrollador puede entender la estructura de directorios de un proyecto con mayor facilidad.

Introducción a Maven

Maven ofrece dos funcionalidades básicas:

  • Gestión de la construcción de un proyecto
  • Gestión de las dependencias de un proyecto

Ambas funcionalidades se configuran a través del fichero pom.xml

Plugins y objetivos

Un concepto clave de Maven son los plugins. Toda la funcionalidad de Maven se realiza a través de plugins. Hay plugins encargados de gestionar las dependencias, plugins encargados de compilar código Java, plugins encargados de ejecutar pruebas de JUnit, plugins encargados de empaquetar el código en un fichero JAR, etc. Los plugins ofrecen su funcionalidad a través de lo que se conoce como objetivos (goals). Por ejemplo, el plugin encargado de la compilación de código (compiler) tiene dos objetivos:

  • compiler:compile que compila el código fuente del proyecto, que está en la carpeta main/src/java
  • compiler:testCompile que compila el código de las pruebas del proyecto, que está en la carpeta main/src/test

Otro ejemplo puede ser el plugin encargado de crear un paquete JAR (jar), que tiene también dos objetivos:

  • jar:jar que crea un fichero jar con el código del proyecto y el contenido de la carpeta src/main/resources
  • jar:test-jar que crea un fichero jar con el código de las pruebas del proyecto y el contenido de la carpeta src/test/resources

Los plugins se pueden configurar en el fichero pom.xml del proyecto y los objetivos de un plugin se pueden invocar por línea de comandos de la siguiente forma:

mvn plugin1:objetivo1..pluginN:objetivoN

Los objetivos se ejecutan siguiendo el orden en que son invocados. Por tanto se podría hacer:

mvn compiler:compile jar:jar

Para compilar el código de nuestro proyecto y empaquetarlo en un JAR.

Ciclo de vida y fases

El otro concepto fundamental de Maven para la gestión de la construcción de un proyecto es el ciclo de vida. Un ciclo de vida está compuesto por un conjunto de fases. En Maven se definen tres ciclos de vida por defecto y normalmente nunca te vas a ver en la necesidad de definir ninguno adicional. Los tres ciclos de vida de Maven son:

  • El ciclo de vida default, que gestiona la construcción y despliegue del proyecto.
  • El ciclo de vida clean, que gestiona la limpieza del directorio del proyecto. Es decir, se encarga de eliminar todos los archivos generados en el proceso de construcción y despliegue.
  • El ciclo de vida site, que gestiona la creación de la documentación del proyecto.

Las fases que componen cada ciclo de vida también están predefinidas. Por ejemplo, el ciclo de vida default está compuesto por las siguientes fases:

validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy

De entre todas ellas las más relevantes son:

  • validate: Que valida que el proyecto es correcto y que está disponible toda la información necesaria
  • compile: Que compila el código fuente del proyecto
  • test: Que prueba el código compilado utilizando algún framework de pruebas unitarias. Estas pruebas no deben requerir que el código esté empaquetado o desplegado.
  • package: Coge el código compilado y lo empaqueta en un formato distribuible. Por ejemplo, como un JAR.
  • verify: Ejecuta comprobaciones de pruebas de integración para asegurarse que se cumplen los criterios de calidad
  • install: Instala el paquete en el repositorio local (el directorio ${user.home}/.m2) para que se pueda usar como dependencia en otros proyectos localmente
  • deploy: Copia el paquete final a un repositorio remoto para compartirlo con otros desarrolladores. Hay que tener en cuenta que este despliegue no se refiere en general al despliegue de la aplicación en un servidor web, sino a dejarlo disponible en un repositorio para que lo usen otros desarrolladores (más información en [Introducción de dependencias]).

En Lifecycles se recogen todas las fases definidas en cada ciclo de vida y una breve descripción de cada una de ellas.

Aunque cada fase es responsable de un paso específico en el ciclo de vida al que corresponda, la manera en la que se realizan esas responsabilidades puede variar en función del tipo de proyecto (ej. si es un proyecto web, una aplicación de consola, una librería, una aplicación de móviles...), del tipo de empaquetado utilizado (ej. si es WAR, JAR, EAR...), etc. Para configurar qué se hace en cada fase, cada fase se enlaza con uno o más objetivos de plugins. De este modo, ejecutar una fase del ciclo de vida equivale a ejecutar los objetivos de plugins vinculados a esa fase. Algunas fases tienen ya vinculadas objetivos de plugins por defecto. Esta vinculación varía dependiendo del tipo de packaging del proyecto. Por ejemplo, para un packaging jar, las fases con objetivos de plugin vinculados son las siguientes (puedes ver la lista completa en Built-in Lifecycle Bindings):

Fase Plugin:objetivo
process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package jar:jar
install install:install
deploy deploy:deploy

Además, esa vinculación se puede configurar a través del fichero pom.xml.

Un ciclo de vida no se ejecuta directamente por línea de comandos, sino que lo que se ejecuta esa una fase del ciclo de vida. La forma de ejecutarlo es igual que los objetivos de plugins:

mvn fase1..faseN

Cuando se ejecuta una fase, se ejecutan también todas las fases previas definidas en el ciclo de vida. Por tanto, si ejecutamos:

mvn package

Se ejecutaran todas las fases del ciclo de vida default desde la primera, que es validate, hasta package, incluyendo por tanto: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package.

Todas las fases que no tengan objetivos de plugins vinculados (por defecto, todas las que no están en negrita) simplemente se ignoran durante la ejecución.

En una misma llamada a Maven es posible mezclar fases con objetivos de plugins. Como siempre, el orden en que se ejecutan es el que aparecen en línea de comandos. Por ejemplo:

mvn clean dependency:copy-dependencies package

Lo que hace es:

  1. Invocar a la fase clean del ciclo de vida clean, que limpia el directorio del proyecto de todos los ficheros generados durante la construcción del mismo.
  2. Invocar al objetivo copy-dependencies del plugin dependency, que lo que hace es copiar los JAR de los que depende del proyecto a una carpeta dentro del mismo.
  3. Invocar a la fase package del ciclo de vida default, que compila, prueba y empaqueta el proyecto.

Ejercicio

Compilar el proyecto

mvn compile

Buscará los fuentes en src/main

Modificar el proyecto

  • Introducir método en la clase App.java
static int getVal(){
return 1;
}
  • Modificar test de la clase AppTest.java
…
assertTrue(App.getVal()==1);

Testear el proyecto

mvn test

Buscará los fuentes en src/test

Introducir error en el test y tratar de generar el .jar en la carpeta target

mvn package