Inside the configuration block, we use the name of a dependency configuration followed by the description of our dependencies. The name of the dependency configuration can be defined explicitly in the build file or can be added by a plugin we use. In Gradle, we can define several types of dependencies. In the following table, we will see the different types we can use:
External module dependencies
External module dependencies are the most common dependencies in projects. These dependencies refer to a module in an external repository. Later in the book, we will find out more about repositories, but basically, a repository stores modules in a central location. A module contains one or more artifacts and meta information, such as references to the other modules it depends on.
We can use two notations to define an external module dependency in Gradle. We can use a string notation or a map notation. With the map notation, we can use all the properties available for a dependency. The string notation allows us to set a subset of the properties but with a very concise syntax.
In the following example Gradle build file, we define several dependencies using the string notation:
The string notation has the following format: moduleGroup:moduleName:version. Before the first colon, the module group name is used, followed by the module name, and the version is mentioned last.
If we use the map notation, we use the names of the attributes explicitly and set the value for each attribute. Let's rewrite our previous example build file and use the map notation:
We can specify extra configuration attributes with the map notation, or we can add an extra configuration closure. One of the attributes of an external module dependency is the transitive
attribute. We learn more about how to work with transitive dependencies in Chapter 3, Resolving Dependencies. In the next example build file, we will set this attribute using the map notation and a configuration closure:
In the rest of this section, you will learn about more attributes you can use to configure a dependency.
Once of the advantages of Gradle is that we can write Groovy code in our build file. This means that we can define methods and variables and use them in other parts of our Gradle file. This way, we can even apply refactoring to our build file and make maintainable build scripts. Note that in our examples, we included multiple dependencies with the com.vehicles
group name. The value is defined twice, but we can also create a new variable with the group name and reference of the variable in the dependencies configuration. We define a variable in our build file inside an ext
configuration block. We use the ext
block in Gradle to add extra properties to an object, such as our project.
The following sample code defines an extra variable to hold the group name:
If we define an external module dependency, then Gradle tries to find a module descriptor in a repository. If the module descriptor is available, it is parsed to see which artifacts need to be downloaded. Also, if the module descriptor contains information about the dependencies needed by the module, those dependencies are downloaded as well. Sometimes, a dependency has no descriptor in the repository, and it is only then that Gradle downloads the artifact for that dependency.
A dependency based on a Maven module only contains one artifact, so it is easy for Gradle to know which artifact to download. But for a Gradle or Ivy module, it is not so obvious, because a module can contain multiple artifacts. The module will have multiple configurations, each with different artifacts. Gradle will use the configuration with the name default
for such modules. So, any artifacts and dependencies associated with the default
configuration are downloaded. However, it is possible that the default
configuration doesn't contain the artifacts we need. We, therefore, can specify the configuration
attribute for the dependency configuration to specify a specific configuration that we need.
The following example defines a configuration
attribute for the dependency configuration:
When there is no module descriptor for a dependency, only the artifact is downloaded by Gradle. We can use an artifact-only notation if we only want to download the artifact for a module with a descriptor and not any dependencies. Or, if we want to download another archive file, such as a TAR file, with documentation, from a repository.
To use the artifact-only notation, we must add the file extension to the dependency definition. If we use the string notation, we must add the extension prefixed with an @
sign after the version. With the map notation, we can use the ext
attribute to set the extension. If we define our dependency as artifact-only, Gradle will not check whether there is a module descriptor available for the dependency. In the next build file, we will see examples of the different artifact-only notations:
A Maven module descriptor can use classifiers for the artifact. This is mostly used when a library with the same code is compiled for different Java versions, for example, a library is compiled for Java 5 and Java 6 with the jdk15
and jdk16
classifiers. We can use the classifier
attribute when we define an external module dependency to specify which classifier we want to use. Also, we can use it in a string or map notation. With the string notation, we add an extra colon after the version attribute and specify the classifier. For the map notation, we can add the classifier
attribute and specify the value we want. The following build file contains an example of the different definitions of a dependency with a classifier:
In the following section, we will see how we can define client module dependencies in our build file.
Using internal Gradle and Groovy dependencies
When we write code to extend Gradle, such as custom tasks or plugins, we can have a dependency on the Gradle API and possibly the Groovy libraries used by the current Gradle version. We can use the gradleApi
and localGroovy
methods in our dependency configuration to have all the right dependencies.
If we are writing some Groovy code to extend Gradle, but we don't use any of the Gradle API classes, we can use localGroovy
. With this method, the classes and libraries of the Groovy version shipped with the current Gradle version are added as dependencies. The following example build script uses the Groovy plugin and adds a dependency to the compile
configuration on Groovy bundled with Gradle:
When we write custom tasks or plugins for Gradle, we are dependent on the Gradle API. We need to import some of the API's classes in order to write our code. To define a dependency on the Gradle classes, we use the gradleApi
method. This will include the dependencies for the Gradle version the build is executed for. The next example build file will show the use of this method: