如何构造一个多模块的Maven项目以一次编译它? [英] How to structure a multi-modules Maven project to compile it at once?

查看:80
本文介绍了如何构造一个多模块的Maven项目以一次编译它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个模块和子模块的Maven项目,我想一次进行编译,即仅使用一次调用"mvn clean install".

I have a Maven project with multiple modules and sub-modules and i want to compile it at once, i.e. using only one call to "mvn clean install".

对于基本项目,以下结构将起作用:

For a basic project, the following structure would work:

.
├── 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文件夹后):

When at the root of the project, running "mvn clean install" command gives (after cleaning up the .m2/repository folder):

[...]
[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),例如:

Now if I want something that is more complex (but still using one super POM), such as:

.
├── 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>

并且,例如,模块A1 POM:

And, for instance 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文件夹之后):

Maven does not manage to resolve the POM files (after cleaning up the .m2/repository folder):

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

I need to first build the super pom:

cd modules/
mvn clean install

只有这样,它才能编译:

And only then will it compile:

[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

如果不进行两步编译,您将如何构造项目以使其正常工作?

How would you structure the project to make it work without this two-steps compilation?

:如注释中所述,将Super POM的relativePath添加到模块POM中会使代码使用一个命令行进行编译.

: as discussed in the comments, adding the relativePath of the Super POM to the modules POMs would make the code compile with one command line.

但是,即使我只将lib1分发给某些开发人员,即使我的超级POM在Maven存储库中,如果没有整个项目结构,lib1也不会编译.这使项目的模块化程度降低了.

However, if I want to distribute only lib1 to some developers, even though my super POM is on a Maven repository, lib1 would not compile without the whole project structure. This makes the project less modular.

推荐答案

让我像您一样开始,但是我对它们的命名有些不同:

Let me start like you did, but I name the things a little bit differently:

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

让我们从project-root开始,它看起来像这样:

Let's start with the project-root, which will look like this:

<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继承 :

The module-parent will look like this. I will emphasis that this contains only the reference to the moduleA and moduleB and will inherit from the 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>project-root</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>org.test.module</groupId>
    <artifactId>module-parent</artifactId>
    <packaging>pom</packaging>

    <modules>
        <module>moduleA</module>
        <module>moduleB</module>
    </modules>
</project>

moduleA将如下所示.请注意,这将从module-parent(父级)开始继承,该级别恰好高于...

moduleA will look like this. Pay attention that this will inherit from module-parent (parent) which is exactly one level above...

<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级别并执行:

If you use this kind of structure you can simply go to the project-root level and do:

mvn clean install

此外,您还可以使用以下内容:

Furthermore afterwards you can use things like this:

mvn -pl moduleA ...

...仅构建模块A(但保持在project-root级别...).

...to build only moduleA (but stay at the project-root level...).

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

module-parent might look like wasted or superfluous in this example, but if you get more modules you could define their supplemental dependencies via dependencyManagement or may changing plugin configurations via pluginManagement which will only be used in this sub area (moduleA, moduleB, ...). If your project becomes larger, you will get more module-parents in parallel..which contain different parts of your applications...and different intentions which can be achieved with this structure.

还有一件事要提;我已经将groupIdorg.test更改为module-parent中的org.test.module.如果您有大量模块,这有时很有用,因为groupId代表存储库中的文件夹结构(就像Java包在Java项目中一样)...这可以为您提供更好的概述...

One more thing is to mention; I have changed the groupId from org.test to org.test.module in the module-parent. This is sometimes useful if you have a large number of modules cause the groupId represents the folder structure in your repository (as java packages do in a Java project)... this give you an better overview...

project-root是用于通过dependencyManagement等定义整体可用依赖项的位置.使用过的插件应通过pluginManagement进行定义...或者可以使用

The project-root is the location to define the overall usable dependencies via dependencyManagement etc....and the used plugins which should be defined via pluginManagement... or may be using maven-enforcer-plugin to define overall project rules...

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

Typical scenarios for this kind of structure are Java EE projects or other large projects (may be with 300...or 1000 modules yes they exist)...

如果有更多模块,则可以使用maven的多线程功能并使用以下命令构建项目:

If you get more modules you can use the multi-thread capability of maven and build your project with:

mvn -T 4 clean install 

来自project-root,大大减少了构建时间.

from the project-root which reduces the build time dramatically.

这篇关于如何构造一个多模块的Maven项目以一次编译它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆