为Maven依赖声明多个范围的正确方法?

Adr*_*hum 53 maven-3 maven

我有一个依赖项,我想在test范围内使用(因此它在运行单元测试时在类路径中),并且在runtime范围内(这样我可以在WAR/EAR /其他包装中包含它用于部署,但不影响依赖工件的传递依赖查找).

一个真实的例子是SLF4J的实现JAR(例如Logback).我希望它在运行测试时存在于类路径中,并且我希望它包含在我的WAR/EAR中,但我不希望项目依赖于我的项目将其包含在传递依赖项查找中.

我尝试使用,<scope>test,runtime</scope>但Maven 3发出警告:

[WARNING] 'dependencies.dependency.scope' for org.slf4j:jcl-over-slf4j:jar 
must be one of [provided, compile, runtime, test, system] but is 'test,runtime'. 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,声明依赖范围的正确方法是什么?

Chr*_*her 36

运行时作用域还使测试类路径上的工件可用.只需使用运行时.(参见Maven 文档.)

为了避免依赖传递地解决,也使其可选<optional>true</optional>:

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback</artifactId>
  <version>0.5</version>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>
Run Code Online (Sandbox Code Playgroud)

  • 但是,在编译测试源时,工件不可用,我认为这是他所需要的.至少,这就是我想弄清楚的.我希望它可用于测试编译和运行,但在编译期间(故意)不能用于主工件. (19认同)
  • @Christopher从我的实验中看来,voor是正确的:当我使用运行时作用域时,我的测试中出现了编译错误. (6认同)
  • @voor 我不认为你是对的。在编译测试源时,运行时范围的工件也应该可用。如果不是这种情况,我会认为这是 Maven 中的一个错误。 (2认同)
  • @jplandrain这听起来像一个bug,它违背了记录/预期的行为.我建议你在https://issues.apache.org/jira/browse/MNG上提交一个问题并演示一个示例项目的问题,以便修复它. (2认同)
  • @mwKART 导入和运行时范围没有意义。导入范围不是真正的范围。它只是特殊的语法,包含在单独的 POM 文件中声明的 dependencyManagement 部分,以便于重用。我建议这是适合在 dependencyManagement 部分中声明的*唯一*范围。当您使用它时,您的实际范围(例如运行时)应该在依赖项部分中声明。 (2认同)
  • @mwKART POM A 在其 `&lt;dependencyManagement&gt;` 部分中声明对具有“导入”范围的 POM B 的依赖关系。在 POM B 中,您有一个“&lt;dependencyManagement&gt;”部分,其中包含实际的依赖项及其版本。当 POM B 被“导入”到 POM A 中时,POM B 的 `&lt;dependencyManagement&gt;` 部分会替换 POM A 中 POM B 的条目。当您想要在特定的 *真实* 范围内实际使用 POM B 的依赖项时,请指定它作为 POM A 的 `&lt;dependency&gt;` 部分中的“运行时”(或其他内容)。请参阅https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies (2认同)

Pre*_*shi 18

不确定这是否仍然可以帮助仍在寻找简单方法的人 - https://howtodoinjava.com/maven/maven-dependency-scopes/此链接帮助我添加了正确的范围。以下是范围映射和我们需要依赖项的阶段的摘要。

  1. 编译 - 构建、测试和运行
  2. 提供 - 构建和测试
  3. 运行时-测试并运行
  4. 测试——编译和测试

因此,当我在测试和运行时需要依赖项时,我将范围指定为“运行时”,并且它按预期工作。


car*_*ing 12

您只能为每个<scope/>标记定义一个范围值.

我担心仅仅使用示波器无法实现您想做的事情.如果您定义范围test,它将仅在测试期间可用; 如果您定义了提供的范围,那么这意味着您希望在编译和测试期间解析和使用项目的依赖关系,但它不会包含在WAR文件中.不管怎样,这不是你想要的.

因此,我建议你看看maven-assembly-plugin,你可以用它实现它,但它仍然需要一些游戏.


小智 7

声明具有范围的依赖项runtime可确保在编译期间库不可用.

将依赖项声明为可选项会导致依赖项解析过程中断; 取决于您的库的项目将需要明确地包含依赖项本身.

所以声明这个的正确方法是:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.13</version>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>
Run Code Online (Sandbox Code Playgroud)