Maven 依赖解析和范围覆盖
免责声明
(我最初以非常详细的方式提出问题 在这里。我在这里摘录了它,因为 maven-users
邮件列表在这个问题上已经保持沉默。) (不仅仅是另一个新手问题)
参考
我的参考资料是 http://maven.apache.org/guides/introduction /introduction-to-dependency-mechanism.html#Dependency_Management;如果这已经过时或错误,请在本次讨论中告诉我。
问题
该文档中有一个部分以“第二个,非常重要......”开头。接下来,我将参考该部分的项目 A
和 B
,并从中摘录。
在该部分中,您将看到项目 A
有一个
部分,除其他外,该部分定义了一个工件 c
,因为具有范围 compile
:
<!-- In A's pom.xml; condensed for brevity -->
<dependencyManagement>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<version>1.0</version>
<scope>compile</scope> <!-- look: compile scope -->
</dependency>
</dependencyManagement>
然后您将看到项目 B
的 pom.xml
,它 (a) 继承自项目 A
(从而继承了它的dependencyManagement
部分)和 (b) 建立对工件 c
的依赖关系,而无需指定其版本
。您还会注意到,对工件 c
的依赖将 c
的范围覆盖为 runtime
,而不是 compile
:
<!-- In B's pom.xml, whose parent is A's pom.xml (above); condensed for brevity -->
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<scope>runtime</scope> <!-- look: runtime scope -->
</dependency>
</dependencies>
您将再次注意到,没有
元素,但有一个
元素。
我对此的解释是,归根结底,B
将取决于 中工件
范围,而不是c
的 1.0
版本运行时编译
范围。
这是正确的吗? 我的 maven-ear-plugin
错误基于以下事实:这是预期的行为。当 maven-ear-plugin
构建 .ear
文件时,不会发生这种情况。
接下来,如果这是正确的,我还希望如果工件 c
具有任何可传递的 runtime
依赖项,它们将在 B
的 中可用>runtime
类路径(由 http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope)。
这是正确的吗?
Disclaimer
(I originally asked the question in a very detailed manner over here. I've excerpted it here as the maven-users
mailing list has gone quiet on this question.) (not just another newbie question)
Reference
My reference material is
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management; please let me know in this discussion if this is outdated or wrong.
Question
There is a section in that document that begins with "A second, and very important...". In what follows I'll refer to that section's projects A
and B
, and will excerpt from them.
In that section, you will see that project A
has a <dependencyManagement>
section that--among other things--defines an artifact, c
, as having scope compile
:
<!-- In A's pom.xml; condensed for brevity -->
<dependencyManagement>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<version>1.0</version>
<scope>compile</scope> <!-- look: compile scope -->
</dependency>
</dependencyManagement>
Then you will see a pom.xml
for project B
that (a) inherits from project A
(thus inheriting its dependencyManagement
section) and (b) establishes a dependency on artifact c
, without having to specify its version
. You will also notice that the dependency on artifact c
overrides the scope of c
to be runtime
, not compile
:
<!-- In B's pom.xml, whose parent is A's pom.xml (above); condensed for brevity -->
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<scope>runtime</scope> <!-- look: runtime scope -->
</dependency>
</dependencies>
Again, you'll note that there is no <version>
element, but there is a <scope>runtime</scope>
element.
My interpretation of this is that when all is said and done, B
will depend on version 1.0
of artifact c
in runtime
scope, not compile
scope.
Is that correct? My maven-ear-plugin
bug rests on the fact that this is the expected behavior. It is not what happens when the maven-ear-plugin
builds an .ear
file.
Next, if that's correct, I would also expect that if artifact c
had any transitive runtime
dependencies they would be available in B
's runtime
classpath (as defined by the somewhat baffling table in http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope).
Is that correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 bug 中发布的示例项目上运行
mvn dependency:tree
上面指定的link,mear-143-middle
中mear-143-leaf
的依赖scope
,其中依赖是明确的定义确实是runtime
,覆盖父 pommear-143
的dependencyManagement
部分中定义的test
范围。在
mear-143-ear
中,mear-143-leaf
被传递包含在内。这里,mear-143
的dependencyManagement
中定义的test
范围优先于继承的runtime
范围。我想这与您上面提到的部分的第二个要点中指定的内容一致。在此引用并以粗体和斜体突出显示相关部分:
Running
mvn dependency:tree
on the sample project posted in the bug link specified above,The dependency
scope
ofmear-143-leaf
inmear-143-middle
, where the dependency is explicitly defined is indeedruntime
, overriding thetest
scope defined in thedependencyManagement
section of parent pom,mear-143
.In
mear-143-ear
,mear-143-leaf
gets included transitively. Here thetest
scope defined independencyManagement
ofmear-143
takes precedence over the inheritedruntime
scope.This, I guess is in line with what is specified in the second bullet point in the section you have referred above. Quoting it here and highlighting in bold and italics the relevant parts:
所选答案足以阐明关键点:dependencyManagement 是否优先取决于子依赖项是显式声明还是传递声明。
作为一个优点,我刚刚创建了一个有关版本和版本的摘要。范围解析完全解决这个问题:
假设依赖项
A
在不同的方式,每个都有不同的版本......哪个版本会最后获胜?只需记住图中的三个规则即可:
,您将找出图中红色编号列表所示的优先级顺序。
The selected answer is good enough to clarify the key point that whether
dependencyManagement
takes precedence relies on whether the child dependency is declared explicitly or transitively.As a plus, I just created a summary concerned with version & scope resolution to kill this problem totally:
Assuming that a dependency
A
is declared eight times in different ways, and each with a different version... which version will win last?just remember the three rules in the picture:
and you will figure out the priority sequence shown as red numbered list in the picture.