1

我继承了一个具有数十个“提供”范围依赖项的 Maven 项目。我正在插入一个新的依赖项,该依赖项本身依赖于前面提到的“提供”依赖项之一。这个新依赖的范围是“compile”/default 标签。

该应用程序在没有添加新依赖项的情况下工作。使用新依赖项成功编译应用程序后,应用程序在运行时失败,因为新依赖项找不到“提供的”依赖项。

是否有必要让所有“提供的”依赖项与“提供的”依赖项一起工作(并且与任何其他范围相同——它们只与他们的类型一起工作)?我想不出任何其他解释为什么新的默认/“编译”依赖项不能与现有的“提供”依赖项一起使用。正如我所提到的,在引入任何新的依赖项之前,它们已经被明确地提供和工作了。任何帮助表示赞赏!我一直在使用有关范围的 Maven 文档和这篇SO 帖子

4

1 回答 1

1

问题不在于您的编译依赖项依赖于提供的依赖项,而是提供的依赖项在运行时不存在。我只能猜测为什么会这样,但一个可能的解释是它已经丢失了,只是之前没有人在运行时实际使用过该依赖项,所以没关系。


本质上,通过建立依赖关系:

  • compile,你说“我需要这个来编译我的代码,我在运行时也需要它”
  • 提供,你说“我需要这个来编译我的代码,但在运行时其他人会提供它”
  • runtime,你说“我不需要它来编译我的代码,但在运行时需要它”

compile是默认和最常见的范围,因为大多数依赖项在编译时和运行时都需要,所以告诉 Maven 在这两种情况下传播它们是有意义的。

提供的适用于其他人将在运行时提供库的情况(例如,servlet 容器通常会提供 aservlet-api.jar作为基础架构的一部分)。但是,当您需要针对某些库进行编译时,此范围有时也(ab)用于奇怪的情况,但在运行时将/可能不会实际使用它(例如,可选功能)。对于您的情况,如果依赖项实际上不是在运行时提供并且尝试在运行时使用它,应用程序只会在提供的依赖项上失败,这一点也很重要。

当存在 API 工件和实现工件时,运行时slf4j-api是非常常见的范围,例如和slf4j-log4j- 然后您只需要在编译时使用 API,但在运行时需要 API 和实际实现。

于 2018-08-31T21:23:05.387 回答