如何关闭maven项目的传递依赖?
How to turn off transitive dependencies for maven projects?
我遇到了JIRA post,它提供了一个解决方案,在 POM 的每个依赖项标签中包含排除标签。
但是我有很多项目,每个项目都有大量的依赖标签。在每个依赖项标签中包含此 <exclusion>
是不可行的。
问题:有没有办法在maven中全局关闭传递依赖的导入?
在 Maven 中,您不能以单一方式关闭所有已声明依赖项的传递依赖项,如 official documentation
所述
Why exclusions are made on a per-dependency basis, rather than at the POM level
This is mainly done to be sure the dependency graph is predictable, and to keep inheritance effects from excluding a dependency that should not be excluded. If you get to the method of last resort and have to put in an exclusion, you should be absolutely certain which of your dependencies is bringing in that unwanted transitive dependency.
确实,自 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 默认情况下都会应用此版本和此排除项。
这个解决方案的主要优点是你集中了这个 mechanism/management 这样至少你不必触及每个 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 更新:最后我们决定不这样做,而是通过使用依赖树命令为每个项目生成新 added/removed 依赖项的报告并广播它来解决原始问题。
即使我不确定您为什么需要这样的机制,而且我不建议这样做,但只排除您实际上不想要的传递依赖项,而依赖于它们的依赖项可以通过某种方式 运行 没有他们。
最后一点非常重要,您的依赖项可能需要传递依赖项才能正常工作。
所以尽管上面所有这些你都可以,但有一个来自 Apache Maven 的插件叫做 Apache Maven Enforcer Plugin,它的内置规则之一是 Ban Transitive Dependencies
我遇到了JIRA post,它提供了一个解决方案,在 POM 的每个依赖项标签中包含排除标签。
但是我有很多项目,每个项目都有大量的依赖标签。在每个依赖项标签中包含此 <exclusion>
是不可行的。
问题:有没有办法在maven中全局关闭传递依赖的导入?
在 Maven 中,您不能以单一方式关闭所有已声明依赖项的传递依赖项,如 official documentation
所述Why exclusions are made on a per-dependency basis, rather than at the POM level
This is mainly done to be sure the dependency graph is predictable, and to keep inheritance effects from excluding a dependency that should not be excluded. If you get to the method of last resort and have to put in an exclusion, you should be absolutely certain which of your dependencies is bringing in that unwanted transitive dependency.
确实,自 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 默认情况下都会应用此版本和此排除项。
这个解决方案的主要优点是你集中了这个 mechanism/management 这样至少你不必触及每个 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 更新:最后我们决定不这样做,而是通过使用依赖树命令为每个项目生成新 added/removed 依赖项的报告并广播它来解决原始问题。
即使我不确定您为什么需要这样的机制,而且我不建议这样做,但只排除您实际上不想要的传递依赖项,而依赖于它们的依赖项可以通过某种方式 运行 没有他们。
最后一点非常重要,您的依赖项可能需要传递依赖项才能正常工作。
所以尽管上面所有这些你都可以,但有一个来自 Apache Maven 的插件叫做 Apache Maven Enforcer Plugin,它的内置规则之一是 Ban Transitive Dependencies