在Maven中将传递依赖性限制为运行时范围

时间:2012-06-15 03:33:53

标签: maven maven-3

我有使用Maven的2个项目。第一个是包含实用程序类和方法的库。第二个项目是一个将库作为依赖项的实际应用程序。我的库在内部使用第三方库。

所以这些是依赖项:

  • 我的图书馆:取决于第三方图书馆
  • 我的申请:取决于我的图书馆

但是,我不希望第三方库类在我的应用程序中编译时。这是因为应用程序由大型团队支持,并且我希望防止人们在应用程序中意外使用第三方库中的方法,因为某些类名称和某些方法名称在两者之间是相似的。当然,我的应用程序必须在运行时中提供第三方库。

如果我所有依赖项的范围是编译,那么它就无法实现我的目标。有没有办法在Maven 3中实现这个目标?

6 个答案:

答案 0 :(得分:18)

非常好的问题,遗憾的是,由于其基本设计,您无法使用Maven 3,或2或任何其他版本执行此操作。您所询问的实际上是一种理想的行为,因为事实上任何工件的compile依赖都应该与runtime范围一致。但是,这样的设计会导致一些问题。正如您可以在Maven's Introduction to the Dependency Mechanism处了解compile范围:

  

应该考虑[编译依赖项的传递依赖关系,它们本身就是编译依赖关系]运行时范围,所以所有   必须明确列出编译依赖项 - 但是,有   您依赖的库扩展了另一个类的情况   库,强制您在编译时可用。为了这   原因,编译时依赖性仍然作为编译范围,即使在   它们是传递性的。

因此,正如您所看到的,您需要的实际上是这种行为的正确设计,遗憾的是无法实现。

答案 1 :(得分:5)

在过去三年中没有任何变化,因此Michal的答案仍然是正确的:没有办法限制Maven中的传递可见性。

但是,你应该考虑重新设计你的库,把它拆分成一个api工件,这个工件是编译时依赖所必需的,它本身不依赖于第三方库和一个只需要作为运行时依赖的实现工件。这取决于第三方图书馆。

答案 2 :(得分:2)

在您的应用程序中,您可以使用“运行时”范围声明对第三方库的显式依赖。

这可以防止在编译时看到第三方库,因此没有直接的用法可以潜入。但是,它仍然会在运行时出现(因为你的库需要它)。

这很有效,但很难处理,并且在pom中应该有一个解释性的XML注释。

答案 3 :(得分:1)

其他答案都是正确的。除了通过拆分人工API模块解决maven中缺少的关键功能外,您还可以选择以下方法:

  • 排除传递依赖关系,然后直接依赖它们(您必须自己管理版本号)
  • 使用checkstyle导入控件和CI。这样团队成员可以使用传递,但随后maven验证将失败
  • 使用gradle。这是Maven的许多限制的解决方案

答案 4 :(得分:0)

您可以使用以下代码分析依赖关系:mvn dependency:analyze或将依赖关系分析为验证生命周期阶段的一部分: https://maven.apache.org/plugins/maven-dependency-plugin/examples/failing-the-build-on-dependency-analysis-warnings.html

答案 5 :(得分:0)

似乎有效的方法是使用pom中的<dependencyManagement>部分。 您将要检查是否有任何副作用,因为它在整个项目范围内都有效。而且您必须专门指定每个库。

以下代码示例使我可以将番石榴(谷歌guice在项目中将其作为编译时传递的依赖项强制移植)到各处的运行时依赖项。

<dependencyManagement> <dependencies> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <scope>runtime</scope> </dependency> </dependencies> </dependencyManagement>