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

Posted

技术标签:

【中文标题】Gradle 中编译和运行时配置的区别【英文标题】:Difference between compile and runtime configurations in Gradle 【发布时间】:2013-05-18 01:06:37 【问题描述】:

我的问题有点常见,但也与 Gradle 相关。

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

当我编译某些东西时,我需要工件来将我的 java 类转换为字节码,所以我需要编译配置,但是为什么需要运行时配置我还需要其他东西来在 JVM 中运行我的应用程序?

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

【问题讨论】:

【参考方案1】:

在最常见的情况下,编译时所需的工件是运行时所需工件的子集。例如,假设一个名为app 的程序使用库foo,而库foo 在内部 使用库bar。那么编译app只需要foo,但是运行它需要foobar。这就是为什么默认情况下,您在 Gradle 的 compile 配置中放置的所有内容在其 runtime 配置中也可见,但反之则不然。

【讨论】:

很遗憾gradle.org/docs/current/userguide/dependency_management.html 中没有明确提及这一点。他们使用编译和运行时没有明确说明它们的含义...... @silasdavis 在文档中解释了区别:gradle.org/docs/current/userguide/… 在 8.3 中。依赖配置 @angelcervera 嗯,确实如此,8. 依赖管理基础知识和 51. 依赖管理。我可以理解为什么它们有两个部分,但是如果后者引用前者可能会很好。我想我登陆 51 并期望它能够提供完整的说明。 @silasdavis 是的。文档中的其他部分也是如此。我必须花同样的空闲时间阅读从 A 到 Z 的所有文档。 @Peter Niederwieser 如果编译任务显示与运行时相同的依赖关系,在什么情况下您会使用运行时而不是编译?【参考方案2】:

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

来自以下链接的 gradle 官方文档:

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

弃用

不应再使用编译和运行时配置声明依赖关系编译和运行时的使用 不鼓励 Java 生态系统插件中的配置 从 Gradle 3.4 开始。

需要使用 implementation、api、compileOnly 和 runtimeOnly 配置来声明依赖和 compileClasspath 和 runtimeClasspath 配置来解决依赖关系。

更重要的是,在最近发布的 Gradle 7.0 版本中,已经删除了编译依赖配置。

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

此版本中使用了已弃用的 Gradle 功能,使其 与 Gradle 7.0 不兼容。使用‘–warning-mode all’来显示 个别弃用警告。

您应该始终使用实现而不是编译依赖项,并使用 runtimeOnly 而不是运行时。

什么是实现依赖?

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

编译类路径 – JDK 能够将 Java 代码编译为 .class 文件所需的那些依赖项。

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

当我们配置 Gradle 依赖项时,我们真正要做的就是配置哪些依赖项应该出现在哪个类路径上。鉴于只有两个类路径,因此我们可以使用三个选项来声明我们的依赖项。

    compileOnly - 仅将依赖项放在编译类路径上。 runtimeOnly - 仅将依赖项放在运行时类路径上。 实现 - 将依赖项放在两个类路径上。

如果您需要依赖项同时位于编译和运行时类路径上,请使用实现依赖项配置。如果不, 考虑 compileOnly 或 runtimeOnly。

【讨论】:

如果我只想要定义,这是一个很好的答案。 :D

以上是关于Gradle 中编译和运行时配置的区别的主要内容,如果未能解决你的问题,请参考以下文章

Gradle 几种依赖方式的区别

gradlew和gradle的区别

AS 根目录结构说明

如何在 Gradle 中定义编译时 *only* 类路径?

如何在 Gradle 中定义编译时 *only* 类路径?

AS的run按钮不能运行gradle