具有不同范围的依赖内的Maven依赖

假设我在如下项目中定义了两个Maven依赖项。

 com.thoughtworks.xstream xstream 1.3.1 test   mycompany.library mylibrary 1.0.1 compile  

然后,在mylibrary中,我也有一个依赖定义如下。

   com.thoughtworks.xstream xstream 1.3.1 compile  

当我打包我的项目时,我没有看到xstream打包在其中。 我认为项目的xstream依赖范围’test’正在覆盖mylibrary的xstream依赖范围’compile’。

在这种情况下,为整个项目包含xstream的最佳方法是什么,以便子模块在项目中打包时可以访问它?

我已经阅读了Apache Maven网站关于Transitive依赖关系的解释,但我很难理解它的含义,并且在这种情况下找出最佳实践。

这对我来说真的很奇怪,如果它是“特色”,我认为这是一个非常危险的。 无论如何,它不是Maven错误,而是在maven文档中。

关于这个问题的最佳实践,我没有听说过,但最安全的方法是依靠传递依赖来完全从你的pom中删除xstream。 如果删除了对mylibrary的依赖,则执行此操作将导致构建失败。 这将作为通知您需要修复的东西。 您不会以静默方式释放所需的依赖项,并且您不会默默地拥有不再需要的依赖项。

另外,mvn dependency:analyze可用于检查包含但未使用的依赖项。

正如mattb的回答所说,将依赖关系声明为test范围会覆盖传递的编译范围的依赖关系声明,因此依赖关系不会包含在打包的war中。

如果您只需要测试中的依赖项,因为“mylibrary”需要执行它,那么您不应该在项目的pom中声明依赖项。 让传递依赖性解析过程处理它。

如果你的项目确实直接使用了xstream jar,你仍然可以依赖传递依赖,因为你需要一个兼容的项目版本和’mylibrary’来运行xstream jar。 您应该具有执行function的unit testing,如果mylibrary将xstream的版本更改为不兼容的版本,则您的构建应该失败,并且您可以在此时解决该问题。

一般来说,我会说你应该尽量避免在多模块项目中直接声明依赖版本。 我在父POM的dependencyManagement部分中声明了这些版本,以便子项只需要声明groupId / artifactId。 或者,从Maven 2.0.9起,还有一个额外的import依赖范围:

此范围仅用于节中pom类型的依赖项。 它表示应该用该POM部分中的依赖项替换指定的POM。 由于它们被替换,具有导入范围的依赖性实际上不参与限制依赖性的传递性。

因此,使用import scope可以在单个POM中定义公共依赖项版本,将该POM的依赖项导入dependencyManagement部分,并在其他POM中声明依赖项的groupId / artifactId。

通过声明自己对xstream的依赖,并将范围设置为test,您将覆盖mylibrary声明的依赖mylibrary

这实际上是一个Mavenfunction – 它允许您执行某些操作,例如依赖于您自己项目中的传递依赖项的更高版本,而不是最终打包同一工件的两个不同版本。 例如,您可能依赖于log4j的1.2.15版本,但是因为您还使用依赖于log4j-1.2.14 libraryX – 您不希望将log4j-1.2.15log4j-1.2.14打包为你的项目。

如果您确实希望将xstream打包到项目中,则不应将范围声明为test 。 事实上,如果你删除你在xstream上列出的依赖关系,事情会随你mylibrary那样,因为mylibrary有一个编译依赖。

如果你想要它打包,你为什么要声明范围? 如果在编译和执行时需要它,你不应该把范围留空吗? 如果你这样做,那么你只需要

  mycompany.modules submodule 1.0.1  

在你的pom。 除非有理由在编译期间而不是在包装期间对其进行去除?