正如您所发现的,版本范围是邪恶的。
真正的问题是版本范围是一个警笛,诱使人们认为他们是一个好主意。
版本范围确实应该被视为对开发人员的提示,以允许开发人员从一组版本中选择他们想要的版本。
Maven 中的错误在于首先允许在其中定义版本范围,pom.xml
因为这允许人们发布他们的工件,其中包含版本范围。
一旦您依赖于具有使用版本范围的传递依赖项的工件,实际上只有两种方法可以解决您的构建问题(一种只是第二种的更花哨的版本)
在传递依赖项上添加您自己的依赖项,但使用固定版本代替范围......例如
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
您不需要列出依赖项,因为它们不具有传递性,同样出于同样的原因,<optional>true</optional>
您也不需要列出依赖项。<scope>provided</scope>
至于上述,但首先通过向依赖项添加排除项来更安全,例如
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.1.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
在这两者中,我更喜欢后者,因为它至少给人们一个暗示,为什么要明确提到这些依赖关系。
所以回到你原来的问题,关键是当你在你的pom.xml
.
如果spring-data-jpa:1.1.1.RELEASE
有一个具有不同坐标的完全不同的传递依赖树,那么当您编辑pom.xml
以更新版本时,您还应该修复传递。
据我所知,目前没有任何强制执行规则来支持验证您的要求。
我建议编写一个执行者规则,我称之为:ensureTransitiveVersionRangesArePinned
该规则应执行以下操作:
- 扫描项目依赖列表
- 计算每个项目依赖提供的传递依赖
- 如果这些传递依赖项中的任何一个是版本范围,那么
- 验证该
exclusion
传递依赖是否存在
- 验证传递依赖项的固定版本是否作为直接项目依赖项(如果没有固定版本,则可能不会失败,因为您可能正在添加位于不同 GAV 的等效工件,或者您可能不需要依赖项)...在任何情况下,如果没有重新添加依赖项,单元测试很可能应该通过触发 CNFE 来捕获它,因此这个检查可能不是严格要求的,但它可能应该打印一个警告。
我不记得是否有工具可以检查它们<exclusions>
是否实际上排除了任何传递依赖项,因此您可能需要对此进行调查。