有很多时候你需要排除一个传递性依赖,比如当你依赖于一个项目,后者又继而依赖于另外一个项目,但你的希望是,要么整个的排除这个传递性依赖,要么用另外一个提供同样功能的依赖来替代这个传递性依赖。Example 9.7, “排除一个传递性依赖”展示的例子中添加了一个对于project-a
的依赖,但排除了传递性依赖project-b
。
Example 9.7. 排除一个传递性依赖
<dependency> <groupId>org.sonatype.mavenbook</groupId> <artifactId>project-a</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>org.sonatype.mavenbook</groupId> <artifactId>project-b</artifactId> </exclusion> </exclusions> </dependency>
通常,你会想要使用另外一个实现来替代一个传递性依赖。比如,如果你正依赖于一个类库,该类库又依赖于Sun JTA API,你会想要替换这个传递性依赖。Hibernate是一个例子。Hibernate依赖于Sun JTA API,而后者在中央Maven仓库中不可用,因为它是不能免费分发的。幸运的是,Apache Gernoimo项目创建了一些可以免费分发的独立实现类库。为了用另外的依赖来替换这个传递性依赖,你需要排除这个传递性以依赖,然后在你的项目中再声明一个依赖。Example 9.8, “排除并替换一个传递性依赖”展示了这样一个替换的样例。
Example 9.8. 排除并替换一个传递性依赖
<dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> <version>3.2.5.ga</version> <exclusions> <exclusion> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jta_1.1_spec</artifactId> <version>1.1</version> </dependency> </dependencies>
在Example 9.8, “排除并替换一个传递性依赖”中,没有什么标记说依赖geronimo-jta_1.1_spec
是一个替换,它只是正好提供了和原来的JTA依赖一样的API。以下列举了一些你可能想要排除或者替换传递性依赖的情况:
-
构建的
groupId
和artifactId
已经更改了,而当前的项目需要一个与传递性依赖不同名称的版本——结果是classpath中出现了同样项目的两份内容。一般来说Maven会捕捉到这种冲突并且使用该项目的一个单独的版本,但是当artifactId
和artifactId
不一样的时候,Maven就会认为它们是两种不同的类库。 -
某个构件没有在你的项目中被使用,而且该传递性依赖没有被标志为可选依赖。在这种情况下,你可能想要排除这种依赖,因为它不是你的系统需要的东西,你要尽量减少应用程序分发时的类库数目。
-
一个构件已经在运行时的容器中提供了,因此不应该被包含在你的构件中。该情况的一个例子是,如果一个依赖依赖于如Servlet API的东西,并且你又要确保这样的依赖没有包含在web应用的
WEB-INF/lib
目录中。 -
为了排除一个可能是多个实现的API的依赖。这种情况在Example 9.8, “排除并替换一个传递性依赖”中阐述;有一个Sun API,需要点击许可证,并且需要耗时的手工安装到自定义仓库,对于同样的API有可免费分发版本,在中央Maven仓库中可用(Geronimo's JTA 实现)。