如何构建一个多模块Maven项目来立即编译它?

时间:2016-01-27 10:18:09

标签: maven maven-3

我有一个包含多个模块和子模块的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&#39 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类似。

当在项目的根目录时,运行&#34; mvn clean install&#34;命令给出(清理.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

如果没有这两步编译,你将如何构建项目以使其工作?

[编辑]:正如评论中所讨论的,将Super POM的relativePath添加到模块POM将使代码使用一个命令行进行编译。

但是,如果我只想将lib1分发给某些开发人员,即使我的超级POM位于Maven存储库中,如果没有整个项目结构,lib1也无法编译。这使得项目不那么模块化。

1 个答案:

答案 0 :(得分:23)

让我像你一样开始,但我对事情的命名有点不同:

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

让我们从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>

    <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>

module parent将如下所示。我将强调这仅包含对moduleAmoduleB的引用,并且继承}中的

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(父级)继承,这正是上面的一级......

module-parent

如果您使用这种结构,只需转到<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> 级别并执行:

project-root

此后你可以使用这样的东西:

mvn clean install

...仅构建moduleA(但保持在mvn -pl moduleA ... 级别......)。

在此示例中,

project-root可能看起来像浪费或多余,但如果您获得更多模块,则可以通过module-parent定义补充依赖项,或者可以通过dependencyManagement更改插件配置用于此子区域(moduleA,moduleB,...)。如果您的项目变得更大,您将获得更多并行的模块父项...其中包含您的应用程序的不同部分......以及使用此结构可以实现的不同意图。

还有一件事要提。我已在模块父级中将pluginManagementgroupId更改为org.test。如果您有大量模块,这有时很有用,因为org.test.module代表了存储库中的文件夹结构(就像Java程序包在Java项目中那样)......这样可以更好地概述......

groupId是通过project-root等定义整体可用依赖项的位置....以及应该通过dependencyManagement定义的已使用的插件...或者可能正在使用maven-enforcer-plugin定义整体项目规则......

这种结构的典型场景是Java EE项目或其他大型项目(可能存在300 ...或1000模块,是的)...

如果您获得更多模块,您可以使用maven的多线程功能并使用以下内容构建项目:

pluginManagement
来自mvn -T 4 clean install

可显着缩短构建时间。