113

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.

Flow
  • 23,572
  • 15
  • 99
  • 156
Xelian
  • 16,680
  • 25
  • 99
  • 152

2 Answers2

166

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.

Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
  • 22
    Shame this isn't mentioned explicitly in http://www.gradle.org/docs/current/userguide/dependency_management.html. They use both compile and runtime without stating explicitly their meaning... – Silas Davis Oct 20 '14 at 14:49
  • 2
    @silasdavis In the documentation explains the difference: http://www.gradle.org/docs/current/userguide/userguide_single.html#configurations in 8.3. Dependency configurations – angelcervera Oct 22 '14 at 09:51
  • @angelcervera Ah so it does, 8. Dependency Management Basics, and 51. Dependency Management. I can see why they have two sections, but perhaps it would be nice if the latter referenced the former. I think I landed on 51 and expected it to give a full account. – Silas Davis Oct 27 '14 at 11:24
  • @silasdavis True. The same for other sections in the documentation. I must take same free time to read all documentation from A to Z. – angelcervera Oct 27 '14 at 13:03
  • Note that `compile` and `runtime` is dependency configurations of `java` plugin. You can read more about this here https://docs.gradle.org/current/userguide/userguide_single.html#tab:configurations – mixel Jul 27 '15 at 11:02
  • 1
    @Peter Niederwieser If the compile task shows the same dependencies as runtime, in what scenario would you use runtime as opposed to compile? – rj2700 Aug 17 '17 at 15:44
  • @rj2700 One could conceivably _compile_ against a set of interfaces and inject different implementations into different artifacts for _runtime_. Java security providers may be one example, Kotlin multi-platform projects another. That said, I haven't come across a use case myself. – Raphael Apr 16 '19 at 16:29
19

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.

KnockingHeads
  • 1,569
  • 1
  • 22
  • 42