// Copyright (C) 2023 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[dependency_management_for_java_projects]]
= Managing Dependencies of JVM Projects

This chapter explains how to apply basic dependency management concepts to JVM-based projects.
For a detailed introduction to dependency management, see <<core_dependency_management.adoc#dependency_management_in_gradle,dependency management in Gradle>>.

[[sec:setting_up_a_standard_build_script_java_tutorial]]
== Dissecting a typical build script

Let's have a look at a very simple build script for a JVM-based project.
It applies the <<java_library_plugin.adoc#java_library_plugin,Java Library plugin>> which automatically introduces a standard project layout, provides tasks for performing typical work and adequate support for dependency management.

.Dependency declarations for a JVM-based project
====
include::sample[dir="snippets/artifacts/dependencyBasics/kotlin",files="build.gradle.kts[]"]
include::sample[dir="snippets/artifacts/dependencyBasics/groovy",files="build.gradle[]"]
====

The link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:dependencies(groovy.lang.Closure)[Project.dependencies{}] code block declares that Hibernate core 3.6.7.Final is required to compile the project's production source code. It also states that junit &gt;= 4.0 is required to compile the project's tests. All dependencies are supposed to be looked up in the Maven Central repository as defined by link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:repositories(groovy.lang.Closure)[Project.repositories{}]. The following sections explain each aspect in more detail.

[[sec:module_dependencies_java_tutorial]]
== Declaring module dependencies

There are various <<declaring_dependencies.adoc#sec:dependency-types,types of dependencies>> that you can declare.
One such type is a _module dependency_.
A <<declaring_dependencies.adoc#sub:module_dependencies,module dependency>> represents a dependency on a module with a specific version built outside the current build.
Modules are usually stored in a repository, such as Maven Central, a corporate Maven or Ivy repository, or a directory in the local file system.

To define an module dependency, you add it to a <<#sec:configurations_java_tutorial,dependency configuration>>:

.Definition of a module dependency
====
include::sample[dir="snippets/artifacts/externalDependencies/kotlin",files="build.gradle.kts[tags=define-dependency]"]
include::sample[dir="snippets/artifacts/externalDependencies/groovy",files="build.gradle[tags=define-dependency]"]
====

To find out more about defining dependencies, have a look at <<declaring_dependencies.adoc#declaring-basic-dependencies,Declaring Dependencies>>.

[[sec:configurations_java_tutorial]]
== Using dependency configurations

A link:{groovyDslPath}/org.gradle.api.artifacts.Configuration.html[Configuration] is a named set of dependencies and artifacts. There are three main purposes for a _configuration_:

Declaring dependencies::
A plugin uses configurations to make it easy for build authors to declare what other subprojects or external artifacts are needed for various purposes during the execution of tasks defined by the plugin. For example a plugin may need the Spring web framework dependency to compile the source code.
Resolving dependencies::
A plugin uses configurations to find (and possibly download) inputs to the tasks it defines. For example Gradle needs to download Spring web framework JAR files from Maven Central.
Exposing artifacts for consumption::
A plugin uses configurations to define what _artifacts_ it generates for other projects to consume. For example the project would like to publish its compiled source code packaged in the JAR file to an in-house Artifactory repository.

With those three purposes in mind, let's take a look at a few of the <<java_library_plugin.adoc#sec:java_library_configurations_graph,standard configurations defined by the Java Library Plugin>>.

implementation::
The dependencies required to compile the production source of the project which _are not_ part of the API exposed by the project. For example the project uses Hibernate for its internal persistence layer implementation.
api::
The dependencies required to compile the production source of the project which _are_ part of the API exposed by the project. For example the project uses Guava and exposes public interfaces with Guava classes in their method signatures.
testImplementation::
The dependencies required to compile and run the test source of the project. For example the project decided to write test code with the test framework JUnit.

Various plugins add further standard configurations.
You can also define your own custom configurations in your build via link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:configurations(groovy.lang.Closure)[Project.configurations{}].
See <<dependency_configurations.adoc#sec:what-are-dependency-configurations,What are dependency configurations>> for the details of defining and customizing dependency configurations.

[[sec:repositories_java_tutorial]]
== Declaring common Java repositories

How does Gradle know where to find the files for external dependencies? Gradle looks for them in a _repository_.
A repository is a collection of modules, organized by `group`, `name` and `version`.
Gradle understands different <<declaring_repositories.adoc#sec:repository-types,repository types>>, such as Maven and Ivy, and supports various ways of accessing the repository via HTTP or other protocols.

By default, Gradle does not define any repositories. You need to define at least one with the help of link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:repositories(groovy.lang.Closure)[Project.repositories{}] before you can use module dependencies. One option is use the Maven Central repository:

.Usage of Maven central repository
====
include::sample[dir="snippets/artifacts/defineRepository/kotlin",files="build.gradle.kts[tags=maven-central]"]
include::sample[dir="snippets/artifacts/defineRepository/groovy",files="build.gradle[tags=maven-central]"]
====

You can also have repositories on the local file system. This works for both Maven and Ivy repositories.

.Usage of a local Ivy directory
====
include::sample[dir="snippets/artifacts/defineRepository/kotlin",files="build.gradle.kts[tags=local-ivy-repo]"]
include::sample[dir="snippets/artifacts/defineRepository/groovy",files="build.gradle[tags=local-ivy-repo]"]
====

A project can have multiple repositories. Gradle will look for a dependency in each repository in the order they are specified, stopping at the first repository that contains the requested module.

To find out more about defining repositories, have a look at <<declaring_repositories.adoc#declaring-basic-repositories,Declaring Repositories>>.

[[sec:publishing_artifacts_java_tutorial]]
== Publishing artifacts

To learn more about publishing artifacts, have a look at <<publishing_setup.adoc#publishing_components,publishing plugins>>.
