137

When adding dependencies to my project I am never sure what prefix I should give them, e.g. "classpath" or "compile".

For example, should my dependencies below be compile time or classpath?

Also, should this be in my applications build.gradle or in the module specific build.gradle?

Current build.gradle (at application level):

apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'org.hibernate:hibernate-core:5.0.5.Final' compile 'mysql:mysql-connector-java:5.1.38' } 
4
  • 2
    I'm not sure I understand. classpath is not a valid dependency scope. Commented Dec 15, 2015 at 10:16
  • Perhaps im getting confused, what are the valid dependency scopes? Commented Dec 15, 2015 at 10:17
  • Take a look at this document: docs.gradle.org/current/userguide/… Commented Dec 15, 2015 at 10:18
  • One thing i noticed is that compileOnly dependencies go to project.configurations.compileClasspath but not to project.configurations.compile, as mentioned here github.com/iboyko/gradle-plugins/issues/5 Commented Jul 28, 2017 at 19:50

4 Answers 4

93

If buildscript itself needs something to run, use classpath.

If your project needs something to run, use compile.

The buildscript{} block is for the build.gradle itself.

For multi-project building, the top-level build file is for the root project, the specific build file is for sub-project (module).

Top-level build file where you can add configuration options common to all sub-projects/modules.

Do not place your application dependencies in top-level build file, they belong in the individual module build.gradle files

Sign up to request clarification or add additional context in comments.

3 Comments

To confirm: does that mean that proandroiddev.com/… should be using a compile and not a classpath ?
But why not place the application dependencies in the top level file itself if the project has just one module, like the typical android applications?
@Harsha the gradle files are generated by Android Studio wizard. The creators of the wizard chose to make it possible to have multiple modules in the multi-project build. With that intent, it's logical not to assume the dependencies in the root project are not going to be shared in all of your modules. If you are sure you'll have only one module, you can put all of your dependencies inside allprojects block of the root build.gradle file.
65

I'm going to guess that you're referencing compile and classpath within the dependencies {} block. If that is so, those are dependency Configurations.

A configuration is simply a named set of dependencies.

The compile configuration is created by the Java plugin. The classpath configuration is commonly seen in the buildScript {} block where one needs to declare dependencies for the build.gradle, itself (for plugins, perhaps).

4 Comments

Thanks, so for my main build.gradle I should not need to use classpath?
@java123999 No, unless you use custom-written plugins
@EricWendelin Where you say "within the dependencies {} block" do you mean "within the buildscript { dependencies{}} block"? (I'm not sure, just asking.)
A dependencies {} block can be declared both inside buildscript {} and outside of it. When inside, you use the classpath configuration for dependencies needed to compile the build script itself.
32

If I understand correctly, you're confusing Project.dependencies script block with the Project.buildscript.dependencies script block (just like I did when I reached this question).

I'll try to answer this with what I found.

I think you should be already familiar with the Project.dependencies script block. In this block, we declare dependencies that are required by our source code. There are several ways to declare a dependency that we need for the project. See Gradle Tutorial: Dependency Types. I'll only mention the part that is the most relevant to this problem:

compile 'org.hibernate:hibernate-core:5.0.5.Final' is a module dependency declaration. The compile configuration (which is now deprecated by the implementation configuration.) is merely a keyword for Implementation only dependencies. It is not a keyword describing which type of dependency it is (by type here I'm following the three types defined in the tutorial, i.e. module, file, and project.)

In Gradle Tutorial: Organizing Build Logic it says:

If your build script needs to use external libraries, you can add them to the script’s classpath in the build script itself. You do this using the buildscript() method, passing in a closure which declares the build script classpath.

This is the same way you declare, for example, the Java compilation classpath. You can use any of the dependency types described in Dependency Types, except project dependencies.

Having declared the build script classpath, you can use the classes in your build script as you would any other classes on the classpath.

I hope things are getting clear to you now.

With classpath "com.android.tools.build:gradle:${Versions.android_gradle_plugin}" we're setting classpath method with com.android.tools.build:gradle:${Versions.android_gradle_plugin} which is a module dependency that is used by the build script itself rather than the source in your project.

On the other hand, with compile 'org.hibernate:hibernate-core:5.0.5.Final' we're declaring a module dependency required for your project with the compile configuration.

tl;dr: The classpath, compile, and implementation are all keywords that can be used against dependencies under different circumstances. The former is used when you want to pass in a dependency to the build script, and the latter is one of the configuration you may want to declare.

1 Comment

Good answer. I have to add, that not only must we stare at the keywords themselves as what is nicely explained above, but in addition we also must take into consideration the artifact that is being requested because the keywords alone does not define the complete context. For example, 'org.projectlombok:lombok:1.18.4' has no classpath association because it is a jar that is only needed during compile javac time but not needed on java runtime. Therefore, correct usage is an interplay of the defined keywords and the artifact. This means, one needs a-priori knowledge.
3

Android:

classpath in project build.gradle —— the implementation after classpath is only used by gradle it self, used in build script. So if i add the implementation (such as retrofit) in the project build.gradle classpath 'retrofit...', i can't get retrofit in my code!! Because —— my code can't see it, only the buildscript can see it.

implementation in app build.gradle —— add the implementation your code can use!!

2 Comments

i see a commet like this —— “But why not place the application dependencies in the top level file itself if the project has just one module, like the typical android applications? ” it will not work!! Reasom is above!
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.