35

The docs mention that implementation provides significant build time improvements over compile/api. What about compileOnly?

My use case is a multi-module (sorry I don't like Gradle's multi-project terminology) project, where I have an Android app, and multiple libraries that the app depends on (implementation). Some of the libraries also depend on one another. Should I use implementation or compileOnly when declaring dependencies in the library modules? My app module will be using implementation to depend on those artifacts, so I don't need them to be transitive through the library modules.

Eliezer
  • 7,209
  • 12
  • 56
  • 103
  • 2
    `compileOnly` means that those dependencies would be accessible though compile time only, and **not** accessible during runtime. If you module does not need those dependencies on runtime I see no issues declaring them `compileOnly`. – azizbekian Oct 17 '17 at 08:22
  • 1
    That doesn't address the question, which is regarding performance. – Eliezer Oct 17 '17 at 08:24

1 Answers1

35

The api configuration should be used for dependencies that are exported to external modules (transitive dependency). Vice-Versa implementation configuration should be used for dependencies that are internal to the component (not transitive dependency).

implementation vs compileOnly:

There is no similarity in their job, compileOnly is

  • a configuration inherited from java-plugin
  • required at compile time
  • also not included in the runtime classpath or exposed to dependent projects.

So compileOnly doesn't replace the implementation configuration job e.g:

implementation 'com.android.support:appcompat-v7:25.1.0' // can't use compileOnly here
testCompile 'junit:junit:4.12'

compile "com.google.dagger:dagger:2.8" // can't use here also
annotationProcessor "com.google.dagger:dagger-compiler:2.8" // can't use here also
compileOnly 'javax.annotation:jsr250-api:1.0' // we can use compileOnly here because it's required on run time only.

Since your case is a "multi-module", you have to use the api configuration, until you reach the final module it's better to use implementation.

Following graph describe those configurations:

enter image description here

Performance?

I think api requires more memory because gradle will snapshot every class in that transitive module, vice versa implementation is a preferred configuration because (as mentioned above) it's used for its own internal implementations.

Kartik Shandilya
  • 3,796
  • 5
  • 24
  • 42
  • Thank you for the explanation, but my question is what improvements, if any, are there to using `compileOnly` over `implementation`. – Eliezer Oct 17 '17 at 09:27
  • Still not quite there. The gradle doc for `compileOnly` says "Dependencies whose API is required at compile time but whose `implementation` is to be provided by a consuming library, application or runtime environment." My question is, is there any benefit to declaring my library's dependencies as `compileOnly` vs `implementation` since both would work (with the caveat being that the consuming module would need to declare those dependencies as `implementation` iif they're in the public API). – Eliezer Oct 17 '17 at 17:08
  • @Eliezer as @azizbekian suggest in comments, if you don't need module in run-time yes use `compileOnly` this well reduce memory usage. –  Oct 17 '17 at 20:26
  • More so then implementation, or on the same level? – Eliezer Oct 17 '17 at 20:57
  • 1
    @Eliezer sry, i didn't under stand that, what you mean? –  Oct 17 '17 at 21:01
  • Is using `compileOnly` going to give better performance than using `implementation`, the same performance as `implementation`, or worse performance than `implementation`? – Eliezer Oct 17 '17 at 21:23
  • 1
    `Is using compileOnly going to give better performance than using implementation` sure. –  Oct 17 '17 at 21:42
  • @Ibrahim `compileOnly` & `implementation` r two very different dependency declarations. You use `compileOnly` in a library module to allow a client app to “optionally” implement/use the dependency. If they want to use it, then they’ll have to declare it on their own in their app module. If they don’t declare the dependency, then it’s not added to the classpath, thus making a smaller APK with less dependencies. And sure, it’ll give performance benefits... but that’s not what it’s use case is for. If you just start switching `implementation` for `classPath` you’ll run into trouble quickly. – Sakiboy Feb 28 '18 at 06:24