Maven 和依赖模块

2022-08-31 15:55:48

同事们一直在吹捧maven的奇迹及其神奇的依赖性的东西,但我发现它在我认为明显的用途上失败了。

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

然后下面我有一些项目,称它们为A和B。

B 需要 A,因此 B 文件夹中的 POM 具有适当的依赖项条目

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

当我执行通常的 mvn 干净安装时,我遇到了一个失败,因为 A 没有构建。

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

但是,maven看到B的依赖关系管理的全部意义不在于进入B POM文件,在那里它看到了对A的依赖关系,因此它应该自动构建A。


答案 1

使用主 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>

在清除本地存储库后,我可以在根目录中发出问题,并最终构建了所有模块。(进入空洞的JAR,但已建成。mvn package

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,这些是文件系统位置,用于搜索与此构建相关的其他工件。


答案 2

我能想到的一个原因,你想要的行为没有被实现,如下:

假设我正在同时处理项目A和B,目前A已经坏了。如果依赖关系解决方案按照您的意愿发生,在A修复之前,我永远无法构建B。因此,我要么必须将更改回滚到A,要么专注于首先修复A。无论哪种方式都可能不是我现在想要关注的。

通常,B 希望使用 A 的“最后一个好”版本,而不是最新的版本。使用存储库中的依赖项意味着它们至少编译良好(并且希望单元测试也运行)。


推荐