Maven和依赖模块

时间:2009-04-30 18:57:05

标签: java maven-2 build-process

同事一直在兜售maven及其魔法依赖的奇迹,但我发现它在我认为显而易见的用途上失败了。

假设我有一个带有主POM的根文件夹。

然后我有一些项目,称他们为A和B

B需要A,因此B文件夹中的POM中包含相应的依赖项

现在,回到根文件夹中,在配置文件中,我指定我要构建B。

当我执行通常的mvn clean安装时,我收到了失败,因为A没有构建。

我的朋友告诉我,我必须在根目录中的主要配置文件中指定A和B.

但是不是maven看到B的依赖管理的全部要点,转到B POM文件,它看到了对A的依赖,所以它应该自动构建A.

6 个答案:

答案 0 :(得分:40)

使用主POM:

~/scratch/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>scratch</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>nipple</module>
        <module>cabbage</module>
    </modules>
</project>

模块POM:

~/scratch/nipple/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>scratch</artifactId>
        <groupId>scratch</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>nipple</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

~/scratch/cabbage/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>scratch</artifactId>
        <groupId>scratch</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>cabbage</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>scratch</groupId>
            <artifactId>nipple</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

清理完本地存储库后,我可以在根目录中发出mvn package,最后建立所有模块。 (进入空洞的JAR,但已建成。)

Maven似乎在存储库或正在进行的构建中查找依赖项。当您只构建单个模块时,它不会自动遍历您的项目结构,因为您不需要在计算机上拥有父项目,更不用说当前模块上方的一个目录。 (亲子关系甚至不是双射的。)

之所以如此,可能是因为模块位置可预测的目录布局绝不是强制性的。上面例子的布局是这样的,这甚至有点普遍和可以接受:

projects
|
+--scratch
|  |
|  +--scratch-parent
|  |  |
|  |  +--pom.xml [The POM of scratch:scratch:1.0-SNAPSHOT]
|  |
|  +--nipple
|  |  |
|  |  +--pom.xml [The POM of scratch:mod1:1.0-SNAPSHOT]
|  |
|  +--cabbage
|  |  |
|  |  +--pom.xml [The POM of scratch:mod2:1.0-SNAPSHOT]

在这种情况下,父POM的<modules>部分将是:

<modules>
    <module>../nipple</module>
    <module>../cabbage</module>
</modules>

请注意,哪个工件ID在哪个模块中没有任何说法。它只是告诉Maven这些是文件系统位置,在那里搜索与此构建相关的其他工件。

答案 1 :(得分:24)

我能想到你所期望的行为尚未实现的原因如下:

假设我正在研究A和B项目。目前A已经破解。如果依赖解析按照您的意愿发生,我将永远无法在A被修复之前构建B.所以我要么必须将我的更改回滚到A,要么首先关注修复A.无论哪种方式都可能不是我现在想要关注的。

一般来说B想要使用A的“最后好”版本,而不是最新版本。使用存储库中的依赖项意味着它们至少编译好了(希望单元测试也运行)。

答案 2 :(得分:14)

看看Maven reactor plugin,特别是reactor:make,它构建了一个模块以及它所依赖的所有模块。

答案 3 :(得分:5)

Rich是完全正确的。您所描述的通常不是预期的行为。 虽然如Deterb所述,如果父POM 知道模块,Maven反应器支持部分构建

使用mvn install -pl B -am构建还应-am)B的依赖关系(即A)。

无论如何,模块A 必须是父POM的模块。

(见Maven Modules + Building a Single Specific Module

答案 4 :(得分:4)

如果你正在使用IntelliJ,他们在Maven运行配置中有一个神奇的复选框:“解析工作空间工件”。所以不需要从父级安装或构建。

答案 5 :(得分:3)

答案只是它不是Maven的工作方式。 Maven背后的想法是为开发人员提供一个逻辑简单的系统来控制依赖关系。从存储库获取依赖关系是关键。每个例外都会削弱这种控制和简单性。在父POM中添加A作为依赖项可完全满足您的方案,而无需添加其他异常。使用批处理文件或ant脚本是解决方案的另一种方法。