排除单个依赖项的所有传递依赖项

在Maven2中,为了排除单个传递依赖,我必须这样做:

<dependency>
<groupId>sample.group</groupId>
<artifactId>sample-artifactB</artifactId>
<version>1</version>
<exclusions>
<exclusion>
<groupId>sample.group</groupId>
<artifactId>sample-artifactAB</artifactId>
</exclusion>
</exclusions>
</dependency>

这种方法的问题是,我必须对sample-artifactB贡献的每个传递依赖项都这样做。

是否有一种方法可以使用某种通配符一次性排除所有传递依赖项,而不是逐个排除?

269336 次浏览

你排除所有传递依赖的原因是什么?

如果有一个特定的工件(如common -logging)需要从每个依赖项中排除,版本99不存在方法可能会有所帮助。


不要使用这种方法。使用maven-执法者-插件和排除。版本99产生虚假的依赖,版本99存储库离线(有类似的镜子,但你也不能依赖它们永远在线;最好只使用Maven Central)。

对于maven2,没有办法做到您所描述的。对于maven 3,有。如果你正在使用maven 3,请参阅这个问题的另一个答案

对于maven 2,我建议为包含<exclusions>的依赖项创建自己的自定义pom。对于需要使用该依赖项的项目,将依赖项设置为自定义pom,而不是典型的工件。虽然这并不一定允许你用一个简单的排除程序排除所有的可传递依赖项,但它允许你只需要编写一次依赖项,并且你的所有项目都不需要维护不必要的长排除列表。

目前,没有办法一次排除一个以上的可传递依赖,但在Maven JIRA站点上有一个特性请求:

https://issues.apache.org/jira/browse/MNG-2315

有一个变通方法,如果你将依赖项的作用域设置为运行时,可传递依赖项将被排除。但是要注意,这意味着如果您想打包运行时依赖项,就需要添加额外的处理。

要在任何打包中包含运行时依赖项,可以使用maven-dependency-plugin的为特定工件复制目标

我发现有一件事很有用:

如果您将带有排除项的依赖项放在项目的父POM的dependencyManagement部分中,或者放在可导入的依赖项管理POM中,那么您就不需要重复排除项(或版本)。

例如,如果你的父POM有:

<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
....
</dependencies>
</dependencyManagement>

然后,项目中的模块可以简单地将依赖声明为:

        <dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>

父POM中的将指定版本和排除项。我几乎在我们所有的项目中都使用了这个技巧,它消除了很多重复。

对我有用的(可能是Maven的一个新特性)只是在排除元素中使用通配符。

我有一个多模块项目,其中包含一个在两个war打包模块中引用的“app”模块。其中一个war打包的模块实际上只需要域类(我还没有将它们从app模块中分离出来)。我发现这个方法很有效:

<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>app</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

groupId和artifactId上的通配符排除了通常会通过使用该依赖项传播到模块的所有依赖项。

如果你在Eclipse下开发,你可以在POM编辑器(启用高级选项卡)依赖关系图中寻找你想要排除的项目依赖关系,然后:

右键单击它->“Exclude Maven Artifact…”Eclipse将为您排除,而不需要查找库链接到哪个依赖项。

在一个类似的问题中,我声明了所需的依赖关系,并提供了作用域。 使用这种方法,可传递依赖项会被获取,但不会包含在包阶段,这正是您想要的。 我也喜欢这个解决方案在维护方面,因为没有pom,或自定义pom在whaley的解决方案,需要维护;您只需要在容器中提供特定的依赖项并完成

如果你需要排除你要包含在程序集中的依赖工件中的所有传递依赖项,你可以在程序集插件的描述符中指定:

<assembly>
<id>myApp</id>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<useTransitiveDependencies>false</useTransitiveDependencies>
<includes><include>*:struts2-spring-plugin:jar:2.1.6</include></includes>
</dependencySet>
</dependencySets>
</assembly>

三年前我建议使用版本99不存在,但现在我想出了一个更好的方法,特别是因为版本99离线:

在项目的父POM中,如果不需要的依赖项悄悄进入构建,则使用maven-enforcer-plugin使构建失败。这可以使用插件的禁止依赖性规则来完成:

<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>only-junit-dep-is-used</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>junit:junit</exclude>
</excludes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>

然后,当它提醒你一个不需要的依赖项时,将它排除在父POM的<dependencyManagement>部分:

<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<version>2.1.8.RELEASE</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>

这样,不需要的依赖项就不会意外出现(不像<exclusion>那样容易忘记),它甚至在编译时也不可用(不像provided作用域),没有虚假的依赖项(不像版本99),并且它可以在没有自定义存储库的情况下工作(不像版本99)。这种方法甚至可以基于工件的版本、分类器、范围或整个groupId - 参见文档来详细说明。

我使用以下的解决方法:而不是试图在所有适当的依赖项中排除工件,我在顶层将依赖项绘制为“提供”。 例如,为了避免发布xml-api的“任何版本”:

    <dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>[1.0,]</version>
<scope>provided</scope>
</dependency>

在类路径中使用最新的maven ..它将删除重复的工件并保留最新的maven工件。