10

I have come across the JIRA post that gives a solution as including exclusion tag in each dependency tag of POM.

But I have large number of projects and each project has huge number of dependency tags. It's not feasible to include this <exclusion> in each of the dependency tags.

Question: Is there a way to globally switch off the importing of transitive dependencies in maven?

4

2 回答 2

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>

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

<parent>
    <groupId>com.sample</groupId>
    <artifactId>projects-governance</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

然后,在相关的父 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>

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

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

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


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

mvn dependency:list -DexcludeTransitive=true -DoutputFile=dependencies.txt -DappendOutput=true

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


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

    </version>
</dependency>

通过以下的:

    </version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

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

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

于 2016-03-11T10:36:43.697 回答
0

即使我不确定你为什么想要这样的机制,我也不建议这样做,只排除你实际上不想要的传递依赖项,其中依赖于它们的依赖项可以在没有它们的情况下运行。

最后一点非常重要,您的依赖项需要传递依赖项才能正常工作。

因此,尽管有上述所有内容,但 Apache Maven 有一个名为 Apache Maven Enforcer Plugin 的插件,它的内置规则之一是Ban Transitive Dependencies

于 2019-09-17T08:38:10.110 回答