Debug School

rakesh kumar
rakesh kumar

Posted on

Dependency management in Gradle

dependency_management
gradle-dependencies

Dependenies projet  depends on other library
Enter fullscreen mode Exit fullscreen mode

What is dependency management?
Software projects rarely work in isolation. In most cases, a project relies on reusable functionality in the form of librariesor is broken up into individual components to compose a modularized system. Dependency management is a technique for declaring, resolving and using dependencies required by the project in an automated fashion.

Gradle build script describes a process of building projects. Most of the projects are not self-contained. They need some files to compile and test the source files. For example, to use Hibernate, we must include some Hibernate JARs in the classpath. Gradle uses some unique script to manage the dependencies, which needs to be downloaded.

The dependencies are used to assist a task, such as required JAR files of the project and external JARs. Every dependency is applied to a specified scope. For example, dependencies are used to compile the source code, and some will be available at runtime. Gradle signifies the scope of a dependency with the help of a Configuration, and a unique name can recognize every configuration. Most of the Gradle plugins support pre-defined configuration for the projects.

Gradle considers the outcomes of building and publishing the projects. Publishing is based on the task that we define. It can copy the files to a local directory or upload them to a remote Maven or lvy repository. We can use these files from another project in the same multi-project build. The process of publishing a task is called publication.

Dependency management in Gradle
Gradle has built-in support for dependency management and lives up to the task of fulfilling typical scenarios encountered in modern software projects. We’ll explore the main concepts with the help of an example project. The illustration below should give you an rough overview on all the moving parts.
Image description

The example project builds Java source code. Some of the Java source files import classes from Google Guava, a open-source library providing a wealth of utility functionality. In addition to Guava, the project needs the JUnit libraries for compiling and executing test code.

Guava and JUnit represent the dependencies of this project. A build script developer can declare dependencies for different scopes e.g. just for compilation of source code or for executing tests. In Gradle, the scope of a dependency is called a configuration. For a full overview, see the reference material on dependency types.

Often times dependencies come in the form of modules. You’ll need to tell Gradle where to find those modules so they can be consumed by the build. The location for storing modules is called a repository. By declaring repositories for a build, Gradle will know how to find and retrieve modules. Repositories can come in different forms: as local directory or a remote repository. The reference on repository types provides a broad coverage on this topic.

At runtime, Gradle will locate the declared dependencies if needed for operating a specific task. The dependencies might need to be downloaded from a remote repository, retrieved from a local directory or requires another project to be built in a multi-project setting. This process is called dependency resolution. You can find a detailed discussion in How Gradle downloads dependencies.

Once resolved, the resolution mechanism stores the underlying files of a dependency in a local cache, also referred to as the dependency cache. Future builds reuse the files stored in the cache to avoid unnecessary network calls.

Modules can provide additional metadata. Metadata is the data that describes the module in more detail e.g. the coordinates for finding it in a repository, information about the project, or its authors. As part of the metadata, a module can define that other modules are needed for it to work properly. For example, the JUnit 5 platform module also requires the platform commons module. Gradle automatically resolves those additional modules, so called transitive dependencies. If needed, you can customize the behavior the handling of transitive dependencies to your project’s requirements.

Projects with tens or hundreds of declared dependencies can easily suffer from dependency hell. Gradle provides sufficient tooling to visualize, navigate and analyze the dependency graph of a project either with the help of a build scan or built-in tasks. Learn more in Viewing and debugging dependencies.

Dependency configurations

Dependency configuration is a set of dependencies and artifacts. Following are three main tasks of configuration:

  1. Declaring dependencies
  2. Resolving dependencies
  3. Exposing artifacts for consumptions Declaring Dependency Dependency is an essential part of any project. We must declare a dependency to use it. Dependency configuration is a process of defining a set of dependencies. This feature is used to declare external dependencies, which we want to download from the web.

Consider the below example of the Hibernate-core dependency:

apply plugin: 'java.'   
repositories {  
   mavenCentral()  
}  
dependencies {  
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'  
   testCompile group: 'junit', name: 'junit', version: '4.+'  
}  
Enter fullscreen mode Exit fullscreen mode

A dependency can be used on different phases of the project. These phases can be:

Compile: At compile time, we will use the dependencies that are required to compile the production source of the project.

Runtime: These dependencies are used at runtime by production classes. By default, it also contains the compile-time dependencies.

Test Compile: These dependencies are required to compile the test source of the project. It also contains the compiled production classes and the compile-time dependencies.

Test Runtime: These dependencies are required to run the tests. It also contains runtime and test compile dependencies.

Resolving Dependencies
The plugin uses the configuration and gets input for the tasks defined. For example, the Gradle project uses the Spring Web Framework jar file, which must be downloaded from Maven Central.

Exposing Artifacts for Consumption
The plugin uses configurations that are used to define artifacts for other projects consumption.

Top comments (0)