De null a full

Programación Java

View on GitHub

Maven

Maven es una herramienta de automatización de gestión de proyectos independiente del IDE.

Un proyecto Maven se reconoce por tener un fichero pom.xml en la carpeta raíz, que describe qué dependencias necesitamos y cómo se compila la aplicación.

Ejecutar un proyecto Maven

Para ejecutar un proyecto Maven, se ejecuta Maven (ya sea el incluído en el IDE o uno instalado normalmente) en la ruta donde esté el pom.xml con una serie de comandos.

La ejecución maven más común es compilar una aplicación, que suele hacerse con el comando

mvn clean install

Este comando ejecuta Maven, haciendo:

Crear un proyecto Maven

Podemos crear un proyecto Maven desde el IDE (por ejemplo, en IntelliJ es una opción en el menú “Nuevo proyecto” si tenemos instalado el plugin de Maven); para ello tenemos que especificar los siguientes parámetros:

Estructura por defecto de un proyecto Maven

Estructura de un pom.xml

En el xml de ejemplo a continuación encontrarás explicaciones de los distintos elementos que lo componen.

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <!-- A lo largo del pom se referencian otros proyectos maven como dependencias
         Estas se usan con el mismo formato de pom: groupId, artifactId, version
         Podemos buscar dependencias para proyectos en mvnrepository.com -->

    <!-- Indicar un proyecto padre es opcional, se usa para heredar configuraciones Maven -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>

    <!-- Propiedades usadas al crear el proyecto -->
    
    <!-- En un proyecto con padre puede no indicarse y usará el groupId del padre -->
    <groupId>es.danpintas</groupId> 
    <artifactId>proyecto-prueba</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- Tipo de aplicación a compilar:
         jar: valor por defecto, aplicación autoejecutable
         war: aplicación web para ser desplegada en un servidor (por ejemplo Tomcat)
         pom: el proyecto sólo tiene configuraciones y no se compila; 
              se usa principalmente en proyectos padre -->
    <packaging>jar</packaging>

    <!-- Propiedades para reutilizar en el pom -->
    <properties>

        <!-- Propiedades por defecto para indicar la versión de Java
             La versión de Java que usa por defecto es Java 5
             Hasta Java 8 se usa 1.version en vez de sólo la versión -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <!-- Propiedades por defecto para indicar la codificación de nuestros ficheros -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.report.outputEncoding>UTF-8</project.report.outputEncoding>

        <!-- Propiedad personalizada para la versión de una dependencia -->
        <mysql.version>8.0.20</mysql.version>

    </properties>

    <!-- Gestión de versiones de dependencias
         Esto es útil especialmente en poms padre cuando no todos los hijos 
         usan la dependencia pero queremos que todos usen la misma versión -->
    <dependencyManagement>
        <dependencies>

            <!-- Podemos importar un pom aquí 
                 para usar las mismas versiones de todas sus dependencias -->
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>8.8.2</version>
                <type>pom</type>
                <!-- Necesario cuando importamos un pom en dependencyManagement -->
                <scope>import</scope> 
            </dependency>

            <!-- También podemos usar dependencias simples -->
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>3.3.3</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <!-- Dependencias del proyecto, librerías que necesitamos para nuestro proyecto -->
    <dependencies>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version> <!-- referencia a una property -->
            <scope>runtime</scope>
        </dependency>

        <!-- Al ir gestionado por un pom en dependencyManagement la versión es opcional -->
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <!-- Alcance de la dependencia, nos indica cómo se gestiona 
                 para ejecutar y/o compilar la aplicación
                 - compile:  - valor por defecto
                             - disponible en main y test
                             - transitiva
                             - se compila
                 - test:     - solo disponible en test 
                             - no transitiva
                             - no se compila
                 - provided: - disponible en main y test
                             - no transitiva
                             - no se incluye en la compilación
                             - se usa principalmente en aplicaciones war 
                               para librerías que incluye el servidor
                 - runtime:  - disponible en main y test
                             - transitiva
                             - no se compila (ni es necesaria para compilar)
                             - usada en implementaciones de librerías comunes,
                               como drivers de base de datos

                 * Si una dependencia de un pom es transitiva, 
                   se importa también al importar dicho pom.
                   Es decir, si A importa a B y B tiene C como dependencia,
                   A importa también C si la dependencia de C en B es transitiva
                   con el mismo alcance con el que importa B-->
            <scope>test</scope>
        </dependency>
        
    </dependencies>

    <!-- Configuración de la compilación -->
    <build>
        <!-- Nombre de la aplicación compilada, 
             por defecto ${project.artifactId}-${project.version} -->
        <finalName>prueba</finalName>

        <plugins>
            <!-- Aquí se incluyen los plugins necesarios para la compilación -->
        </plugins>

    </build>
    
</project>

Ejercicios

Crea un nuevo proyecto Maven que:

Este ejercicio de prueba es simple, pero basta para practicar el uso más común de maven (gestión de dependencias); el resto de conceptos se pondrán en uso como parte de otros proyectos.