我有使用Maven的2个项目。第一个是包含实用程序类和方法的库。第二个项目是一个将库作为依赖项的实际应用程序。我的库在内部使用第三方库。
所以这些是依赖项:
但是,我不希望第三方库类在我的应用程序中编译时。这是因为应用程序由大型团队支持,并且我希望防止人们在应用程序中意外使用第三方库中的方法,因为某些类名称和某些方法名称在两者之间是相似的。当然,我的应用程序必须在运行时中提供第三方库。
如果我所有依赖项的范围是编译,那么它就无法实现我的目标。有没有办法在Maven 3中实现这个目标?
答案 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中缺少的关键功能外,您还可以选择以下方法:
答案 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>