Maven依赖性问题:提供的和编译的依赖性一起工作

时间:2018-08-31 21:02:17

标签: java maven maven-dependency

我继承了一个带有数十个“提供的”范围内的依赖项的Maven项目。我正在插入一个新的依赖项,该依赖项本身是对先前提到的“提供的”依赖项中的依赖项。这个新的依赖项的范围为“ compile” /默认标记。

该应用程序无需添加新的依赖项即可运行。使用新的依赖关系成功编译应用程序后,由于新的依赖关系找不到“提供的”依赖关系,因此应用程序在运行时失败。

所有“提供的”依赖项是否都必须与“提供的”依赖项一起工作(是否与其他作用域相同-它们仅适用于其种类)是否必要?对于新的默认/“编译”依赖项为何无法与现有“提供”的依赖项一起工作,我想不出任何其他解释。正如我已经提到的,在引入任何新的依赖项之前,已经清楚地提供了它们并可以使用它们。任何帮助表示赞赏!我一直在使用maven documentation on scopes和这个SO post

1 个答案:

答案 0 :(得分:1)

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


本质上,通过建立依赖性:

  • 编译,您说的是“我需要它来编译我的代码,我也需要在运行时使用它”
  • 已提供,您说的是“我需要它来编译我的代码,但在运行时其他人会提供它”
  • 运行时,您说的是“我不需要它来编译我的代码,但在运行时会需要它”

编译是默认的也是最常见的范围,因为在编译时和运行时都需要大多数依赖项,因此有必要告诉Maven在这两种情况下都进行传播。 / p>

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

运行时的范围很广,当存在API工件和实现工件(例如slf4j-apislf4j-log4j)时-那么您只需要在编译时使用API​​,但在运行时需要API和实际实现。