Gradle 编译和运行时配置的差异

我的问题有点常见,但它也与格拉德尔有关。

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

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

如果这听起来很蠢,我很抱歉,但我不明白。

65529 次浏览

In the most common case, the artifacts needed at compile time are a subset of those needed at runtime. For example, let's say that a program called app uses library foo, and library foo foo0 uses library bar. Then only foo is needed to compile app, but both foo and bar are needed to run it. This is why by default, everything that you put on Gradle's compile configuration is also visible on its runtime configuration, but the opposite isn't true.

Updating the answer as per the latest gradle versions.

From gradle's official documentation at below link:

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

Deprecations

Dependencies should no longer be declared using the compile and runtime configurations The usage of the compile and runtime configurations in the Java ecosystem plugins has been discouraged since Gradle 3.4.

The implementation, api, compileOnly and runtimeOnly configurations should be used to declare dependencies and the compileClasspath and runtimeClasspath configurations to resolve dependencies.

More so, the compile dependency configuration has been removed in the recently released Gradle 7.0 version.

If you try to use compile in your Gradle 3.4+ project you’ll get a warning like this:

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0. Use ‘–warning-mode all’ to show the individual deprecation warnings.

You should always use implementation rather than compile for dependencies, and use runtimeOnly instead of runtime.

What is an implementation dependency?

When you’re building and running a Java project there are two classpaths involved:

Compile classpath – Those dependencies which are required for the JDK to be able to compile Java code into .class files.

Runtime classpath – Those dependencies which are required to actually run the compiled Java code.

When we’re configuring Gradle dependencies all we’re really doing is configuring which dependencies should appear on which classpath. Given there are only two classpaths, it makes sense that we have three options to declare our dependencies.

  1. compileOnly – put the dependency on the compile classpath only.
  2. runtimeOnly – put the dependency on the runtime classpath only.
  3. implementation – put the dependency on both classpaths.

Use the implementation dependency configuration if you need the dependency to be on both the compile and runtime classpaths. If not, consider compileOnly or runtimeOnly.