【发布时间】:2016-01-27 10:18:08
【问题描述】:
我有一个包含多个模块和子模块的 Maven 项目,我想一次编译它,即只使用一次“mvn clean install”调用。
对于一个基本项目,以下结构可以工作:
.
├── 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
聚合器是:
<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>
超级 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>
模块 A 的 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>
模块 B 类似。
在项目的根目录下,运行“mvn clean install”命令给出(清理 .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
现在,如果我想要更复杂的东西(但仍然使用一个超级 POM),例如:
.
├── 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
根 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>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>
并且,例如 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 无法解析 POM 文件(清理 .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
我需要先构建超级pom:
cd modules/
mvn clean install
只有这样它才能编译:
[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
如果没有这个两步编译,您将如何构建项目以使其正常工作?
[编辑]:正如 cmets 中所讨论的,将 Super POM 的 relativePath 添加到模块 POM 将使代码使用一个命令行编译。
但是,如果我只想将 lib1 分发给一些开发人员,即使我的超级 POM 位于 Maven 存储库中,如果没有整个项目结构,lib1 也无法编译。这使得项目的模块化程度降低。
【问题讨论】:
-
Lib1 和 2 必须在您的 parent-pom 中定义为模块?!还是有理由不这样做? Maven 不会在 reactor-build 中包含传递依赖。
-
这个想法是用一个命令行编译整个项目。这就是我将 lib1 和 lib2 添加到根聚合器的原因。在这个 POM 中直接添加最终模块(例如
modules/lib1/moduleA1 )不会改变行为并且 Maven 也无法构建。 -
您的问题不是关于 reactor build ,而是关于您的 parent-pom。 IMO 您必须编辑所有父 pom 定义以添加
元素。 See Example 2 here. -
添加 relativePath 确实有效。但是,当您添加新模块/子模块并且您的结构变得更加复杂时,我发现它很不方便。
-
没错,但 Eclipse 和 IntelliJ 都有很好的工具来解决这种情况。你必须添加一个 Maven Module