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

Ben*_*Ben 22 maven-3 maven

我有一个包含多个模块和子模块的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
Run Code Online (Sandbox Code Playgroud)

聚合器是:

<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>
Run Code Online (Sandbox Code Playgroud)

超级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>
Run Code Online (Sandbox Code Playgroud)

模块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>
Run Code Online (Sandbox Code Playgroud)

模块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
Run Code Online (Sandbox Code Playgroud)

现在,如果我想要更复杂的东西(但仍然使用一个超级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
Run Code Online (Sandbox Code Playgroud)

根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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

并且,例如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>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我需要先建立超级pom:

cd modules/
mvn clean install
Run Code Online (Sandbox Code Playgroud)

只有这样才会编译:

[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
Run Code Online (Sandbox Code Playgroud)

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

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

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

khm*_*ise 24

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

.
??? modules-root
?   ??? moduleA
?   ?   ??? pom.xml <--- Module A POM
?   ??? moduleB
?   ?   ??? pom.xml <--- Module B POM
?   ??? pom.xml     <--- modules root
??? pom.xml         <--- project-root
Run Code Online (Sandbox Code Playgroud)

让我们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>
Run Code Online (Sandbox Code Playgroud)

module parent会是这样的.我将强调这只包含对moduleAand 的引用moduleB,并将继承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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

如果您使用这种结构,您可以直接进入project-root关卡并执行:

mvn clean install
Run Code Online (Sandbox Code Playgroud)

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

mvn -pl moduleA ...
Run Code Online (Sandbox Code Playgroud)

...仅构建moduleA(但保持在project-root关卡......).

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

还有一件事要提.我已经改变了groupId,从org.testorg.test.module在模块父.如果您有大量模块导致groupId表示存储库中的文件夹结构(如Java项目中的Java包那样),这有时很有用......这样可以更好地概述...

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

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

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

mvn -T 4 clean install 
Run Code Online (Sandbox Code Playgroud)

从中project-root大大减少了构建时间.