如何关闭maven项目的传递依赖?

A.R*_*K.S 7 maven-3 maven transitive-dependency

我遇到了JIRA帖子,它提供了一个解决方案,在POM的每个依赖项标签中都包含了排除标记.

但是我有大量的项目,每个项目都有大量的依赖标记.<exclusion>在每个依赖标记中包含它是不可行的.

问题:有没有办法全局关闭maven中传递依赖项的导入?

A_D*_*teo 7

在 Maven 中,您不能以一种方式关闭所有声明依赖项的传递依赖项,如官方文档所述

为什么在每个依赖项的基础上进行排除,而不是在 POM 级别进行

这样做主要是为了确保依赖图是可预测的,并防止继承效应排除不应该排除的依赖。如果您采用最后的方法并且必须排除,您应该绝对确定您的哪个依赖项引入了不需要的传递依赖项。


实际上,从 Maven 3.2.1 开始,您可以指定通配符来排除特定依赖项的所有传递依赖项,但这仍然是每个依赖项而不是全局依赖项。

您实际上希望每个 pom 中的每个依赖项都具有以下内容(!!):

<dependency>
    <groupId>groupId</groupId>
    <artifactId>artifactId</artifactId>
    <version>version</version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Run Code Online (Sandbox Code Playgroud)

虽然这不是可取的,因为它可能很容易(和负面)影响相关项目的可维护性,一个可能的解决方案是为所有相关项目拥有一个共同的父 POM,这样每个 pom 都会声明:

<parent>
    <groupId>com.sample</groupId>
    <artifactId>projects-governance</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>
Run Code Online (Sandbox Code Playgroud)

然后,在相关的父 POM 中,您将拥有:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample</groupId>
    <artifactId>modules</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
            <!-- for each and every foreseen dependency of children poms -->
            <dependency>
                <groupId>groupId</groupId>
                <artifactId>artifactId</artifactId>
                <version>version</version>
                <exclusions>
                    <exclusion>
                        <groupId>*</groupId>
                        <artifactId>*</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
Run Code Online (Sandbox Code Playgroud)

请注意该dependencyManagement部分,这里我们说的是:对于所有子 POM,每当您使用我声明的相关依赖项时,对于此 groupId 和此 artifacId,默认情况下将应用此版本和此排除项。

这个解决方案的主要优点是你集中了这个机制/管理,这样至少你不必接触每个 POM(除了关于新父级的更改)。

但是,您仍然需要在父 POM 中列出所有项目使用的所有依赖项,并为所有项目应用通配符排除项。


要获取每个项目的所有依赖项的列表,您可以采用手动方法(打开每个 POM!)或在每个项目上运行以下命令:

mvn dependency:list -DexcludeTransitive=true -DoutputFile=dependencies.txt -DappendOutput=true
Run Code Online (Sandbox Code Playgroud)

Maven的依赖插件,然后将指定在写dependencies.txt文件中声明的依赖性(格式为groupId:artifactId:packaging:version:scope有关项目)。请注意,最后一个参数 ,appendOutput可能有助于在同一文件的末尾写入,以使它们集中以进行进一步处理(删除重复项,将它们移动到新的父 pom)。


要将通配符应用于所有声明的依赖项,快速提示是简单地替换(使用任何文本编辑器或通过 shell 脚本)以下标记:

    </version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

通过以下几个:

    </version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Run Code Online (Sandbox Code Playgroud)

然后保存文件。并且您会自动以一种非常安全的方式将通配符排除应用于所有依赖项。

OP更新:最后我们决定不这样做,而是通过使用依赖树命令为每个项目生成新添加/删除的依赖项的报告并广播它来解决原始问题。