Solución a errores de dependencias en proyectos multi-módulo de Spring Boot con Maven

En arquitecturas de microservicios o proyectos multi-módulo, es común encontrar un error durente la ejecución de mvn install o mvn package donde el compilador indica que no puede encontrar símbolos de clases ubicadas en módulos compartidos, a pesar de que la aplicación se ejecuta correctamente desde el entorno de desarrollo.

Análisis del problema

Este comportamiento se origina por la forma en que spring-boot-maven-plugin gestiona el empaquetado. A diferencia del plugin estándar de Apache Maven, el plugin de Spring Boot ejecuta una tarea de repackage que transforma el JAR original en un archivo ejecutable (fat JAR). Cuando un módulo de biblioteca compartida se empaqueta de esta manera, su estructura interna de clases se modifica para aislar las dependencias. Como resultado, otros módulos que dependen de esta biblioteca no pueden resolver sus clases durante la fase de compilación de Maven.

Implementación de la solución

Para resolver este conflicto, el plugin de Spring Boot debe aplicarse exclusivamente a los módulos que contienen un punto de entrada ejecutable (clases anotadas con @SpringBootApplication), y nunca a los módulos que funcionan únicamente como librerías de apoyo.

1. Limpieza del POM padre

El primer paso es asegurar que el archivo pom.xml raíz no declare la sección <build> con el plugin de Spring Boot. El POM padre solo debe gestionar dependencias, versiones y propiedades globales.

<?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>
    
    <groupId>com.nexus.platform</groupId>
    <artifactId>nexus-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>nexus-gateway</module>
        <module>nexus-service</module>
        <module>nexus-core</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2021.0.5</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.nexus.platform</groupId>
                <artifactId>nexus-core</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2. Configuración en módulos ejecutables

En los módulos que representan servicios independientes o aplicaciones desplegables, se debe incluir explícitamente el plugin dentro de la sección <build>.

<?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">
    <parent>
        <groupId>com.nexus.platform</groupId>
        <artifactId>nexus-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>nexus-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.nexus.platform</groupId>
            <artifactId>nexus-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. Mantenimiento de módulos de biblioteca

Los módulos diseñados para ser consumidos como dependencias internas no deben contener ninguna configuración del plugin de Spring Boot. Al omitir la sección <build>, Maven utilizará el empaquetado JAR estándar, preservando la estructura de clases necesaria para la compilación cruzada entre módulos.

<?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">
    <parent>
        <groupId>com.nexus.platform</groupId>
        <artifactId>nexus-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>nexus-core</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
    </dependencies>
</project>

Etiquetas: spring-boot maven multi-module spring-cloud java

Publicado el 7-11 18:44