maven maven-3

¿Cómo estructurar un proyecto de varios módulos de Maven para compilarlo a la vez?



maven-3 (1)

Tengo un proyecto de Maven con múltiples módulos y submódulos y quiero compilarlo a la vez, es decir, usar solo una llamada para "instalar mvn clean".

Para un proyecto básico, la siguiente estructura funcionaría:

. ├── modules │   ├── moduleA │   │   └── pom.xml <--- Module A POM │   ├── moduleB │   │   └── pom.xml <--- Module B POM │   └── pom.xml <--- Super POM (at the root of "modules" folder) └── pom.xml <--- Aggregator POM

Con el agregador siendo:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.test</groupId> <artifactId>aggregator</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <modules> <module>modules</module> <module>modules/moduleA</module> <module>modules/moduleB</module> </modules> </project>

El Super POM:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.test</groupId> <artifactId>super-pom</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> </project>

Módulo A''s POM:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>moduleA</artifactId> <parent> <groupId>org.test</groupId> <artifactId>super-pom</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> </project>

El módulo B es similar.

Cuando se encuentra en la raíz del proyecto, ejecutar el comando "mvn clean install" (después de limpiar la carpeta .m2 / repository):

[...] [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] super-pom .......................................... SUCCESS [ 0.450 s] [INFO] moduleA ............................................ SUCCESS [ 1.746 s] [INFO] moduleB ............................................ SUCCESS [ 0.029 s] [INFO] agregator .......................................... SUCCESS [ 0.006 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS

Ahora, si quiero algo que sea más complejo (pero que todavía use un súper POM), como:

. ├── modules │   ├── lib1 │   │   ├── moduleA1 │   │   │   └── pom.xml │   │   ├── moduleB1 │   │   │   └── pom.xml │   │   └── pom.xml <--- lib1 aggregator POM │   ├── lib2 │   │   ├── moduleA2 │   │   │   └── pom.xml │   │   ├── moduleB2 │   │   │   └── pom.xml │   │   └── pom.xml <--- lib2 aggregator POM │   └── pom.xml <--- Super POM └── pom.xml <--- Aggregator POM

Con la raíz POM siendo:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.test</groupId> <artifactId>agregator</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <modules> <module>modules</module> <module>modules/lib1</module> <module>modules/lib2</module> </modules> </project>

Lib1 POM:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.test</groupId> <artifactId>lib1-agregator</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <modules> <module>moduleA1</module> <module>moduleB1</module> </modules> </project>

Y, por ejemplo moduleA1 POM:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>moduleA1</artifactId> <parent> <groupId>org.test</groupId> <artifactId>super-pom</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> </project>

Maven no logra resolver los archivos POM (después de limpiar la carpeta .m2 / repository):

[INFO] Scanning for projects... [ERROR] [ERROR] Some problems were encountered while processing the POMs: [WARNING] ''parent.relativePath'' of POM org.test:moduleA1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleA1/pom.xml) points at org.test:lib1-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13 [FATAL] Non-resolvable parent POM for org.test:moduleA1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 [WARNING] ''parent.relativePath'' of POM org.test:moduleB1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleB1/pom.xml) points at org.test:lib1-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13 [FATAL] Non-resolvable parent POM for org.test:moduleB1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 [WARNING] ''parent.relativePath'' of POM org.test:moduleA2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleA2/pom.xml) points at org.test:lib2-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13 [FATAL] Non-resolvable parent POM for org.test:moduleA2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 [WARNING] ''parent.relativePath'' of POM org.test:moduleB2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleB2/pom.xml) points at org.test:lib2-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13 [FATAL] Non-resolvable parent POM for org.test:moduleB2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 @ [ERROR] The build could not read 4 projects -> [Help 1] [ERROR] [ERROR] The project org.test:moduleA1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleA1/pom.xml) has 1 error [ERROR] Non-resolvable parent POM for org.test:moduleA1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 -> [Help 2] [ERROR] [ERROR] The project org.test:moduleB1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleB1/pom.xml) has 1 error [ERROR] Non-resolvable parent POM for org.test:moduleB1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 -> [Help 2] [ERROR] [ERROR] The project org.test:moduleA2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleA2/pom.xml) has 1 error [ERROR] Non-resolvable parent POM for org.test:moduleA2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 -> [Help 2] [ERROR] [ERROR] The project org.test:moduleB2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleB2/pom.xml) has 1 error [ERROR] Non-resolvable parent POM for org.test:moduleB2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and ''parent.relativePath'' points at wrong local POM @ line 7, column 13 -> [Help 2] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException

Necesito primero construir el super pom:

cd modules/ mvn clean install

Y sólo entonces se compilará:

[INFO] Reactor Summary: [INFO] [INFO] super-pom .......................................... SUCCESS [ 0.271 s] [INFO] moduleA1 ........................................... SUCCESS [ 1.202 s] [INFO] moduleB1 ........................................... SUCCESS [ 0.027 s] [INFO] lib1-agregator ..................................... SUCCESS [ 0.006 s] [INFO] moduleA2 ........................................... SUCCESS [ 0.027 s] [INFO] moduleB2 ........................................... SUCCESS [ 0.022 s] [INFO] lib2-agregator ..................................... SUCCESS [ 0.007 s] [INFO] agregator .......................................... SUCCESS [ 0.007 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS

¿Cómo estructuraría el proyecto para que funcione sin esta compilación de dos pasos?

[EDITAR]: como se discutió en los comentarios, agregar la ruta relativa del Super POM a los módulos POM haría que el código se compilara con una línea de comando.

Sin embargo, si quiero distribuir solo lib1 a algunos desarrolladores, a pesar de que mi súper POM está en un repositorio de Maven, lib1 no se compilaría sin toda la estructura del proyecto. Esto hace que el proyecto sea menos modular.


Déjame comenzar como lo hiciste, pero nombro las cosas un poco diferente:

. ├── modules-root │ ├── moduleA │ │ └── pom.xml <--- Module A POM │ ├── moduleB │ │ └── pom.xml <--- Module B POM │ └── pom.xml <--- modules root └── pom.xml <--- project-root

Comencemos con la project-root del project-root , que se verá así:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.test</groupId> <artifactId>project-root</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> <modules> <module>modules-root</module> </modules> </project>

El module parent se verá así. moduleA que esto contiene solo la referencia al moduleA y el moduleA y moduleB de la project-root del project-root :

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.test</groupId> <artifactId>super-pom</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <groupId>org.test.module</groupId> <artifactId>modules-root</artifactId> <packaging>pom</packaging> <modules> <module>moduleA</module> <module>moduleB</module> </modules> </project>

moduleA se verá así. Preste atención a que esto heredará del module-parent (padre), que es exactamente un nivel por encima de ...

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.test.module</groupId> <artifactId>module-parent</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>moduleA</artifactId> <packaging>..</packaging> <....other dependencies..> </project>

Si usa este tipo de estructura, simplemente puede ir al nivel de project-root del project-root y hacer:

mvn clean install

Además después puedes usar cosas como esta:

mvn -pl moduleA ...

... para construir solo el módulo A (pero permanecer en el nivel de project-root del project-root ...).

module-parent puede parecer desperdiciado o superfluo en este ejemplo, pero si obtiene más módulos, puede definir sus dependencias adicionales a través de dependencyManagement o puede cambiar las configuraciones de complementos a través de pluginManagement que solo se usarán en esta subárea (móduloA, móduloB, ... .). Si su proyecto se hace más grande, obtendrá más módulos de padres en paralelo ... que contienen diferentes partes de sus aplicaciones ... y diferentes intenciones que pueden lograrse con esta estructura.

Una cosa más es mencionar. He cambiado el groupId de groupId de org.test a org.test.module en el módulo-padre. Esto a veces es útil si tiene una gran cantidad de módulos, ya que groupId representa la estructura de carpetas en su repositorio (como hacen los paquetes java en un proyecto Java) ... esto le brinda una mejor visión general ...

La project-root es la ubicación para definir las dependencias usables en general a través de dependencyManagement etc ... y los complementos utilizados que deben definirse a través de pluginManagement ... o pueden estar usando maven-enforcer-plugin para definir las reglas generales del proyecto ...

Los escenarios típicos para este tipo de estructura son los proyectos Java EE u otros proyectos grandes (pueden ser con 300 ... o 1000 módulos, sí existen) ...

Si obtiene más módulos, puede usar la capacidad multihilo de maven y construir su proyecto con:

mvn -T 4 clean install

de la project-root del project-root que reduce el tiempo de construcción dramáticamente.