16

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

所以这些是依赖项:

  • 我的库:依赖第三方库
  • 我的应用程序:取决于我的图书馆

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

如果我所有依赖项的范围都是compile,那它就达不到我的目标。有没有办法在 Maven 3 中实现这一点?

4

7 回答 7

20

非常好的问题,不幸的是,由于其基本设计,您不能使用 Maven 3、2 或任何其他版本来做到这一点。您所问的实际上是一种理想的行为,因为实际上任何工件的compile依赖关系都应该是可传递的runtime。然而,这样的设计会导致一些问题。正如您可以在Maven 的依赖机制简介中阅读的关于compile范围的内容:

其目的是 [应考虑编译依赖项的传递依赖项,它们本身就是编译依赖项] 运行时范围,因此必须显式列出所有编译依赖项 - 但是,在某些情况下,您所依赖的库扩展了一个类另一个库,迫使您在编译时可用。出于这个原因,即使编译时依赖项是可传递的,它们仍保留为编译范围。

因此,如您所见,您实际上需要的是对这种行为的正确设计,不幸的是,这种行为是不可能实现的。

于 2012-06-15T07:02:30.000 回答
6

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

但是,您应该考虑重新设计您的库以将其拆分为一个 api-artifact,它是编译时依赖项所必需的,并且它本身不依赖于第三方库和一个仅需要作为运行时依赖项并且依赖于的实现工件第三方库。

于 2015-10-20T20:00:29.160 回答
2

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

这可以防止在编译时看到第三方库,因此不能直接使用。但是,它仍然会在运行时出现(因为您的库需要它)。

这可行,但很尴尬,值得在 pom.xml 中添加解释性 XML 注释。

于 2016-08-15T00:56:55.620 回答
1

其他答案都是正确的。除了通过拆分一个人工 API 模块来解决 maven 中缺少的关键特性之外,您还可以使用以下替代方法:

  • 排除传递依赖,然后直接依赖它们(你必须自己管理版本号)
  • 使用 checkstyle 导入控制和 CI。这样团队成员可以使用传递,但是 Maven 验证将失败
  • 使用梯度。这是对 Maven 的许多限制的解决方案
于 2017-02-01T09:59:09.583 回答
1

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

于 2017-12-08T11:05:28.573 回答
1

似乎有效的是<dependencyManagement>pom.xml 中的使用部分。您将需要检查是否有任何副作用,因为它适用于整个项目。而且您必须具体指定每个库。

以下代码示例允许我强制 guava(在项目中由 google guice 作为编译时传递依赖项 smurfed)到任何地方的运行时依赖项。

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

于 2019-09-23T15:34:29.280 回答
0

你可以这样尝试:

#My application pom.xml
 <dependencies>
        <dependency>
            <groupId>My groupId</groupId>
            <artifactId>My library</artifactId>
            <version>${version}</version>
            <exclusions>
                <exclusion>
                    <groupId>third-party library</groupId>
                    <artifactId> third-party library</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>third-party library</groupId>
            <artifactId> third-party library</artifactId>
            <version>${version}</version>
            <scope>runtime</scope>
        </dependency>
</dependencies>
于 2021-10-18T13:45:18.477 回答