Gradle Dependencies and Dependency Configurations TODEPLETE

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

A dependency is an artifact, usually located in a repository, the project needs. From a very generic perspective, a dependency can be thought of as a pointer to another piece of software.

Gradle groups dependencies in, and handles them as sets, referred to as dependency configurations. A dependency configuration is a named set of dependencies and artifacts, grouped together for a specific goal. For example, some dependencies should be used during the compilation phase, whereas others need to be available during the testing phase, or at runtime. These are dependency scopes, and Gradle represents the scope of a dependency with the help of a Configuration. Each configuration can be identified by a unique name. Many Gradle plugins add pre-defined configurations to the project. For example, the Java plugin adds configurations to represent the various classpaths needed for compilation, testing, etc. A dependency configuration has three main purposes:

  • To declare dependencies: plugins use dependency configurations to allow build authors to declare what other subproject of external artifacts are needed during the execution of tasks defined by the plugin.
  • To resolve dependencies: plugins use dependency configurations to find and download inputs to the tasks it defines.
  • To expose artifacts for consumption: plugins use dependency configurations to define what artifacts it generates. Configurations are using during the artifact publishing process.

Configurations can be displayed with:

task configs {

    configurations.each { println it.name }
}

The same configurations (with more details attached) are displayed by

gradle dependencies 

Custom configurations may be defined: https://docs.gradle.org/current/userguide/managing_dependency_configurations.html#_defining_custom_configurations.

Configuration Hierarchy

A configuration can extend other configurations to form an inheritance hierarchy. Child configurations inherit the whole set of dependencies declared for any of its superconfigurations. Dependencies may be inherited from other configurations: https://docs.gradle.org/current/userguide/managing_dependency_configurations.html#sub:inheriting_dependencies_from_other_configurations.



In Gradle, dependencies are declared in build.gradle.

At runtime, Gradle will attempt to locate declared dependencies needed for the task being executed. This process may involve access and download from a remote repository, retrieval from a local directory, or building another project, in case of a multi-project build. This process is called dependency resolution https://docs.gradle.org/current/userguide/introduction_dependency_management.html#sec:dependency_resolution. A specific dependency may find itself in the dependency graph because it was declared in the build script or it is dependency of a declared dependency (transitive dependency).

Whenever Gradle tries to resolve a dependency in a repository, it looks for a metadata file and the default artifact file, a JAR. The build fails if none of these artifact files can be resolved. Under certain conditions, tweaking the way Gradle resolves artifacts for a dependency might be desired. TODO https://docs.gradle.org/current/userguide/declaring_dependencies.html#sub:resolve_specific_artifacts_from_dependency

Once a dependency is resolved, Gradle stores into a local cache, referred to as the dependency cache.

Dependencies are declared with:

dependencies { 
 ... 
}

in:

build.gradle

Configuration, in this context, does not refer to a configuration file, as in a settings configuration or a build configuration. It refers to named set of dependencies or artifacts, and it can probably thought of as being a concept similar to a Maven scope.

TO Deplete

Dependency Management

Dependency management is a technique for declaring, resolving and using dependencies required by the project in an automated fashion.

Dependency Types

Module Dependency

Module dependency is the most common form of dependency. It refers to a module in a repository.

TODO https://docs.gradle.org/current/userguide/dependency_types.html#sub:module_dependencies

Local File Dependency

TODO:

Project Dependency

TODO:

Gradle Distribution-Specific Dependency

TODO https://docs.gradle.org/current/userguide/dependency_types.html#sub:api_dependencies

Dependency Constraint

A dependency constraint defines requirements that need to be met by a module to make it a valid result for a dependency resolution process. A recommended practice for large projects is to declare dependencies without versions and use dependency constraints for version declaration. The advantage is that dependency constrains allow you to manage versions of all dependencies, including transitive ones, in one place.

Dynamic Version

An aggressive approach for consuming dependencies is to declare that a module depends on the latest version of a dependency, or the latest version of a version range. This approach is called dynamic versioning. By default, Gradle caches dynamic versions of dependencies for 24 hours. Within this time frame, Gradle does not try to resolve newer versions from the declared repositories. This threshold can be configured. The build.gradle syntax for dynamic versioning is:

dependencies {
    implementation 'org.slf4j:slf4j-api:1.2.+'
}

Changing Versions or Snapshots

In Maven, changing versions are referred to as napshots.

TODO when needed https://docs.gradle.org/current/userguide/declaring_dependencies.html#sub:declaring_dependency_with_changing_version

Resolution Rule

A resolution rule influences the behavior of how a dependency is resolved. Resolution rules are defined as part of the build logic. TODO https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html.

Transitive Dependency

A transitive dependency is a dependency of a dependency of a module. The immediate dependencies are declared in a module's metadata, and the build system is supposed to automatically resolve the dependency graph. TODO: https://docs.gradle.org/current/userguide/managing_transitive_dependencies.html. Gradle offers facilities to inspect the transitive dependency graph.

The Dependency Cache

https://docs.gradle.org/current/userguide/dependency_cache.html

Once a dependency is resolved as result of the dependency resolution, Gradle stores the associated artifacts in a local cache, known as the dependency cache.

The Gradle dependency cache consists of two storage types located under Gradle user home caches subdirectory: file-based storage for downloaded artifacts and raw metadata files, and a binary store of resolved module meta-data.

Example:

$HOME/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.12/8e20852d05222dc286bf1c71d78d0531e177c317/slf4j-api-1.7.12.jar