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

tim*_*nil 14 java maven-2

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

    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.3.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>mycompany.library</groupId>
        <artifactId>mylibrary</artifactId>
        <version>1.0.1</version>
        <scope>compile</scope>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

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

    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.3.1</version>
        <scope>compile</scope>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

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

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

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

Buh*_*uhb 12

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

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

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


Ric*_*ler 5

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

如果您只需要在测试中的依赖,因为"在MyLibrary"需要它来执行,你不应该声明依赖于所有在你项目的POM.让传递依赖解析过程处理它.

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

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

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

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