【问题标题】:Maven: How do you deal with dependencies that are both direct and transitive?Maven:你如何处理直接和传递的依赖关系?
【发布时间】:2011-01-11 20:00:42
【问题描述】:

我正在尝试确定解决以下情况的方法:

有 3 个 Maven 工件:A、B 和 C。

B 依赖于 A。(即它使用了 A 的一些代码)

C 依赖于 A 和 B(即它使用 A 的一些代码和 B 的代码)。

假设我想为 B 和 C 使用相同版本的 A。

应该使用什么方法?

1) 在 C 的 pom.xml 中将 A 声明为依赖项。

Pro:开发人员很清楚 C 依赖于 A。 缺点:如果A的版本发生变化,需要多处更新。 (B和C)

2) 不要在 C 的 pom.xml 中将 A 声明为依赖项。

赞成/反对:与选项 1 相反。

【问题讨论】:

  • 错字:我猜你的意思是C depends on both A and B,当你说“C 取决于 A 和 C”时
  • 你是对的。我修正了错字。

标签: java maven-2


【解决方案1】:

我认为您应该在 pom.xml 中声明所有直接依赖项。传递依赖只是自动解决依赖关系的便利。

如果您更改直接依赖项的版本,传递依赖项可能会随之更改,从而可能破坏模块。模块应该构建为一个独立的单元,因此应该具有明确定义的依赖关系,不会因外部更改而中断。

我不同意这违反了 DRY 原则,因为 maven 在单个项目及其 pom 范围内定义事物。并且在这个范围内没有重复。

更新: 对现有传递依赖项的依赖使项目本身变得脆弱,并且还可能导致更复杂的问题,例如何时包含它。

例如,如果 C 对 A 有编译依赖,但对 B 有运行时依赖,那么您现在必须添加依赖(因为它不再在您的构建路径中)或将 B 声明为可编译,即使它不是。为了清楚起见,有很多话要说。明确定义您的依赖项是什么以及它们的范围是什么,并期望您的依赖项也这样做。在大多数情况下,您的依赖项是一个黑匣子,直到它引起问题并且您必须打开它。

【讨论】:

  • 在类路径中有两个版本的相同工件/jar 可能会造成混乱(Jar-hell)。您很可能希望在两个依赖项目(B 和 C)中都有一个版本。如果您想更新 A 的版本,则必须在两个 POM(重复)中更新相同的内容,否则可能存在版本问题。这就是我提到 DRY 的原因。
  • C 实际上依赖于 A,应该明确说明。传递依赖 C -> B -> A 是 B 的实现细节,可能会发生变化。你不应该知道或关心它。实际上,可能导致 Jar 版本地狱,但鉴于其在工具链中的位置,它应该成为 Maven 的一部分,以警告并帮助解决此类问题。
  • @Nishant - 我让 maven 处理解析罐子,它不会在类路径中放置两个,它决定放入哪个。正如我所说,项目是独立的,应该配置为这样的。对传递依赖的依赖只是混淆了你的依赖实际上是什么,这使得它们更难管理,而不是更容易,因为项目由于外部变化而变得更加脆弱。
  • 啊,好吧。我明白你在说什么。是的,您将拥有更高版本的工件,maven 会为您完成。
【解决方案2】:

1) 在 C 的 pom.xml 中将 A 声明为依赖项。

依赖是可读的

依赖是灵活的。如果要从 B 中删除 A 的依赖项,则无需考虑依赖于 B 的项目。

正如 other answer 中所建议的那样,在 pom 中写下直接依赖项是一个好习惯.xml 并让 maven 处理。

2) 不要在 C 的 pom.xml 中将 A 声明为依赖项。

大多数情况下,没有开发人员会看到 pom.xml。如果他们愿意,他们可以使用mvn dependency:tree 看到它,它会显示传递依赖。

发布新版本的 A 时会有单点更改。如果您在多个位置定义依赖关系,您可能会忘记更新所有位置。在这种情况下,Maven 会自动使用最新的。但是,它有时会刺痛。

有些人喜欢这个,因为大多数情况下,这种类型的依赖是常识(例如MyWebApp -> MyWebAppLib -> MySharedLibMyWebApp -> MySharedLib),他们希望避免在每个版本的多个位置添加更新版本的步骤。

我已经写下了优缺点,你应该自己评估最适合你的。


编辑#1: 啧啧!我已经更换了我的 cmets。
Edit#2:this answer 进行讨论后更新了答案。

【讨论】:

  • @Jin Kim 我误读了选项。所以,我的评论顺序错误。修好了。
  • 选项(A)是指选项(1)?
  • @Jin Kim 我已经更新了帖子以使其具有一定的意义,我之前把你的选项粘贴错了。
  • (-1) 罗宾的回答更好恕我直言
  • @Damien , @Jin Kim -- 在与@Robin 讨论后更新了我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 2021-02-15
  • 2017-09-20
相关资源
最近更新 更多