Bloque de Conocimiento de Maven2
Imprimir

Bloque de Conocimiento de Maven2

Tabla de contenidos

Introducción

Maven2 es una herramienta para la Administración de proyectos. Esta nueva versión fue construída desde cero para mejorar varios aspectos de Maven1. Las principales mejoras son:

  • Soporte nativo para multiproyecto
  • Scope de Dependencias
  • Resolución automática de dependencias transitivas
  • Unificación de archivos de configuración

Versiones previas: Maven 1


Contenidos

Maven se puede extender mediante plugins. La mayoría de los plugins disponibles en Maven1 (¡que son muchos!) ya se encuentran portados para la versión 2.

Maven2 define una estructura de directorio estándar que, si bien puede ser modificada, nos ayuda a navegar los proyectos fácilmente: Cualquier programador acostumbrado a la estructura de Maven2 debería saber donde encontrar las pruebas unitarias, los archivos .java del dominio del proyecto y los archivos de configuración u otros recursos.

La estructura de directorios predeterminada es la siguiente:

| |- src | | | |-main | | | | | |-java | | |-resources | | |-test | | |-java | | |-resources | |- target | | | |-classes | |-site

Para crear un proyecto Maven2 en blanco hay que ejecutar el siguiente comando:

mvn archetype:create -DgroupId= -DartifactId=

Para crear un proyecto de tipo Web:

mvn archetype:create -DgroupId= - DartifactId= -Dpackagename= - DarchetypeArtifactId=maven-archetype-webapp

donde: es el identificador único (en nuestro caso: com.epidataconsulting). es el nombre del artefacto (seria el nombre del proyecto).

Este comando genera la estructura de directorio antes mencionada y un archivo pom.xml (con un mínima estructura) que tiene la siguiente forma:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.epidataconsulting</groupId>
 <artifactId>proyecto</artifactId>
 <packaging>jar</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>Proyecto de prueba</name>
 <dependencies>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>3.8.1</version>
     <scope>test</scope>
   </dependency>
 </dependencies>
</project>

Este archivo pom.xml contiene los siguientes elementos:

  • modelVersion: La versión del Modelo de Proyecto. En Maven2 debe ser 4.0.0
  • packaging: Como se empaquetará este artefacto: jar, war o ear
  • version: La versión actual de nuestro artefacto
  • name: Un nombre que se usará en la generación de documentación
  • dependencies: Contiene las dependencias del proyecto
  • dependency: Describe una dependencia en particular
    • groupId: El groupId de la dependencia en el repositorio Maven2
    • artifactId: El artifactId de la dependencia en el repositorio Maven2
    • version: La versión que se desea utilizar
    • scope: El alcance de la dependencia ver scope?

Esta es una versión reducida de la totalidad de características que ofrece el Project Object Model (POM). En un pom.xml más completo se pueden agregar más datos del proyecto, configurar el repositorio de deploy, el lugar donde se colocará el sito web, se pueden configurar reportes de calidad para incluir en dicho sitio y especificar los datos de los desarrolladores y colaboradores del proyecto, entre otras cosas. Una vez creado el proyecto y agregadas las dependencias necesarias al POM ejecutamos:

mvn compile

para compilar nuestro proyecto.

Más comandos útiles

Otros comandos útiles de maven son:

  • mvn test: Ejecuta los test de unidad
  • mvn test-compile: Compila los test de unidad
  • mvn package: Nos genera el paquete de nuestro proyecto (Jar, War o Ear, según hayamos definido)
  • mvn install: Instala nuestro artifact en el repositorio local
  • mvn clean: Limpia los archivos de compilación.
  • mvn -Declipse.downloadSources=true eclipse:eclipse: Baja los fuentes (en caso de falla de algún download, se terminara el proceso, en ese caso se puede añadir -fae (falla ante un error insalvable))
  • mvn -Declipse.workspace= eclipse:add-maven-repo: Para agregar la variable M2_REPO a Eclipse
  • mvn javadoc:javadoc: Para generar los JavaDocs?
  • mvn ... -Dmaven.test.skip=true: Evita la ejecución de tests
  • mvn site: Para generar el sitio web del proyecto (queda en target/site)

Configuración

Agregar al MANIFEST las dependencias

En un war sería así

<plugin>
	        <groupId>org.apache.maven.plugins</groupId>
	        <artifactId>maven-war-plugin</artifactId>
	        <configuration>
	          <archive>
	            <manifest>
	              <addClasspath>true</addClasspath>
	              <addExtensions/>
	              <classpathPrefix/>
	            </manifest>
	            <manifestEntries>
	              <mode>development</mode>
	              <ur<x>l>${pom.ur<x>l}</ur<x>l>
	            </manifestEntries>
	          </archive>
	        </configuration>
	      </plugin>

Deploy del jar en el repo

Desde target, donde se encuentra el jar (en este caso se llama colmena-util-xml-0.2.jar), ejecutar la siguiente línea. Se puede observar que se hace referencia al pom.xml con ../pom.xml para que se genere el pom.xml correcto y no uno por default. Con esto se gana que las dependencias se usen en el proyecto que utilice el jar deployado en cuestión:

mvn deploy:deploy-file -DartifactId=colmena-util-xml -DgroupId=com.epidatacon

sulting.epidata.colmena.common.xml -Dpackaging=jar -Dversion=0.2 -DrepositoryId=bua -Durl=scpexe:192.168.1.151/repository -Dfile=colmena-util-xml-0.2.jar -DpomFile=../pom.xml

Aclaraciones: Bajo Windows, en settings.xml hay que tener configurado donde está plink.exe y pscp.exe:
<server>
      <id>bua</id>
      <configuration>
      	<sshExecutable>C:\Putty\plink.exe</sshExecutable>
      	<scpExecutable>C:\Putty\pscp.exe</scpExecutable>
      </configuration>
      <username>nicolasg</username>
      <password>Tu_Password</password>
    </server>

Notas:

  • en Linux no es necesario el tag ni sus tags hijos
  • el tag password es opcional (tanto en Windows como en Linux)

Hay que tener en cuenta que en caso de usar la autentificación Clave Pública-Privada tenemos que tener iniciado el pageant y asociada la correspondiente clave privada, así como también tiene que estar en el servidor la clave pública. El enfoque Clave Pública-Privada es útil para no tener que tener escrito el password en el settings.xml.

En caso de querer hacer el deploy de un proyecto propio, la manera correcta sería definiendo en el pom.xml las siguientes líneas:

<distributionManagement>
		<repository>
                        <id>mismo_id_que_el_del_server_en_setting_xml</id>
                        <ur<x>l>scpexe://ip_del_repositorio_compartido/directorio_del_repo</ur<x>l>
		</repository>
	</distributionManagement>
(en Linux hay que poner scp:// en vez de scpexe:// )

y

<build>     
                <extensions>       
			<extension>         
				<groupId>org.apache.maven.wagon</groupId>          
				<artifactId>wagon-ssh-external</artifactId>          
                                <version>1.0-alpha-6</version>       
			</extension>     
		</extensions>   
        </build>

Con estas últimas líneas lo que hacemos es indicar que el ssh que se usará para conectarse al servidor no es el que trae maven internamente. Para hacer el deploy del proyecto, basta con escribir:

mvn deploy

Links relacionados con "mvn deploy":

Deploy de un jar en el repositorio local

Algunas veces sucede que se necesita usar una clase que se encuentra en un jar del cual no tenemos todo el proyecto (es un jar ajeno) o el proyecto no está "mavenizado" . Desde ya, el proyecto no debe estar en http://www.ibiblio.org/Maven2/, porque de ese modo no sería necesario hacer esto.

En esos casos, hay un goal de Maven para poder subir el jar en cuestión (en este caso se llama jarDeEjemplo.jar) al repositorio local. Obviamente debemos disponer del archivo para poder hacer esto. Primero hay que posicionarse en el directorio en el cual se encuentra ubicado el archivo. Luego ha que ejecutar la siguiente línea:

mvn install:install-file -Dfile=jarDeEjemplo.jar -DartifactId=nombreProyecto -DgroupId=nombreGrupo -Dpackaging=jar -Dversion=1.0

Con esto se sube el jar y se dispone del mismo para configurar el pom.xml de cualquier proyecto local. Eso sí, solamente está disponible en la máquina en la que se hizo esto. Para poder usarlo de manera global habría que subirlo al repositorio compartido, pero ese es otro tema, que va más allá de este título.

Cabe destacar que se pueden elegir los nombres de grupo y de artifact que uno quiera, así como también la versión del archivo, por lo que conviene estar al tanto de los verdaderos nombres de grupo y artefacto y del número de versión, para que esta información se pueda compartir y le sirva a alguien más, en el caso en que luego se suba esto a otro repositorio, utilizado por más desarrolladores.

Compilación con Java 5

<project>
.....
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
.....
</build>
</project>

Maven Proxy

Introducción

En general es conveniente trabajar utilizando un proxy del repositorio maven en la red local.

Al ejecutar cualquier comando de maven que requiera utilizar las dependencias del proyecto (como ser compile, test, package, etc) maven busca dichas dependencias en el repositorio local y en caso de no encontrarlas, las irá a buscar a un repositorio de internet.

Utilizando un proxy, el algoritmo cambia de la siguiente manera: primero busca en el directorio local. En caso de no encontrar la dependencia, la irá a buscar al maven proxy. Luego, el maven proxy, si tiene dicha dependencia, se la enviará a la aplicación que ejecutó el comando, caso contrario, la descargará de un repositorio de internet y luego se la enviará a la aplicación.

Ventajas

  • Majora en la velocidad de ejecución de comandos maven
    • Cada usuario dentro de la misma red, trabajando con maven, no deberá ir a buscar a internet cada dependencia, simplemente se irá a buscar la primera vez que sea requerida. Luego, cuando otro usuario requiera dicha libreria, ésta será devuelta por el maven proxy evitandole al usuario la espera de la descarga.
  • Evitar dependencias faltantes
    • Existen ciertas depedencias, que no son de dominio público. Por razones de licencias, no pueden estar expuestas en internet. Entonces, maven al querer utilizar las dependencias, no podrá bajarlas lo que causará un error en la ejecución del comando, no permitiendo que éste se complete. Para solucionar esto, teniendo un maven proxy, podemos ubicar la dependencia manualmente en el repositorio.
    • Debido a que no es requerido por los creadores de proyectos java el uso de maven, pueden existir ciertas dependencias de nuestro proyecto que no podremos encontrar en repositorios de internet, porque no fueron publicadas. Dichas dependencias también deben ser manualmente ubicadas en el proxy de maven.

Herramientas: Repositorios compartidos

Archiva (de Apache)

  • Open Source
  • Gratuito
  • Interfaz web
  • Seguridad con varios perfiles
  • Sencilla configuración (del servidor y de los clientes)
    • Para configurar el acceso a dicho proxy en las computadoras de la red, en el archivo settings.xml de la instalación local de maven, colocar lo siguiente, dentro del tag :

<mirror>
    <id>archiva.default</id>
    <ur<x>l>http://NOMBRE-DEL-SERVER:8080/archiva/repository/internal/</ur<x>l>
    <mirrorOf>*</mirrorOf>
</mirror>

Mejoras a maven 2

Soporte nativo para multiproyecto

Scope de Dependencias

Cada una de las dependencias puede tener distinto alcance dentro del proyecto. Los scopes definidos son:

  • test
  • compile
  • runtime
  • provided
  • system

En el caso de los proyectos web, con los alcances test, provided y system, una dependencia no se incluirá en el war (que es generado por los goals package, install o deploy).

Resolución automática de dependencias transitivas

Supongamos el siguiente caso: nuestro proyecto depende de struts y de hibernate, a su vez, hibernate depende de log4j. Maven2 resuelve automáticamente la dependencia de log4j.

Unificación de archivos de configuración

Los archivos de configuración que se utilizan ahora son el pom.xml (define la configuración del proyecto) y settings.xml (define la configuración global o a nivel de usuario).

Ciclo de vida

Maven 2 está enfocado en el concepto de ciclo de vida de un proyecto. El POM de un proyecto tiene definido un tipo de artefacto producto, en la etiqueta . Este tipo de artefacto determina el ciclo de vida del proyecto. Para el tipo de artefacto jar las fases son:

Goal Binding artifactId prefix goal
validate -
[initialize] -
generate-sources -
process-sources -
generate-resources -
process-resources maven-resources-plugin resources resources
compile maven-compiler-plugin compiler compile
process-classes -
generate-test-sources -
process-test-sources -
generate-test-resources -
process-test-resources maven-resources-plugin resources testResources
test-compile maven-compiler-plugin compiler testCompile
test maven-surefire-plugin surefire test
package maven-jar-plugin jar jar
integration-test -
verify -
install maven-install-plugin install install
deploy maven-deploy-plugin deploy deploy

La columna goal indica cuáles de las fases se pueden "obtener". Al ejecutar maven con un determinado goal, se ejecutan todas las fases hasta la correspondiente al goal. Así, por ejemplo, si se desea crear el jar del proyecto, se ejecuta maven package. Si se desea recompilar todos los fuentes, se ejecuta maven compile. Ejecutar "maven compile" va hacer que se ejecute también todas las fases anteriores en el ciclo de vida, como la generación de fuentes y recursos.

Existen objetivos (goal) con sus propios ciclos de vida. Por ejemplo, maven clean elimina todos los productos del proyecto (todo bajo el directorio target). Se puede poner más de un objetivo en los argumentos y se ejecutan en secuencia.

Si se quiere ejecutar un plugin específico se debe usar la sintaxis plugin:goal.

Plugins hechos con Java

Los plug-ins se implementan directamente en Java en vez de usar Jelly, como en Maven 1. Simplificaron los archivos de configuración y definieron una manera standard de configurar los plugins.

Conceptos importantes para usuarios de Maven 1

Como está explicado arriba, Maven 2 tiene un concepto de goal distinto. En Maven 1 para compilar se ejecuta el comando: >maven java:compile indicando que se desea ejecutar el goal compile del plugin java. Además cada plugin tiene un objetivo por defecto. Por ejemplo, compile es el objetivo por defecto del plugin java. Por lo que ejecutar >maven java es equivalente al comando anterior. En maven 2 los goal son referidos al ciclo de vida. Se puede todavía utilizar la sintaxis plugin:goal", pero no existe el concepto de goal'' por defecto para un plugin, por lo cual ejecutar >mvn eclipse producirá un error al no encontrar el goal "eclipse" en el ciclo de vida del proyecto.

Maven Profiles
 
Permite configurar diferentes aspectos de la compilación (y otras etapas) de un proyecto Maven. Dependiendo del profile se active, será esa la configuración utilizada. Esta es una forma de hacer que un proyecto sea portable, configurando en los profiles las cosas que sean sensibles al entorno.
 
 
Niveles


 
Hay en principio 3 niveles donde podemos configurar los profiles (para Maven 2).
 
Global: definiéndolo en el archivo %M2_HOME%/conf/settings.xml, cada profile está definido entre los tags     <profiles> y se indica cuales estarán activados para todos los casos dentro del tag <activeProfiles>.
 
Por usuario: definido en el archivo %USER_HOME%/.m2/settings.xml, de la misma forma que en el caso global.
 
Y por proyecto: Es el caso que se va a abordar, definidos en el pom.xml de cada proyecto donde queremos que se aplique esta configuración por profiles.
 
 
Cada nivel superior abarca los niveles inferiores, esto significa que si realizo cambios en el settings.xml dentro de %M2_HOME%/conf, estos tendran alcance de efecto en los niveles por usuario y por proyecto.
Tanto los profiles definidos en forma global o por usuario (externos a un proyecto en particular) tienen mucho menos poder de configuración (solo se pueden configurar los Repositories, pluginRepositories y algunas properties)
 
 
 
pom.xml

 
<proyect>
...
   <profiles>  
       <profile>
          <id>ID_DEL_PROFILE</id>
          <activation>
              condiciones de activación (no son obligatorias)
          </activation>  
 
          Aca van, las propiedades definidas en este profile,
          la configuracion de plugins, tareas a ejecutar, etc

       </profile>
      ...
   </profiles>
...
</proyect>
 
 
 
 
Alcance

 
Estos items del pom pueden ser modificados por profile

  • <repositories>
  • <pluginRepositories>
  • <dependencies>
  • <plugins>
  • <properties>
  • <modules>
  • <reporting>
  • <dependencyManagement>
  • <distributionManagement>
  • <build> :
    • <defaultGoal>
    • <resources>
    • <testResources>
    • <finalName>
 
 
Por ejemplo, en el pom puedo tener ciertas variables cuyo valor depende del profile que se activa.
<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.myco.plugins</groupId>
        <artifactId>spiffy-integrationTest-plugin</artifactId>
        <version>1.0</version>
        <configuration>
          <appserverHome>${appserver.home}</appserverHome>
        </configuration>
      </plugin>
      ...
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>appserverConfig-dev</id>
      <activation>
          ...
      </activation>
      <properties>
        <appserver.home>/path/to/dev/appserver</appserver.home>
      </properties>
    </profile>

    <profile>
      <id>appserverConfig-dev-2</id>
      <activation>
          ...
      </activation>
      <properties>
        <appserver.home>/path/to/another/dev/appserver2</appserver.home>
      </properties>
    </profile>
  </profiles>
  ...
</project>
 
Si el profile activado es appserverConfig-dev, la variable ${appserver.home} tendrá el valor /path/to/dev/appserver
 
 
 
 
Activación de un profile

  • Default:

 <profile>
    <id>desarrollo</id>
    <activation>
       <activeByDefault>true</activeByDefault>
    </activation>

    ...
  </profile>

  • Explícitamente por linea de comandos:

           A través de la consola, cuando ejecutames un goal de maven, de la siguiente forma

       mvn goal -P profileId
      Ejemplo: mvn package -P desarrollo (donde "desarrollo" es el ID del profile)
 
  • Por variables de sistema:

Por presencia de la variable (no importa el valor):

<profiles>
  <profile>
    <activation>
      <property>
        <name>debug</name>
      </property>
    </activation>
    ...
  </profile>
</profiles>

O por valor:

<profiles>
  <profile>
    <activation>
      <property>
        <name>environment</name>
        <value>test</value>
      </property>
    </activation>
    ...
  </profile>
</profiles>
 
Se define una variable del sistema de la siguiente manera:
mvn groupId:artifactId:goal -Denvironment=test
 
  • Versión de JDK:
  <profile>
    <activation>
      <jdk>1.4</jdk>
    </activation>
    ...
  </profile>
 
<profiles>
  <profile>
    <activation>
      <jdk>[1.3,1.6)</jdk>
    </activation>
    ...
  </profile>
</profiles>

   En este último caso, se activa si la version es mayor o igual a la 1.3, pero menor a la 1.6

 

  • Atributos del sistema operativo:
<profiles>
  <profile>
    <activation>
      <os>
        <name>Windows XP</name>
        <family>Windows</family>
        <arch>x86</arch>
        <version>5.1.2600</version>
      </os>
    </activation>
    ...
  </profile>
</profiles>
  • Presencia o ausencia de archivos:

Ausencia:

<profiles>
  <profile>
    <activation>
      <file>
        <missing>target/generated-sources/org/apache/maven</missing>
      </file>
    </activation>
    ...
  </profile>
</profiles>

Presencia:

    <activation>
      <file>
       
<exists>target/generated-sources/org/apache/maven</exists>
      </file>
    </activation>

 

 

Tasks


Para la ejecución de tasks, configuramos el plugin maven-antrun-plugin, de forma tal que en cada profile, en el goal que le especificamos, ejecute las tasks definidas, por ejemplo borrar y copiar archivos.

<profile>
    <id>desarrollo</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>  
    <build>
       <plugins>
          <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <executions>
             <execution>
                 <phase>prepare-package</phase>
                 <goals>
                     <goal>run</goal>
                 </goals>
                 <configuration>
                     <tasks>
                         <delete file="${project.build.outputDirectory}/conexionActual.properties"/>
                         <copy file="src/main/resources/profiles/desarrollo/conexionActual.dev.properties" tofile="${project.build.outputDirectory}/conexionActual.properties"/>  

                    </tasks>
                </configuration>
            </execution>
         </executions>
       </plugin>
    </plugins>
  </build>
</profile>

 

 


Tips Interesantes

Chequeo de pom

Si necesitamos saber como va a quedar nuestro pom antes de ser procesado por el interprete de maven, sólo tenemos que escribir ^ mvn help:effective-pom ^

Jar utilizados

Muchas veces necesitamos tener a mano todos los jars que utilizamos en el proyecto maven. La manera mas sencilla de obtenerlos es ejecutando el comando ^ mvn dependency:copy-dependencies ^ Con este comando tendrán todos los jars necesarios para el proyecto en la carpeta target/dependency

Maven como una Herramienta Externa (External Tool) en Eclipse

Si se desea ejecutar goals de maven dentro de la IDE, es posible configurar estos goals como una herramienta externa. Para esto, es una buena práctica agregar una variable a Eclipse que apunte a mvn.bat. Los pasos son
  1. Desde el Menú ir a Window>Preferences.
  2. Seleccionar Run/Debug>String Substitution.
  3. Presionar New y Agregar una nueva variable. Como ejemplo:
    • Name:maven_exec
    • Value:C:\aplicacionesj2ee\maven-2.0.4\bin
    • Description: el directorio bin de maven
Esta variable la usaremos a continuación cuando creemos un "programa" externo. Para ejemplificar la creación de un programa externo daré los pasos para correr mvn eclipse:eclipse a través de la IDE. Luego cada uno puede repetir el proceso para correr esos scripts tan cotidianos y no tener que usar una consola externa. Los pasos son:
  1. Desde el Menú ir a Run>External Tools>External Tools...>Seleccionar Program.
  2. Presionar New, lo cual creará un programa en blanco con el nombre New_configuration
  3. Cambiar Name por un nombre más significativo como MavenEclipse
  4. Ingresar la ubicacion de mvn.bat en Location
    1. Presionar Variables y seleccionar la variable maven_exec
    2. agregar \mvn.bat
    3. Location tendrá ${maven_exec}\mvn.bat
  5. Ingresar Working Directory
    1. Presionar Variables y seleccionar la variable project_loc
  6. Ingresar eclipse:eclipse en Arguments
El resultado será Name: ))MavenEclipse((
  • Main
    • Location:${maven_exec}\mvn.bat
    • Working Directory:${project_loc}
    • Arguments: eclipse:eclipse
Entonces resta ejecutarlo a través del menú Run>External Tools y elegir ))MavenEclipse(( o con el botón que se encuentra en la barra de herramientas.

Documentación existente

Bibliografía

Libro recomendado

"Better Builds with Maven - How-to Guide for Maven2", Vincent Massol y Jason Van Zyl, Mergere Library Press, Junio 2006

Nota introductoria de maven 2.

http://www.javaworld.com/javaworld/jw-12-2005/jw-1205-maven.html?lsrc=jwrss (external link) Está bastante buena. la intro si se desea agregar información o pasar un artículo a alguien.

Ciclos de vida de Maven 2

http://cvs.peopleware.be/training/maven/Maven2/buildLifecyclePhases.html (external link) Tiene resumidos los ciclos de vida para cada tipo de packaging.

Otras páginas de interés


Contribuyentes a esta página: flor13211 puntos  , lucianod1282 puntos  , NataliaR , The Greek , PabloLFC9712 puntos  , bernardoc , diegom , Acuariano , nicokiki , Quirón19361 puntos  y gianu .
Page last modified on Jueves 05 de Julio, 2012 12:38:28 EDT by flor13211 puntos .
El contenido de esta página esta licenciado bajo los términos del http://creativecommons.org/licenses/by-sa/2.5/legalcode.

Usuarios en línea

14 usuarios en línea