Tutorial de Apache Maven

1. Introducción

La construcción de un proyecto de software generalmente consiste en tareas tales como descargar dependencias, colocar archivos jar adicionales en una ruta de clases, compilar el código fuente en código binario, ejecutar pruebas, empaquetar código compilado en artefactos implementables como archivos JAR, WAR y ZIP, y desplegar estos artefactos. a un servidor de aplicaciones o repositorio.

Apache Maven automatiza estas tareas, minimizando el riesgo de que los humanos cometan errores al crear el software manualmente y separando el trabajo de compilar y empaquetar nuestro código del de la construcción del código.

En este tutorial, exploraremos esta poderosa herramienta para describir, construir y administrar proyectos de software Java utilizando una pieza central de información, el Modelo de Objetos del Proyecto (POM), que está escrito en XML.

2. ¿Por qué utilizar Maven?

Las características clave de Maven son:

  • Configuración de proyecto simple que sigue las mejores prácticas: Maven intenta evitar la mayor cantidad de configuración posible, proporcionando plantillas de proyecto (denominadas arquetipos )
  • gestión de dependencias: incluye actualización automática, descarga y validación de la compatibilidad, así como reportar los cierres de dependencias (conocidas también como dependencias transitivas)
  • aislamiento entre las dependencias del proyecto y los complementos: con Maven, las dependencias del proyecto se recuperan de los repositorios de dependencias, mientras que las dependencias de los complementos se recuperan de los repositorios de complementos, lo que resulta en menos conflictos cuando los complementos comienzan a descargar dependencias adicionales
  • sistema de repositorio central: las dependencias del proyecto se pueden cargar desde el sistema de archivos local o desde repositorios públicos, como Maven Central
Para aprender a instalar Maven en su sistema, consulte este tutorial sobre Baeldung.

3. Modelo de objetos del proyecto

La configuración de un proyecto Maven se realiza a través de un Modelo de Objetos de Proyecto (POM) , representado por un archivo pom.xml . El POM describe el proyecto, administra las dependencias y configura complementos para construir el software.

El POM también define las relaciones entre módulos de proyectos de varios módulos. Veamos la estructura básica de un archivo POM típico :

 4.0.0 org.baeldung org.baeldung jar 1.0-SNAPSHOT org.baeldung //maven.apache.org   junit junit 4.12 test      //...    

Echemos un vistazo más de cerca a estas construcciones.

3.1. Identificadores de proyectos

Maven usa un conjunto de identificadores, también llamados coordenadas, para identificar de forma única un proyecto y especificar cómo se debe empaquetar el artefacto del proyecto:

  • groupId : un nombre base único de la empresa o grupo que creó el proyecto
  • artifactId : un nombre único del proyecto
  • versión : una versión del proyecto
  • embalaje : un método de embalaje (por ejemplo, WAR / JAR / ZIP )

Los primeros tres de estos ( groupId: artifactId: version ) se combinan para formar el identificador único y son el mecanismo mediante el cual especifica qué versiones de bibliotecas externas (por ejemplo, JAR) utilizará su proyecto.

3.2. Dependencias

Estas bibliotecas externas que utiliza un proyecto se denominan dependencias. La función de administración de dependencias en Maven asegura la descarga automática de esas bibliotecas desde un repositorio central, por lo que no tiene que almacenarlas localmente.

Esta es una característica clave de Maven y proporciona los siguientes beneficios:

  • utiliza menos almacenamiento al reducir significativamente la cantidad de descargas desde repositorios remotos
  • agiliza la comprobación de un proyecto
  • proporciona una plataforma eficaz para intercambiar artefactos binarios dentro de su organización y más allá sin la necesidad de construir artefactos desde la fuente cada vez

Para declarar una dependencia en una biblioteca externa, debe proporcionar groupId, artifactId y la versión de la biblioteca. Echemos un vistazo a un ejemplo:

 org.springframework spring-core 4.3.5.RELEASE 

A medida que Maven procesa las dependencias, descargará la biblioteca Spring Core en su repositorio local de Maven.

3.3. Repositorios

Un repositorio en Maven se usa para almacenar artefactos de compilación y dependencias de diferentes tipos. El repositorio local predeterminado se encuentra en la carpeta .m2 / repository en el directorio de inicio del usuario.

Si hay un artefacto o un complemento disponible en el repositorio local, Maven lo usa. De lo contrario, se descarga de un repositorio central y se almacena en el repositorio local. El repositorio central predeterminado es Maven Central.

Algunas bibliotecas, como el servidor JBoss, no están disponibles en el repositorio central pero están disponibles en un repositorio alternativo. Para esas bibliotecas, debe proporcionar la URL del repositorio alternativo dentro del archivo pom.xml :

  JBoss repository //repository.jboss.org/nexus/content/groups/public/  

Tenga en cuenta que puede utilizar varios repositorios en sus proyectos.

3.4. Propiedades

Las propiedades personalizadas pueden ayudar a que su archivo pom.xml sea ​​más fácil de leer y mantener. En el caso de uso clásico, usaría propiedades personalizadas para definir versiones para las dependencias de su proyecto.

Las propiedades de Maven son marcadores de posición de valor y se puede acceder a ellas en cualquier lugar dentro de un pom.xml utilizando la notación $ {nombre} , donde nombre es la propiedad.

Veamos un ejemplo:

 4.3.5.RELEASE    org.springframework spring-core ${spring.version}   org.springframework spring-context ${spring.version}  

Ahora, si desea actualizar Spring a una versión más reciente, solo tiene que cambiar el valor dentro deletiqueta de propiedad y todas las dependencias que utilizan esa propiedad en su Se actualizarán las etiquetas.

Las propiedades también se utilizan a menudo para definir variables de ruta de construcción:

 ${project.build.directory}/tmp/   //... ${project.resources.build.folder} //... 

3.5. Construir

The build section is also a very important section of the Maven POM. It provides information about the default Maven goal, the directory for the compiled project, and the final name of the application. The default build section looks like this:

 install ${basedir}/target ${artifactId}-${version}  filters/filter1.properties  //... 

The default output folder for compiled artifacts is named target, and the final name of the packaged artifact consists of the artifactId and version, but you can change it at any time.

3.6. Using Profiles

Another important feature of Maven is its support for profiles. A profile is basically a set of configuration values. By using profiles, you can customize the build for different environments such as Production/Test/Development:

  production    //...      development  true     //...     

As you can see in the example above, the default profile is set to development. If you want to run the production profile, you can use the following Maven command:

mvn clean install -Pproduction

4. Maven Build Lifecycles

Every Maven build follows a specified lifecycle. You can execute several build lifecyclegoals, including the ones to compile the project’s code, create a package, and install the archive file in the local Maven dependency repository.

4.1. Lifecycle Phases

The following list shows the most important Maven lifecycle phases:

  • validate – checks the correctness of the project
  • compile – compiles the provided source code into binary artifacts
  • test – executes unit tests
  • package – packages compiled code into an archive file
  • integration-test – executes additional tests, which require the packaging
  • verify – checks if the package is valid
  • install – installs the package file into the local Maven repository
  • deploy – deploys the package file to a remote server or repository

4.2. Plugins and Goals

A Maven plugin is a collection of one or more goals. Goals are executed in phases, which helps to determine the order in which the goals are executed.

The rich list of plugins that are officially supported by Maven is available here. There is also an interesting article how to build an executable JAR on Baeldung using various plugins.

To gain a better understanding of which goals are run in which phases by default, take a look at the default Maven lifecycle bindings.

To go through any one of the above phases, we just have to call one command:

mvn 

For example, mvn clean install will remove the previously created jar/war/zip files and compiled classes (clean) and execute all the phases necessary to install new archive (install).

Please note that goals provided by plugins can be associated with different phases of the lifecycle.

5. Your First Maven Project

In this section, we will use the command line functionality of Maven to create a Java project.

5.1. Generating a Simple Java Project

In order to build a simple Java project, let's run the following command:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=org.baeldung.java -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

The groupId is a parameter indicating the group or individual that created a project, which is often a reversed company domain name. The artifactId is the base package name used in the project, and we use the standard archetype.

Since we didn't specify the version and the packaging type, these will be set to default values — the version will be set to 1.0-SNAPSHOT, and the packaging will be set to jar.

If you don't know which parameters to provide, you can always specify interactiveMode=true, so that Maven asks for all the required parameters.

After the command completes, we have a Java project containing an App.java class, which is just a simple “Hello World” program, in the src/main/java folder.

We also have an example test class in src/test/java. The pom.xml of this project will look similar to this:

 4.0.0 org.baeldung org.baeldung.java jar 1.0-SNAPSHOT org.baeldung.java //maven.apache.org   junit junit 4.1.2 test   

As you can see, the junit dependency is provided by default.

5.2. Compiling and Packaging a Project

The next step is to compile the project:

mvn compile

Maven will run through all lifecycle phases needed by the compile phase to build the project's sources. If you want to run only the test phase, you can use:

mvn test

Now let's invoke the package phase, which will produce the compiled archive jar file:

mvn package

5.3. Executing an Application

Finally, we are going to execute our Java project with the exec-maven-plugin. Let's configure the necessary plugins in the pom.xml:

 src   maven-compiler-plugin 3.6.1  1.8 1.8    org.codehaus.mojo exec-maven-plugin 1.5.0  org.baeldung.java.App    

The first plugin, maven-compiler-plugin, is responsible for compiling the source code using Java version 1.8. The exec-maven-plugin searches for the mainClass in our project.

To execute the application, we run the following command:

mvn exec:java

6. Multi-Module Projects

The mechanism in Maven that handles multi-module projects (also called aggregator projects) is called Reactor.

The Reactor collects all available modules to build, then sorts projects into the correct build order, and finally, builds them one by one.

Let's see how to create a multi-module parent project.

6.1. Create Parent Project

First of all, we need to create a parent project. In order to create a new project with the name parent-project, we use the following command:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=parent-project

Next, we update the packaging type inside the pom.xml file to indicate that this is a parent module:

pom

6.2. Create Submodule Projects

In the next step, we create submodule projects from the directory of parent-project:

cd parent-project mvn archetype:generate -DgroupId=org.baeldung -DartifactId=core mvn archetype:generate -DgroupId=org.baeldung -DartifactId=service mvn archetype:generate -DgroupId=org.baeldung -DartifactId=webapp

To verify if we created the submodules correctly, we look in the parent-project pom.xml file, where we should see three modules:

 core service webapp 

Moreover, a parent section will be added in each submodule’s pom.xml:

 org.baeldung parent-project 1.0-SNAPSHOT 

6.3. Enable Dependency Management in Parent Project

Dependency management is a mechanism for centralizing the dependency information for a muti-module parent project and its children.

When you have a set of projects or modules that inherit a common parent, you can put all the required information about the dependencies in the common pom.xml file. This will simplify the references to the artifacts in the child POMs.

Let's take a look at a sample parent's pom.xml:

   org.springframework spring-core 4.3.5.RELEASE  //...  

By declaring the spring-core version in the parent, all submodules that depend on spring-core can declare the dependency using only the groupId and artifactId, and the version will be inherited:

  org.springframework spring-core  //... 

Moreover, you can provide exclusions for dependency management in parent's pom.xml, so that specific libraries will not be inherited by child modules:

  org.springframework spring-context  

Finally, if a child module needs to use a different version of a managed dependency, you can override the managed version in child's pom.xml file:

 org.springframework spring-core 4.2.1.RELEASE 

Please note that while child modules inherit from their parent project, a parent project does not necessarily have any modules that it aggregates. On the other hand, a parent project may also aggregate projects that do not inherit from it.

For more information on inheritance and aggregation please refer to this documentation.

6.4. Updating the Submodules and Building a Project

We can change the packaging type of each submodule. For example, let's change the packaging of the webapp module to WAR by updating the pom.xml file:

war

Now we can test the build of our project by using the mvn clean install command. The output of the Maven logs should be similar to this:

[INFO] Scanning for projects... [INFO] Reactor build order: [INFO] parent-project [INFO] core [INFO] service [INFO] webapp //............. [INFO] ----------------------------------------- [INFO] Reactor Summary: [INFO] ----------------------------------------- [INFO] parent-project .................. SUCCESS [2.041s] [INFO] core ............................ SUCCESS [4.802s] [INFO] service ......................... SUCCESS [3.065s] [INFO] webapp .......................... SUCCESS [6.125s] [INFO] -----------------------------------------

7. Conclusion

En este artículo, discutimos algunas de las características más populares de la herramienta de compilación Apache Maven.

Todos los ejemplos de código en Baeldung se crean con Maven, por lo que puede consultar fácilmente nuestro sitio web del proyecto GitHub para ver varias configuraciones de Maven.