Maven, como herramienta central en el desarrollo de software Java, ofrece no solo una gestión de dependencias eficiente sino también una funcionalidad avanzada para la herencia de proyectos. Hoy exploraremos la gestión de dependencias en Maven, sus ventajas y desventajas, así como opciones avanzadas como dependencias opcionales, scopes y exclusiones. Luego, nos sumergiremos en la herencia de proyectos, destacando cómo crear un proyecto que herede de una clase padre y cómo referenciarlo en el pom.xml del proyecto hijo.

Usualmente este tipo de proyectos en Maven trabajan con una arquitectura de proyecto monolítico, esto significa que la mayoría de sus funcionalidades van a heredar de un proyecto base, este proyecto base tendrá será el padre y todos los demás proyectos sus hijos.

Gestión de dependencias en Maven

Ventajas de la gestión de dependencias:

  1. Centralización: Maven centraliza la información de dependencias en el archivo pom.xml, simplificando la comprensión y el mantenimiento del proyecto.
  2. Automatización de descargas: Maven automatiza la descarga de dependencias desde repositorios remotos, eliminando la necesidad de gestionarlas manualmente.
  3. Versionamiento coherente: Permite especificar rangos de versiones para garantizar coherencia y evitar conflictos.

Desventajas de la gestión de dependencias:

  1. Complejidad inicial: La configuración inicial del pom.xml puede parecer compleja para principiantes, aunque esta complejidad se compensa con la eficiencia a largo plazo.
  2. Dependencia de la red: Requiere acceso a Internet para descargar dependencias, lo que puede ser una limitación en entornos sin acceso a internet.

Opciones avanzadas para la gestión de dependencias:

Optional:

La etiqueta <optional> permite marcar dependencias como opcionales. Estas dependencias no se incluirán automáticamente en los proyectos que utilicen el actual, pero los desarrolladores pueden optar por incluirlas explícitamente. Esta etiqueta ayuda cuando tenemos múltiples proyectos que heredan la misma librería a un mismo proyecto, de esta manera se gestionará el uso de solo una y las demás serán opcionales.

<dependency>
    <groupId>org.example</groupId>
    <artifactId>optional-library</artifactId>
    <version>1.0</version>
    <optional>true</optional>
</dependency>

Scope:

La etiqueta <scope> permite especificar el alcance de la dependencia. Por ejemplo, las dependencias con alcance test solo están disponibles durante la fase de prueba.

Existen varios tipos de scope dependiendo de la necesidad del proyecto:

  • compile (sino ponemos un scope es el usado por defecto): La dependencia es necesaria para compilar el código fuente del proyecto y también para ejecutar y probar el código.
  • provided: La dependencia es necesaria para compilar el código fuente del proyecto, pero se espera que esté proporcionada por el entorno de ejecución (como el contenedor de servlets en el caso de un proyecto web). Esto funciona para cuando tenemos un servidor de aplicaciones que nos inyecta dependencias propias y que sino colocamos esta etiqueta, podemos presentar conflictos entre librerías del servidor y de la aplicación.
  • runtime: La dependencia no es necesaria para compilar el código fuente, pero es necesaria para la ejecución y las pruebas.
  • test: La dependencia solo es necesaria para la ejecución de pruebas, no para compilar el código fuente del proyecto.
  • system: Similar a provided, pero se espera que la librería esté disponible en el sistema de archivos. A menudo se utiliza para dependencias que no están disponibles en repositorios Maven o en el servidor de aplicaciones.
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>provided</scope>
</dependency>

Exclusión de dependencias:

La exclusión de dependencias permite evitar la inclusión de ciertas dependencias, esto funciona especialmente cuando tenemos librerías que ya vienen implicitas en otras librerías, por ejemplo cuando usamos Spring framework que ya trae una serie de librerías incluídas, si hubiera alguna que nos genere un problema de compatibilidad o de ejecución, la podríamos excluir:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
		<exclusions>
		     <exclusion>
		         <groupId>org.hibernate.validator</groupId>
		         <artifactId>hibernate-validator</artifactId>
		      </exclusion>
		 </exclusions>
</dependency>

Herencia de proyectos en Maven

La herencia de proyectos en Maven permite la creación de una jerarquía, donde un proyecto principal (padre) define configuraciones comunes y los proyectos secundarios (hijos) heredan esas configuraciones. Veamos un ejemplo:

Creación de un proyecto padre:

Crearemos un proyecto Maven y dentro del pom.xml añadiremos lo siguiente:

<!-- pom.xml en el Proyecto Padre -->
<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.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <properties>
        <!-- Propiedades comunes -->
    </properties>

    <dependencies>
        <!-- Dependencias comunes -->
    </dependencies>
</project>

Creación de un proyecto hijo:

Ahora en la creación del proyecto hijo, deberemos usar las etiquetas <parent> donde indicaremos la información del proyecto padre:

<!-- pom.xml en el Proyecto Hijo -->
<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>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>child-project</artifactId>
    <version>1.0.0</version>

    <dependencies>
        <!-- Dependencias adicionales del proyecto hijo -->
    </dependencies>
</project>

Referenciando el proyecto hijo en el proyecto padre:

Y por último haremos referencia al proyecto padre colocando la etiquete modules y child-project:

<!-- pom.xml en el Proyecto Padre -->
<project ...>
    ...
    <modules>
        <module>child-project</module>
    </modules>
    ...
</project>

Con esta estructura, el proyecto hijo hereda las configuraciones del proyecto padre, permitiendo una gestión eficiente y coherente de proyectos más complejos.

Heredando dependencias

Ahora para el caso de heredar dependencias, en la clase padre se deberá colocar la dependencia completa con su número de versión:

<dependency>
	<groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.3.3.RELEASE</version>
</dependency>

Sin embargo, la diferencia viene cuando la heredamos al hijo, en este caso se deberá colocar sin la versión y dentro de las etiquetas <dependencyManagement>:

<dependencyManagement>
		<dependencies>
            <groupId>org.springframework.security.oauth.boot</groupId>
			<artifactId>spring-security-oauth2-autoconfigure</artifactId>
        </dependencies>
</dependencyManagement>

De esta manera, las versiones de las dependencias se centrarán en la clase padre y solamente se heredarán las dependencias que coloquemos en la clase hijo, así ante una posible migración a nuevas versiones, todo se mantendrá centralizado en el proyecto padre.

Maven ofrece una solución integral para la gestión de dependencias y la herencia de proyectos en el desarrollo de software Java. La combinación de estas características proporciona un marco robusto y escalable para proyectos de cualquier tamaño. Al entender y aprovechar estas herramientas, los desarrolladores pueden construir y mantener proyectos Java de manera más eficiente y coherente.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *