我的问题有点常见,但它也与 Gradle 有关。
为什么我们需要编译和运行时配置?
当我编译某些东西时,我需要工件来将我的 java 类转换为字节码,所以我需要编译配置,但是为什么需要运行时配置我还需要其他东西来在 JVM 中运行我的应用程序吗?
对不起,如果这听起来很愚蠢,但我不明白。
我的问题有点常见,但它也与 Gradle 有关。
为什么我们需要编译和运行时配置?
当我编译某些东西时,我需要工件来将我的 java 类转换为字节码,所以我需要编译配置,但是为什么需要运行时配置我还需要其他东西来在 JVM 中运行我的应用程序吗?
对不起,如果这听起来很愚蠢,但我不明白。
在最常见的情况下,编译时所需的工件是运行时所需工件的子集。例如,假设一个名为的程序app
使用 library foo
,而 libraryfoo
内部使用 library bar
。然后只foo
需要 compile app
,但两者foo
和bar
都需要运行它。这就是为什么默认情况下,您在 Gradle 配置中放置的所有内容compile
在其配置中也是可见的runtime
,但反之则不然。
根据最新的 gradle 版本更新答案。
来自以下链接的 gradle 官方文档:
https://docs.gradle.org/current/userguide/upgrading_version_5.html
弃用
不应再使用编译和运行时配置声明依赖关系自 Gradle 3.4 以来,不鼓励在 Java 生态系统插件中使用编译和运行时配置。
应该使用 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。