Difference between compile and runtime configurations in Gradle

My question is a little bit common, but it is linked with Gradle too.

Why we need compile and runtime configuration?

When I compile something I need artifacts to convert my java classes in bytecode so I need compile configuration, but why is needed runtime configuration do I need something else to run my application in JVM?

Sorry if it sounds stupid, but I don't understand.


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 internally 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.