为什么 Maven 依赖的顺序很重要?

我认为 Maven 依赖关系的顺序以前并不重要,并且认为这是它的一个优点。这是我的旧 pom.xml的依赖项:

<dependencies>


<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.19</version>
</dependency>


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>


<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.19</version>
</dependency>


<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.19</version>
</dependency>


</dependencies>

它工作得很好,今天我想移动春季依赖到底部,这样那些球衣相关的可以在一起。然而,我的 Jetty 抱怨道:

[ERROR] Failed to execute goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run (default-cli) on project mtest: Execution default-cli of goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run failed: A required class was missing while executing org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run: org/apache/commons/logging/LogFactory

这真的很令人困惑,所以我必须考虑依赖顺序吗? 我如何知道正确的顺序?

42290 次浏览

从2.0.9版开始,Maven 如何解决传递依赖关系,因此依赖关系 是的的顺序很重要。节选自 文件:

(...)这决定了当遇到工件的多个版本时将使用依赖项的哪个版本。(...)总是可以通过在项目的 POM 中显式声明它来保证版本。(...)从 Maven 2.0.9开始,声明中的顺序就起作用了: 第一个声明获胜

要扩展另一个答案(声明顺序影响 Maven 的传递依赖关系的依赖中介) ,有几个工具可以使用:

  • mvn dependency:tree [-Dscope=[runtime|test]]将向您显示所选范围的可用依赖项
  • mvn dependency:build-classpath给出类路径上可用依赖项的顺序(如果两个或多个类路径条目具有相同的类,则前者胜出)。详情请参阅此处

我不太了解您的情况,但通常情况下,您在编译/运行时得到的是错误的1个或更多 jar 版本。声明您自己的有问题的库版本或锁定该版本<dependencyManagement>是这里的选项。

现在回答你的另一个问题 -如何知道声明依赖项时的正确顺序?

我的建议 -正确的声明顺序是按照所需的顺序获取所需依赖项的版本的顺序。使用上面的工具检查您的依赖关系,并在必要时调整声明的顺序。

注意,大多数 jar 包含名称不连贯的类,因此 jar 在类路径中出现的确切顺序通常并不那么重要。我注意到的唯一例外是 一些 SLF4J 的罐子,它有意从其他日志程序库中隐藏它打算替换的类。