java 不同范围的依赖内的Maven依赖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1396901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maven dependency within dependency with different scope
提问by tim_wonil
Say I have two Maven dependencies defined in a project like below.
假设我在如下项目中定义了两个 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>
Then, within mylibrary, I also have a dependency defined as below.
然后,在 mylibrary 中,我还有一个如下定义的依赖项。
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
<scope>compile</scope>
</dependency>
When I package my project, I don't see xstream packaged within it. I think the project's xstream dependency scope, 'test' is overriding the mylibrary's xstream dependency scope, 'compile'.
当我打包我的项目时,我没有看到 xstream 打包在其中。我认为项目的 xstream 依赖范围“test”覆盖了 mylibrary 的 xstream 依赖范围“compile”。
In this kind of situation, what's the best way to include the xstream for the whole project so the submodule can have access to it when packaged within the project?
在这种情况下,为整个项目包含 xstream 以便子模块在项目中打包时可以访问它的最佳方法是什么?
I've read Apache Maven website's explanation on Transitive dependencies, but I'm struggling to understand what it means, and also to find out the best practice in this situation.
我已经阅读了 Apache Maven 网站对传递依赖项的解释,但我正在努力理解它的含义,并在这种情况下找出最佳实践。
采纳答案by Buhb
This feels really odd to me, and if it's "feature", I think it is a really dangerous one. Anyway, it's not a Maven bug and it's in the maven documentation here.
这对我来说真的很奇怪,如果是“功能”,我认为这是一个非常危险的功能。无论如何,这不是 Maven 错误,它位于此处的 Maven 文档中。
Regarding best practices on this issue, I haven't heard of any, but the safest way to proceed ought to be to entirely remove xstream from your pom, relying on the transitive dependency. Doing this will result in a build failure if the dependency to mylibrary is removed. This will act as a notification to you that you need to fix something. You won't silently loose required dependencies, and you won't silently have dependencies you no longer need.
关于这个问题的最佳实践,我还没有听说过,但最安全的方法应该是从你的 pom 中完全删除 xstream,依赖于传递依赖。如果删除了对 mylibrary 的依赖,这样做将导致构建失败。这将作为您需要修复某些内容的通知。您不会默默地丢失所需的依赖项,也不会默默地拥有不再需要的依赖项。
On a side note, mvn dependency:analyze can be used to check for dependencies that are included but not used.
附带说明一下, mvn dependency:analyze 可用于检查包含但未使用的依赖项。
回答by Rich Seller
As mattb's answer says, declaring the dependency as testscope overrides the transitive compile-scoped dependency declaration, and as a result the dependency is not included in your packaged war.
正如 mattb 的回答所说,将依赖声明为test范围会覆盖传递性编译范围的依赖声明,因此该依赖不包含在打包的War中。
If you only need the dependency in your tests because 'mylibrary' needs it to execute, you shouldn't declare the dependency at allin your project's pom. Let the transitive dependency resolution process handle it.
如果您只需要在测试中的依赖,因为“在MyLibrary”需要它来执行,你不应该声明依赖于所有在你项目的POM。让传递依赖解析过程处理它。
If your project does use the xstream jar directly, you can still rely on the transitive dependency, as you will need a compatible version for your project and 'mylibrary' to both run against the xstream jar. You should have unit tests that exercise the functionality, and if mylibrary changes version of xstream to an incompatible version, your builds should fail, and you can address the issue at that point.
如果您的项目确实直接使用 xstream jar,您仍然可以依赖传递依赖项,因为您的项目和“mylibrary”需要一个兼容版本才能针对 xstream jar 运行。您应该进行单元测试来执行该功能,如果 mylibrary 将 xstream 的版本更改为不兼容的版本,您的构建应该会失败,此时您可以解决问题。
In general I'd say you should try to avoid declaring dependency versions directly in multi-module projects. I declare the versions in a dependencyManagementsection of a parent POM so that the child need only declare the groupId/artifactId. Alternatively, from Maven 2.0.9 onwards there is an additional dependency scope of import:
一般来说,我会说你应该尽量避免直接在多模块项目中声明依赖版本。我在父 POM的dependencyManagement部分中声明了版本,这样子POM 只需要声明groupId/artifactId。或者,从 Maven 2.0.9 开始,还有一个额外的依赖范围import:
This scope is only used on a dependency of type pom in the section. It indicates that the specified POM should be replaced with the dependencies in that POM's section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.
此范围仅用于该部分中 pom 类型的依赖项。它表示指定的 POM 应该替换为该 POM 部分中的依赖项。由于它们被替换,具有导入范围的依赖项实际上并不参与限制依赖项的传递性。
So using import scope you can define your common dependency versions in a single POM, import the dependencies of that POM into your dependencyManagement section, and just declare the groupId/artifactId of the dependency in your other POMs.
因此,使用导入范围,您可以在单个 POM 中定义公共依赖项版本,将该 POM 的依赖项导入您的 dependencyManagement 部分,然后只需在其他 POM 中声明依赖项的 groupId/artifactId。
回答by matt b
By declaring your own dependency on xstream, and setting the scope to test, you are overriding the dependencies declared by mylibrary.
通过声明您自己对 xstream 的依赖,并将范围设置为 test,您将覆盖由mylibrary.
This is actually a Maven feature - it allows you to do things such as depend on a later version of a transitive dependency within your own project, and not end up packaging two different versions of the same artifact. For example, you might depend on version 1.2.15of log4j, but because you also use libraryXwhich depends on log4j-1.2.14- you wouldn't want both log4j-1.2.15and log4j-1.2.14to be packaged with your project.
这实际上是一个 Maven 特性——它允许你做一些事情,比如依赖你自己项目中传递依赖的更新版本,而不是最终打包同一工件的两个不同版本。例如,你可能依赖于版本1.2.15的log4j的,而是因为你也可以使用libraryX它取决于log4j-1.2.14-你不希望既log4j-1.2.15和log4j-1.2.14与你的项目进行包装。
If you actually want xstream to be packaged within your project, you should not be declaring the scope as test. In fact if you remove your listed dependency on xstream, things will work out as you like, since mylibraryhas a compile dependency on it..
如果您确实希望将 xstream 打包到您的项目中,则不应将范围声明为test. 事实上,如果你删除你列出的对 xstream 的依赖,事情就会如你所愿,因为mylibrary对它有编译依赖。
回答by aperkins
If you want it packaged, why are you declaring scope? If it is required at compile and execution time, shouldn't you leave the scope blank? If you did that, then you would only need
如果要打包,为什么要声明范围?如果在编译和执行时需要它,您不应该将范围留空吗?如果你这样做了,那么你只需要
<dependency>
<groupId>mycompany.modules</groupId>
<artifactId>submodule</artifactId>
<version>1.0.1</version>
</dependency>
in your pom. Unless there is a reason to descope it during compile but not during packaging?
在你的 pom. 除非有理由在编译期间而不是在打包期间取消它的范围?

