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

时间:2016-03-11 00:17:29

标签: maven maven-3 transitive-dependency

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

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

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

2 个答案:

答案 0 :(得分:4)

在Maven中,您无法以单一方式关闭所有声明的依赖项的传递依赖项,如official documentation所述

  

为什么要在每个依赖项基础上进行排除,而不是在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>

虽然这是不可取的,因为它可能很容易(并且消极地)影响相关项目的可维护性,但可能的解决方案是为所有相关项目建立一个共同的parent 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 Dependency Plugin将在指定的dependencies.txt文件中写入相关项目的声明的依赖项(格式为groupId:artifactId:packaging:version:scope)。请注意,最后一个参数appendOutput可能有助于在同一文件的末尾写入,以便将它们集中用于进一步处理(删除重复项,将它们移动到新的父pom)。

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

    </version>
</dependency>

通过以下方式:

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

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

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

答案 1 :(得分:0)

即使我不确定为什么要使用这种机制,我也不建议这样做,仅排除您实际上不希望传递依赖的依赖项,依赖它们的依赖项可以在没有它们的情况下如何运行

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

因此,尽管您已完成上述所有工作,但仍有来自Apache Maven的名为Apache Maven Enforcer插件的插件,它具有的内置规则之一是 Ban Transitive Dependencies