Gradle中编译和运行时配置的区别

113

我的问题有点普遍,但它也与Gradle有关。

为什么我们需要编译和运行时配置?

当我编译一些东西时,我需要构件来将我的Java类转换为字节码,因此我需要编译配置,但是为什么需要运行时配置?难道我需要其他东西来在JVM中运行我的应用程序吗?

如果听起来很愚蠢,对不起,但我不明白。

2个回答

168

在大多数情况下,编译时所需的构建工具是运行时所需工具的子集。例如,假设程序名为app的程序使用库foo,而库foo内部使用库bar。那么仅需要foo来编译app,但运行它需要foobar两者。这就是为什么默认情况下,您将放置在Gradle的compile配置中的所有内容也会出现在其runtime配置中,但反之则不成立。


22
遗憾的是,http://www.gradle.org/docs/current/userguide/dependency_management.html 中没有明确提到这一点。他们在不明确说明含义的情况下同时使用了“compile”和“runtime”这两个词... - Silas Davis
2
@silasdavis 在文档中解释了区别: http://www.gradle.org/docs/current/userguide/userguide_single.html#configurations,位于第8.3节的依赖配置。 - angelcervera
啊,是的,它确实有,第8节是“依赖管理基础”,第51节是“依赖管理”。我可以理解为什么他们要有两个部分,但也许后者可以引用前者。我想我看到51,期望它给出完整的说明。 - Silas Davis
请注意,compileruntimejava插件的依赖配置。您可以在此处阅读更多信息:https://docs.gradle.org/current/userguide/userguide_single.html#tab:configurations - mixel
1
如果编译任务显示与运行时相同的依赖项,在什么情况下您会使用运行时而不是编译时? - rj2700
显示剩余2条评论

19

根据最新的gradle版本更新答案。

以下链接是从gradle官方文档中获取的:

https://docs.gradle.org/current/userguide/upgrading_version_5.html

弃用功能

不应再使用compile和runtime配置来声明依赖项。自Gradle 3.4以来,Java生态系统插件已经不推荐使用compile和runtime配置。

应该使用implementation、api、compileOnly和runtimeOnly配置来声明依赖项,并使用compileClasspath和runtimeClasspath配置来解析依赖项。

此外,在最近发布的Gradle 7.0版本中,已删除了compile依赖项配置。

如果在Gradle 3.4+项目中尝试使用compile,则会收到如下警告:

本构建使用了已废弃的Gradle功能,与Gradle 7.0不兼容。请使用“--warning-mode all”显示单个过时警告。

您应该始终使用implementation而不是compile来声明依赖关系,并使用runtimeOnly而不是runtime。

什么是实现依赖项?

当构建和运行Java项目时,涉及两个类路径:

编译类路径 - 那些需要用于JDK将Java代码编译为.class文件的依赖。

运行时类路径 - 那些需要实际运行已编译Java代码的依赖。

当我们配置Gradle依赖项时,我们所做的就是配置哪些依赖项应出现在哪个类路径上。鉴于只有两个类路径,因此有三个选项来声明我们的依赖关系。

  1. 仅编译 - 仅将依赖项放置在编译类路径上。
  2. 仅运行时 - 仅将依赖项放置在运行时类路径上。
  3. 实现 - 将依赖项放置在两个类路径上。

如果您需要将依赖项放置在编译和运行时类路径上,请使用实现依赖配置。否则,请考虑仅编译或仅运行时。


1
如果我只想要定义,那么这是一个很好的答案。 :D - Mukul Anand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接