<!--
  ~ Copyright 2009 the original author or authors.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.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.
  -->
<chapter id='dependency_management'>
    <title>Dependency Management</title>
    <section id='sec:Introduction'>
        <title>Introduction</title>
        <para>Dependency management is a critical feature of every build, and Gradle has placed an emphasis on offering first-class dependency management that is both easy to understand and
            compatible with a wide variety of approaches. If you are familiar with the approach used by either Maven or Ivy you will be delighted to learn that Gradle is fully compatible with both
            approaches in addition to being flexible enough to support fully-customized approaches.
        </para>

        <para>Here are the major highlights of Gradle's support for dependency management:</para>
        <itemizedlist>
            <listitem>
                <para><emphasis>Transitive dependency management</emphasis>: Gradle gives you full control of your project's dependency tree.
                </para>
            </listitem>
            <listitem>
                <para><emphasis>Support for non-managed dependencies</emphasis>: If your dependencies are simply files in version control or a shared drive, Gradle provides powerful functionality
                    to support this.
                </para>
            </listitem>
            <listitem>
                <para><emphasis>Support for custom dependency definitions.</emphasis>: Gradle's Module Dependencies give you the ability to describe the dependency hierarchy in the build script.
                </para>
            </listitem>
            <listitem>
                <para><emphasis>A fully customizable approach to Dependency Resolution</emphasis>: Gradle provides you with the ability to customize resolution rules making dependency substitution
                    easy.
                </para>
            </listitem>
            <listitem>
                <para><emphasis>Full Compatibility with Maven and Ivy</emphasis>: If you have defined dependencies in a Maven POM or an Ivy file, Gradle provides seamless integration with a range of
                    popular build tools.
                </para>
            </listitem>
            <listitem>
                <para><emphasis>Integration with existing dependency management infrastructure</emphasis>: Gradle is compatible with both Maven and Ivy repositories. If you use Archiva, Nexus, or
                    Artifactory, Gradle is 100% compatible with all repository formats.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            With hundreds of thousands of interdependent open source components each with a range of versions and incompatibilities, dependency management has a habit of causing problems as builds
            grow in complexity. When a build's dependency tree becomes unwieldy, your build tool shouldn't force you to adopt a single, inflexible approach to dependency management. A proper build
            system has to be designed to be flexible, and Gradle can handle any situation.
        </para>

        <section id='sub:dependency_management_and_migrations'>
            <title>Flexible dependency management for migrations</title>
            <para>
                Dependency management can be particularly challenging during a migration from one build system to another. If you are migrating from a tool like Ant or Maven to Gradle, you may be
                faced with some difficult situations. For example, one common pattern is an Ant project with version-less jar files stored in the filesystem. Other build systems require a wholesale
                replacement of this approach before migrating. With Gradle, you can adapt your new build to any existing source of dependencies or dependency metadata. This makes incremental migration
                to Gradle much easier than the alternative. On most large projects, build migrations and any change to development process is incremental because most organizations can't afford to
                stop everything and migrate to a build tool's idea of dependency management.
            </para>

            <para>Even if your project is using a custom dependency management system or something like an Eclipse .classpath file as master data for dependency management, it is very easy to write a
                Gradle plugin to use this data in Gradle. For migration purposes this is a common technique with Gradle. (But, once you've migrated, it might be a good idea to move away from a
                .classpath file and use Gradle's dependency management features directly.)
            </para>
        </section>

        <section id='sub:dependency_management_and_java'>
            <title>Dependency management and Java</title>
            <para>It is ironic that in a language known for its rich library of open source components that Java has no concept of libraries or versions. In Java, there is no standard way to tell the
                JVM that you are using version 3.0.5 of Hibernate, and there is no standard way to say that
                <literal>foo-1.0.jar</literal>
                depends on <literal>bar-2.0.jar</literal>. This has led to external solutions often based on build tools. The most popular ones at the moment are Maven and Ivy. While Maven provides a
                complete build system, Ivy focuses solely on dependency management.
            </para>
            <para>Both tools rely on descriptor XML files, which contain information about the dependencies of a particular jar. Both also use repositories where the actual jars are placed together
                with their descriptor files, and both offer resolution for conflicting jar versions in one form or the other. Both have emerged as standards for solving dependency conflicts, and while
                Gradle originally used Ivy under the hood for its dependency management. Gradle has replaced this direct dependency on Ivy with a native Gradle dependency resolution engine which
                supports a range of approaches to dependency resolution including both POM and Ivy descriptor files.
            </para>
        </section>
    </section>

    <section id='sec:dependency_management_overview'>
        <title>Dependency Management Best Practices</title>
        <para>While Gradle has strong opinions on dependency management, the tool gives you a choice between two
            options: follow recommended best practices or support any kind of pattern you can think of. This section
            outlines the Gradle project's recommended best practices for managing dependencies.
        </para>
        <para>No matter what the language, proper dependency management is important for every project.
            From a complex enterprise application written in Java depending on hundreds of open source
            libraries to the simplest Clojure application depending on a handful of libraries, approaches to dependency
            management vary widely and can depend on the target technology, the method of application deployment, and the
            nature of the project. Projects bundled as reusable libraries may have different requirements than
            enterprise applications integrated into much larger systems of software and infrastructure. Despite this wide variation of requirements,
            the Gradle project recommends that all projects follow this set of core rules:
        </para>
        <section id='sub:versioning_the_jar_name'>
            <title>Put the Version in the Filename (Version the jar)</title>
            <para>The version of a library must be part of the filename. While the version of a jar is usually in the Manifest file, it isn't readily apparent when you are inspecting a
                project. If someone asks you to look at a collection of 20 jar files, which would you prefer? A collection of files with names like <filename>commons-beanutils-1.3.jar</filename>
                or a collection of files with names like <filename>spring.jar</filename>? If dependencies have file names with version numbers you can quickly identify the versions of
                your dependencies.
            </para>
            <para>If versions are unclear you can introduce subtle bugs which are very hard to find. For example there might be a project which uses Hibernate 2.5. Think about a developer who decides
                to install version 3.0.5 of Hibernate on her machine to fix a critical security bug but forgets to notify others in the team of this change. She may address the security bug
                successfully, but she also may have introduced subtle bugs into a codebase that was using a now-deprecated feature from Hibernate. Weeks later there is an exception on the integration
                machine which can't be reproduced on anyone's machine. Multiple developers then spend days on this issue only finally realising that the error would have easy to uncover if they knew
                that Hibernate had been upgraded from 2.5 to 3.0.5.
            </para>
            <para>Versions in jar names increase the expressiveness of your project and make them easier to maintain. This practice also reduces the potential for error.
            </para>
        </section>
        <section id='sub:transitive_dependency_management'>
            <title>Manage transitive dependencies</title>
            <para>Transitive dependency management is a technique that enables your project to depend on libraries which, in turn, depend on other libraries. This recursive pattern of transitive
                dependencies results in a tree of dependencies including your project's first-level dependencies, second-level dependencies, and so on. If you don't model your dependencies as a
                hierarchical tree of first-level and second-level dependencies it is very easy to quickly lose control over an assembled mess of unstructured dependencies. Consider the Gradle project
                itself, while Gradle only has a few direct, first-level dependencies, when Gradle is compiled it needs more than one hundred dependencies on the classpath. On a far larger scale,
                Enterprise projects using Spring, Hibernate, and other libraries, alongside hundreds or thousands of internal projects, can result in very large dependency trees.
            </para>
            <para>When these large dependency trees need to change, you'll often have to solve some dependency version conflicts. Say one open source library needs one version of a logging library and
                a another uses an alternative version. Gradle and other build tools all have the ability to resolve conflicts, but what differentiates Gradle is the
                control it gives you over transitive dependencies and conflict resolution.
            </para>
            <para>While you could try to manage this problem manually, you will quickly find that this approach doesn't scale. If you want to get rid of a first level dependency you really can't be
                sure which other jars you should remove. A dependency of a first level dependency might also be a first level dependency itself, or it might be a transitive dependency of yet another
                first level dependency. If you try to manage transitive dependencies yourself, the end of the story is that your build becomes brittle: no one dares to change your dependencies because
                the risk of breaking the build is too high. The project classpath becomes a complete mess, and, if a classpath problem arises, hell on earth invites you for a ride.
            </para>
            <note><emphasis>NOTE:</emphasis>In one project, we found a mystery LDAP related jar in the classpath. No code referenced this jar and there was no connection to the project. No one could
                figure out what the jar was for, until it was removed from the build and the application suffered massive performance problems whenever it attempted to authenticate to LDAP. This
                mystery jar was a necessary transitive, fourth-level dependency that was easy to miss because no one had bothered to use managed transitive dependencies.
            </note>
            <para>Gradle offers you different ways to express first-level and transitive dependencies. With Gradle you can mix and match approaches; for example, you could store your jars in an SCM
                without XML descriptor files and still use transitive dependency management.
            </para>
        </section>
        <section id='sub:version_conflicts'>
            <title>Resolve version conflicts</title>
            <para>Conflicting versions of the same jar should be detected and either resolved or cause an exception. If you don't use transitive dependency management, version conflicts are undetected
                and the often accidental order of the classpath will determine what version of a dependency will win. On a large project with many developers changing dependencies, successful builds
                will be few and far between as the order of dependencies may directly affect whether a build succeeds or fails (or whether a bug appears or disappears in production).
            </para>
            <para>If you haven't had to deal with the curse of conflicting versions of jars on a classpath, here is a small anecdote of the fun that awaits you. In a large project with 30
                submodules, adding a dependency to a subproject changed the order of a classpath, swapping Spring 2.5 for an older 2.4 version. While
                the build continued to work, developers were starting to notice all sorts of surprising (and surprisingly awful) bugs in production. Worse yet, this unintentional downgrade of Spring
                introduced several security vulnerabilities into the system, which now required a full security audit throughout the organization.
            </para>
            <para>In short, version conflicts are bad, and you should manage your transitive dependencies to avoid them. You might also want to learn where conflicting versions are used and consolidate on a
                particular version of a dependency across your organization. With a good conflict reporting tool like Gradle, that information can be used to communicate with the entire organization
                and standardize on a single version.
                <emphasis>If you think version conflicts don't happen to you, think again.</emphasis>
                It is very common for different first-level dependencies to rely on a range of different overlapping versions for other dependencies, and the JVM doesn't yet offer an easy way to have
                different versions of the same jar in the classpath (see <xref linkend='sub:dependency_management_and_java'/>).
            </para>
            <para>Gradle offers the following conflict resolution strategies:</para>
            <itemizedlist>
                <listitem>
                    <emphasis>Newest</emphasis>: The newest version of the dependency is used. This is Gradle's default strategy, and is often an appropriate choice as long as versions are backwards-compatible.
                </listitem>
                <listitem>
                    <emphasis>Fail</emphasis>: A version conflict results in a build failure. This strategy requires all version conflicts to be resolved explicitly in the build script. See
                    <apilink class='org.gradle.api.artifacts.ResolutionStrategy'/> for details on how to explicitly choose a particular version.
                </listitem>
            </itemizedlist>
            <para>While the strategies introduced above are usually enough to solve most conflicts, Gradle provides more fine-grained mechanisms to resolve version conflicts:</para>
            <itemizedlist>
                <listitem>
                    Configuring a first level dependency as <emphasis>forced</emphasis>. This approach is useful if the dependency in conflict is already a first level dependency.
                    See examples in <apilink class='org.gradle.api.artifacts.dsl.DependencyHandler'/>.
                </listitem>
                <listitem>
                    Configuring any dependency (transitive or not) as <emphasis>forced</emphasis>. This approach is useful if the dependency in conflict is a transitive dependency.
                    It also can be used to force versions of first level dependencies.
                    See examples in <apilink class='org.gradle.api.artifacts.ResolutionStrategy'/>
                </listitem>
                <listitem>
                    Dependency resolve rules are an <link linkend="feature_lifecycle">incubating</link> feature introduced in Gradle 1.4 which give you fine-grained control over the version selected for a particular dependency.
                </listitem>
            </itemizedlist>
            <para>To deal with problems due to version conflicts, reports with dependency graphs are also very helpful. Such reports are another feature of dependency management.</para>
        </section>
        <section id='sub:dynamic_versions_and_changing_modules'>
            <title>Use Dynamic Versions and Changing Modules</title>
            <para>There are many situations when you want to use the latest version of a particular dependency, or the latest in a range of versions. This can be a requirement during development, or
                you may be developing a library that is designed to work with a range of dependency versions. You can easily depend on these constantly changing dependencies by using a
                <emphasis>dynamic version</emphasis>. A dynamic version can be either a version range (e.g. <literal>2.+</literal>) or it can be a placeholder for the latest version available
                (e.g. <literal>latest.integration</literal>).
            </para>
            <para>Alternatively, sometimes the module you request can change over time, even for the same version. An example of this type of <emphasis>changing module</emphasis>
                is a Maven <literal>SNAPSHOT</literal> module, which always points at the latest artifact published. In other words, a standard Maven snapshot is a module that never stands still
                so to speak, it is a “changing module”.
            </para>
            <para>The main difference between a <emphasis>dynamic version</emphasis> and a <emphasis>changing module</emphasis> is that when you resolve a <emphasis>dynamic version</emphasis>, you'll
                get the real, static version as the module name. When you resolve a <emphasis>changing module</emphasis>, the artifacts are named using the version you requested, but the underlying
                artifacts may change over time.
            </para>
            <para>By default, Gradle caches dynamic versions and changing modules for 24 hours. You can override the default cache modes using <link linkend="sec:cache_command_line_options">command
                line options</link>. You can change the cache expiry times in your build using the resolution strategy (see <xref linkend='sec:controlling_caching'/>).
            </para>
        </section>
    </section>
    <section id='sub:configurations'>
        <title>Dependency configurations</title>
        <para>In Gradle dependencies are grouped into configurations. Configurations have a name, a number of other properties,
            and they can extend each other.
            Many Gradle plugins add pre-defined configurations to your project. The Java plugin, for example,
            adds some configurations to represent the various classpaths it needs. see
            <xref linkend='sec:java_plugin_and_dependency_management'/>
            for details. Of course you can add custom configurations on top of that. There are many use cases
            for custom configurations. This is very handy for example for adding dependencies not needed for
            building or testing your software (e.g. additional JDBC drivers to be shipped with your distribution).
        </para>
        <para>
            A project's configurations are managed by a <literal>configurations</literal> object. The closure you pass to
            the configurations object is applied against its API. To learn more about this API have a look at
            <apilink class='org.gradle.api.artifacts.ConfigurationContainer'/>.
        </para>
        <para>To define a configuration:</para>
        <sample id="defineConfiguration" dir="userguide/artifacts/defineConfiguration" title="Definition of a configuration">
            <sourcefile file="build.gradle" snippet="define-configuration"/>
        </sample>
        <para>To access a configuration:</para>
        <sample id="defineConfiguration" dir="userguide/artifacts/defineConfiguration" title="Accessing a configuration">
            <sourcefile file="build.gradle" snippet="lookup-configuration"/>
        </sample>
        <para>To configure a configuration:</para>
        <sample id="defineConfiguration" dir="userguide/artifacts/defineConfiguration" title="Configuration of a configuration">
            <sourcefile file="build.gradle" snippet="configure-configuration"/>
        </sample>
    </section>

    <section id='sec:how_to_declare_your_dependencies'>
        <title>How to declare your dependencies</title>
        <para>There are several different types of dependencies that you can declare:
        </para>
        <table>
            <title>Dependency types</title>
            <thead>
                <tr>
                    <td>Type</td>
                    <td>Description</td>
                </tr>
            </thead>
            <tr>
                <td>
                    <link linkend="sub:module_dependencies">External module dependency</link>
                </td>
                <td>A dependency on an external module in some repository.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:project_dependencies">Project dependency</link>
                </td>
                <td>A dependency on another project in the same build.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:file_dependencies">File dependency</link>
                </td>
                <td>A dependency on a set of files on the local filesystem.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:client_module_dependencies">Client module dependency</link>
                </td>
                <td>A dependency on an external module, where the artifacts are located in some repository but the module meta-data
                    is specified by the local build. You use this kind of dependency when you want to override the meta-data for the module.
                </td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:api_dependencies">Gradle API dependency</link>
                </td>
                <td>A dependency on the API of the current Gradle version.
                    You use this kind of dependency when you are developing custom Gradle plugins and task types.
                </td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:groovy_dependencies">Local Groovy dependency</link>
                </td>
                <td>A dependency on the Groovy version used by the current Gradle version.
                    You use this kind of dependency when you are developing custom Gradle plugins and task types.
                </td>
            </tr>
        </table>

        <section id='sub:module_dependencies'>
            <title>External module dependencies</title>
            <para>External module dependencies are the most common dependencies. They refer to a module in an external repository.
            </para>
            <sample id="moduleDependencies" dir="userguide/artifacts/externalDependencies" title="Module dependencies">
                <sourcefile file="build.gradle" snippet="module-dependencies"/>
            </sample>
            <para>See the <apilink class='org.gradle.api.artifacts.dsl.DependencyHandler'/> class in the API documentation
                for more examples and a complete reference.
            </para>
            <para>Gradle provides different notations for module dependencies. There is a string notation and
                a map notation. A module dependency has an API which allows further configuration. Have a look at
                <apilink class='org.gradle.api.artifacts.ExternalModuleDependency'/>
                to learn all about the API.
                This API provides properties and configuration methods. Via the string notation you can define a subset
                of the properties. With the map notation you can define all properties. To have access to the complete API,
                either with the map or with the string notation, you can assign a single dependency to a configuration
                together with a closure.
            </para>
            <para>If you declare a module dependency, Gradle looks for a module descriptor file (<filename>pom.xml</filename> or
                <filename>ivy.xml</filename>) in the repositories. If such a module descriptor file exists, it is parsed and the artifacts of
                this module (e.g. <filename>hibernate-3.0.5.jar</filename>) as well as its dependencies (e.g. cglib) are downloaded. If no such
                module descriptor file exists, Gradle looks for a file called <filename>hibernate-3.0.5.jar</filename>
                to retrieve. In Maven, a module can have one and only one artifact. In Gradle and Ivy, a module can have multiple artifacts.
                Each artifact can have a different set of dependencies.
            </para>
            <section id='ssub:multi_artifact_dependencies'>
                <title>Depending on modules with multiple artifacts</title>
                As mentioned earlier, a Maven module has only one artifact. Hence, when your project depends on a Maven module, it's obvious what its artifact is.
                With Gradle or Ivy, the case is different. Ivy's dependency descriptor (<filename>ivy.xml</filename>) can declare multiple artifacts.
                For more information, see the Ivy reference for <filename>ivy.xml</filename>.
                In Gradle, when you declare a dependency on an Ivy module, you actually declare a dependency on the <literal>default</literal> configuration of that module.
                So the actual set of artifacts (typically jars) you depend on is the set of artifacts that are associated with the
                <literal>default</literal> configuration of that module. Here are some situations where this matters:
                <itemizedlist>
                    <listitem>The <literal>default</literal> configuration of a module contains undesired artifacts. Rather than depending on the
                        whole configuration, a dependency on just the desired artifacts is declared.
                    </listitem>
                    <listitem>The desired artifact belongs to a configuration other than <literal>default</literal>. That configuration is explicitly named
                        as part of the dependency declaration.
                    </listitem>
                </itemizedlist>
                There are other situations where it is necessary to fine-tune dependency declarations.
                Please see the <apilink class='org.gradle.api.artifacts.dsl.DependencyHandler'/> class in the API documentation for examples and a complete reference for declaring dependencies.
            </section>
            <section id='ssub:artifact_dependencies'>
                <title>Artifact only notation</title>
                <para>As said above, if no module descriptor file can be found, Gradle by default
                    downloads a jar with the name of the module. But sometimes, even if the repository contains module descriptors, you want to download only the artifact jar, without
                    the dependencies.
                    <footnote>
                        <para>Gradle supports partial multiproject builds (see <xref linkend='multi_project_builds'/>).</para>
                    </footnote>
                    And sometimes you want to download a zip from a repository, that does not have module descriptors. Gradle provides an <emphasis>artifact only</emphasis>
                    notation for those use cases - simply prefix the extension that you want to be downloaded with <literal>'@'</literal> sign:
                    <sample id="artifactOnly" dir="userguide/artifacts/externalDependencies" title="Artifact only notation">
                        <sourcefile file="build.gradle" snippet="artifact-only"/>
                    </sample>
                    An artifact only notation creates a module dependency which downloads only the artifact file with the specified extension. Existing module descriptors are ignored.
                </para>
            </section>
            <section id='sub:classifiers'>
                <title>Classifiers</title>
                <para>The Maven dependency management has the notion of classifiers.
                    <footnote>
                        <para>
                            <ulink url='http://books.sonatype.com/mvnref-book/reference/pom-relationships-sect-project-relationships.html'/>
                        </para>
                    </footnote>
                    Gradle supports this. To retrieve classified dependencies from a Maven repository you can write:
                </para>
                <sample id="classifier" dir="userguide/artifacts/excludesAndClassifiers" title="Dependency with classifier">
                    <sourcefile file="build.gradle" snippet="classifier"/>
                </sample>
                <para>As can be seen in the first line above, classifiers can be used together with the artifact only notation.
                </para>
            </section>
            <para>It is easy to iterate over the dependency artifacts of a configuration:</para>
            <sample id="externalDependencies" dir="userguide/artifacts/externalDependencies" title="Iterating over a configuration">
                <sourcefile file="build.gradle" snippet="use-configuration"/>
                <output args="-q listJars"/>
            </sample>
        </section>

        <section id='sub:client_module_dependencies'>
            <title>Client module dependencies</title>
            <para>Client module dependencies allow you to declare <emphasis>transitive</emphasis> dependencies directly in the build script. They are a replacement for a module descriptor
                in an external repository.
            </para>
            <sample id="client-modules" dir="userguide/artifacts/externalDependencies" title="Client module dependencies - transitive dependencies">
                <sourcefile file="build.gradle" snippet="client-modules"/>
            </sample>
            <para>This declares a dependency on Groovy. Groovy itself has dependencies. But Gradle does
                not look for an XML descriptor to figure them out but gets the information from the build file. The
                dependencies of a client module can be normal module dependencies or artifact dependencies or another
                client module. Also look at the API documentation for the <apilink class='org.gradle.api.artifacts.ClientModule'/> class.
            </para>
            <para>In the current release client modules have one limitation. Let's say your project is a library and
                you want this library to be uploaded to your company's Maven or Ivy repository. Gradle uploads the
                jars of your project to the company repository together with the XML descriptor file of the dependencies.
                If you use client modules the dependency declaration in the XML descriptor file is not correct. We will
                improve this in a future release of Gradle.
            </para>
        </section>

        <section id='sub:project_dependencies'>
            <title>Project dependencies</title>
            <para>Gradle distinguishes between external dependencies and dependencies on projects which are part of the
                same multi-project build. For the latter you can declare <firstterm>Project Dependencies</firstterm>.
            </para>
            <sample id="project-dependencies" dir="java/multiproject/api" title="Project dependencies">
                <sourcefile file="build.gradle" snippet="project-dependencies"/>
            </sample>
            <para>For more information see the API documentation for
                <apilink class="org.gradle.api.artifacts.ProjectDependency"/>.
            </para>
            <para>Multi-project builds are discussed in <xref linkend='multi_project_builds'/>.
            </para>
        </section>

        <section id="sub:file_dependencies">
            <title>File dependencies</title>
            <para>File dependencies allow you to directly add a set of files to a configuration, without first adding
                them to a repository. This can be useful if you cannot, or do not want to, place certain files in a
                repository. Or if you do not want to use any repositories at all for storing your dependencies.
            </para>
            <para>To add some files as a dependency for a configuration, you simply pass a
                <link linkend="sec:file_collections">file collection</link>
                as a dependency:
            </para>
            <sample id="file-dependencies" dir="userguide/artifacts/externalDependencies" title="File dependencies">
                <sourcefile file="build.gradle" snippet="file-dependencies"/>
            </sample>
            <para>File dependencies are not included in the published dependency descriptor for your project.
                However, file dependencies are included in transitive project dependencies within the same build.
                This means they cannot be used outside the current build, but they can be used with the same build.
            </para>
            <para>
                You can declare which tasks produce the files for a file dependency. You might do this when, for example,
                the files are generated by the build.
            </para>
            <sample id="generatedFileDependencies" dir="userguide/artifacts/generatedFileDependencies" title="Generated file dependencies">
                <sourcefile file="build.gradle" snippet="generated-file-dependencies"/>
                <output args="-q list"/>
            </sample>
        </section>

        <section id="sub:api_dependencies">
            <title>Gradle API Dependency</title>
            <para>You can declare a dependency on the API of the current version of Gradle by using the <apilink class="org.gradle.api.artifacts.dsl.DependencyHandler" method="gradleApi"/>
                method. This is useful when you are developing custom Gradle tasks or plugins.
            </para>
            <sample id="gradle-api-dependencies" dir="customPlugin/plugin" title="Gradle API dependencies">
                <sourcefile file="build.gradle" snippet="gradle-api-dependencies"/>
            </sample>
        </section>

        <section id="sub:groovy_dependencies">
            <title>Local Groovy Dependency</title>
            <para>You can declare a dependency on the Groovy that is distributed with Gradle by using the <apilink class="org.gradle.api.artifacts.dsl.DependencyHandler" method="localGroovy"/>
                method. This is useful when you are developing custom Gradle tasks or plugins in Groovy.
            </para>
            <sample id="local-groovy-dependencies" dir="customPlugin/plugin" title="Gradle's Groovy dependencies">
                <sourcefile file="build.gradle" snippet="local-groovy-dependencies"/>
            </sample>
        </section>

        <section id='sub:exclude_transitive_dependencies'>
            <title>Excluding transitive dependencies</title>
            <para>You can exclude a <emphasis>transitive</emphasis> dependency either by configuration or by dependency:
            </para>
            <sample id="exclude-dependencies" dir="userguide/artifacts/excludesAndClassifiers" title="Excluding transitive dependencies">
                <sourcefile file="build.gradle" snippet="exclude-dependencies"/>
            </sample>
            <para>If you define an exclude for a particular configuration, the excluded transitive dependency will be filtered for all
                dependencies when resolving this configuration or any inheriting configuration.
                If you want to exclude a transitive dependency from all your
                configurations you can use the Groovy spread-dot operator to express this in a concise way, as shown in the example.
                When defining an exclude, you can specify either only the organization or only the module name or both.
                Also look at the API documentation of the <apilink class="org.gradle.api.artifacts.Dependency"/> and <apilink class="org.gradle.api.artifacts.Configuration"/> classes.
            </para>
            <para>
                Not every transitive dependency can be excluded - some transitive dependencies might be essential
                for correct runtime behavior of the application. Generally, one can exclude transitive
                dependencies that are either not required by runtime or that are guaranteed to be available
                on the target environment/platform.
            </para>
            <para>
                Should you exclude per-dependency or per-configuration?
                It turns out that in the majority of cases you want to use the per-configuration exclusion.
                Here are some typical reasons why one might want to exclude a transitive dependency.
                Bear in mind that for some of these use cases there are better solutions than exclusions!
                <itemizedlist>
                    <listitem>The dependency is undesired due to licensing reasons.</listitem>
                    <listitem>The dependency is not available in any remote repositories.</listitem>
                    <listitem>The dependency is not needed for runtime.</listitem>
                    <listitem>The dependency has a version that conflicts with a desired version. For that use case please refer to <xref linkend='sub:version_conflicts'/>
                        and the documentation on <apilink class='org.gradle.api.artifacts.ResolutionStrategy'/> for a potentially better solution to the problem.
                    </listitem>
                </itemizedlist>
                Basically, in most of the cases excluding the transitive dependency should be done per configuration.
                This way the dependency declaration is more explicit. It is also more accurate because a per-dependency
                exclude rule does not guarantee the given transitive dependency does not show up in the configuration.
                For example, some other dependency, which does not have any exclude rules, might pull in
                that unwanted transitive dependency.
            </para>
            <para>
                Other examples of dependency exclusions can be found in the reference for the <apilink class='org.gradle.api.artifacts.ModuleDependency'/> or
                <apilink class='org.gradle.api.artifacts.dsl.DependencyHandler'/> classes.
            </para>
        </section>
        <section>
            <title>Optional attributes</title>
            <para id="para:dependencies_with_empty_attributes">All attributes for a dependency are optional, except the name.
                Which attributes are required for actually finding dependencies in the repository will depend on the repository type.
                See <xref linkend='sec:repositories'/>. For example, if you work with Maven repositories, you need to define the
                group, name and version. If you work with filesystem repositories you might only need the name or the name
                and the version.
            </para>
            <sample id="dependenciesWithEmptyAttributes" dir="userguide/artifacts/externalDependencies" title="Optional attributes of dependencies">
                <sourcefile file="build.gradle" snippet="dependencies-with-empty-attributes"/>
            </sample>
            <para id="para:notation_collections">You can also assign collections or arrays of dependency notations to a configuration:
            </para>
            <sample id="listGrouping" dir="userguide/artifacts/externalDependencies" title="Collections and arrays of dependencies">
                <sourcefile file="build.gradle" snippet="list-grouping"/>
            </sample>
        </section>
        <section id="sec:dependency_configurations">
            <title>Dependency configurations</title>
            <para>In Gradle a dependency can have different configurations (as your project can have different configurations). If you
                don't specify anything explicitly, Gradle uses the default configuration of the dependency. For dependencies
                from a Maven repository, the default configuration is the only possibility anyway. If you work with Ivy repositories and
                want to declare a non-default configuration for your dependency you have to use the map notation and declare:
            </para>
            <sample id="dependencyConfigurations" dir="userguide/artifacts/externalDependencies" title="Dependency configurations">
                <sourcefile file="build.gradle" snippet="dependency-configurations"/>
            </sample>
            <para>To do the same for project dependencies you need to declare:</para>
            <sample id="dependencyConfigurationsProjects" dir="/java/multiproject/services/webservice" title="Dependency configurations for project">
                <sourcefile file="build.gradle" snippet="dependency-configurations"/>
            </sample>
        </section>
        <section>
            <title>Dependency reports</title>
            <para>You can generate dependency reports from the command line (see <xref linkend="para:commandline_dependency_report"/>).
                With the help of the Project report plugin (see <xref linkend="project_reports_plugin"/>) such a report can be created by your build.
            </para>
            <para>
                Since Gradle 1.2 there is also a new programmatic API to access the resolved dependency information.
                The dependency reports (see the previous paragraph) are using this API under the covers.
                The API lets you walk the resolved dependency graph and provides information about the dependencies.
                In future releases the API will grow to provide more information about the resolution result.
                For more information about the API please refer to the Javadocs on
                <apilink class="org.gradle.api.artifacts.ResolvableDependencies" method="getResolutionResult"/>.
                Potential usages of the <apilink class="org.gradle.api.artifacts.result.ResolutionResult"/> API:
                <itemizedlist>
                    <listitem>Creation of advanced dependency reports tailored to your use case.</listitem>
                    <listitem>Enabling the build logic to make decisions based on the content of the dependency graph.</listitem>
                </itemizedlist>
            </para>
        </section>
    </section>
    <section id='sec:working_with_dependencies'>
        <title>Working with dependencies</title>
        <para>For the examples below we have the following dependencies setup:</para>
        <sample id="configurationHandlingSetup" dir="userguide/artifacts/configurationHandling" title="Configuration.copy">
            <sourcefile file="build.gradle" snippet="setup"/>
        </sample>
        <para>The dependencies have the following transitive dependencies:</para>
        <para>shark-1.0 -> seal-2.0, tuna-1.0</para>
        <para>orca-1.0 -> seal-1.0</para>
        <para>tuna-1.0 -> herring-1.0</para>
        <para>You can use the configuration to access the declared dependencies or a subset of those:
        </para>
        <sample id="configurationHandlingDependencies" dir="userguide/artifacts/configurationHandling" title="Accessing declared dependencies">
            <sourcefile file="build.gradle" snippet="dependencies"/>
            <output args="-q dependencies"/>
        </sample>
        <para>The <code>dependencies</code> task returns only the dependencies belonging explicitly to the configuration.
            The <code>allDependencies</code> task includes the dependencies from extended configurations.
        </para>
        <para>To get the library files of the configuration dependencies you can do:
        </para>
        <sample id="configurationHandlingAllFiles" dir="userguide/artifacts/configurationHandling" title="Configuration.files">
            <sourcefile file="build.gradle" snippet="allFiles"/>
            <output args="-q allFiles"/>
        </sample>
        <para>Sometimes you want the library files of a subset of the configuration dependencies (e.g. of a single dependency).
        </para>
        <sample id="configurationHandlingFiles" dir="userguide/artifacts/configurationHandling" title="Configuration.files with spec">
            <sourcefile file="build.gradle" snippet="files"/>
            <output args="-q files"/>
        </sample>
        <para>The <code>Configuration.files</code> method always retrieves all artifacts of the <emphasis>whole</emphasis>
            configuration. It then filters the retrieved files by specified dependencies. As you can see in the example, transitive dependencies are included.
        </para>
        <para>You can also copy a configuration. You can optionally specify that only a subset of dependencies from the original configuration
            should be copied. The copying methods come in two flavors. The <code>copy</code> method copies only the dependencies belonging explicitly to the configuration. The
            <code>copyRecursive</code> method copies all the dependencies, including the dependencies from extended configurations.
        </para>
        <sample id="configurationHandlingCopy" dir="userguide/artifacts/configurationHandling" title="Configuration.copy">
            <sourcefile file="build.gradle" snippet="copy"/>
            <output args="-q copy"/>
        </sample>
        <para>It is important to note that the returned files of the copied configuration
            are often but not always the same than the returned files of the dependency subset of the original configuration.
            In case of version conflicts between dependencies of the subset and dependencies not belonging to the subset the resolve result might be different.
        </para>
        <sample id="configurationHandlingCopyVsFiles" dir="userguide/artifacts/configurationHandling" title="Configuration.copy vs. Configuration.files">
            <sourcefile file="build.gradle" snippet="copyVsFiles"/>
            <output args="-q copyVsFiles"/>
        </sample>
        <para>In the example above, <code>orca</code> has a dependency on <code>seal-1.0</code> whereas <code>shark</code> has a dependency on<code>seal-2.0</code>. The original configuration
            has therefore a version conflict which is resolved to the newer <code>seal-2.0</code> version. The <code>files</code> method therefore returns <code>seal-2.0</code> as a
            transitive dependency of<code>orca</code>. The copied configuration only has <code>orca</code> as a dependency and therefore there is no version conflict and <code>seal-1.0</code>
            is returned as a transitive dependency.
        </para>
        <para>Once a configuration is resolved it is immutable. Changing its state or the state of one of its dependencies
            will cause an exception. You can always copy a resolved configuration. The copied configuration is in the unresolved
            state and can be freshly resolved.
        </para>
        <para>To learn more about the API of the configuration class see the API documentation:
            <apilink class='org.gradle.api.artifacts.Configuration'/>.
        </para>
    </section>
    <section id='sec:repositories'>
        <title>Repositories</title>
        <para>Gradle repository management, based on Apache Ivy, gives you a lot of freedom regarding repository layout and retrieval policies.
            Additionally Gradle provides various convenience method to add pre-configured repositories.
        </para>
        <para>You may configure any number of repositories, each of which is treated independently by Gradle. If Gradle finds a module descriptor in a
            particular repository, it will attempt to download all of the artifacts for that module from <emphasis>the same repository</emphasis>.
            Although module meta-data and module artifacts must be located in the same repository, it is possible to compose a single repository of multiple
            URLs, giving multiple locations to search for meta-data files and jar files.
        </para>

        <para>There are several different types of repositories you can declare:</para>
        <table>
            <title>Repository types</title>
            <thead>
                <tr>
                    <td>Type</td>
                    <td>Description</td>
                </tr>
            </thead>
            <tr>
                <td>
                    <link linkend="sub:maven_central">Maven central repository</link>
                </td>
                <td>A pre-configured repository that looks for dependencies in Maven Central.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:maven_jcenter">Maven JCenter repository</link>
                </td>
                <td>A pre-configured repository that looks for dependencies in Bintray's JCenter.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:maven_local">Maven local repository</link>
                </td>
                <td>A pre-configured repository that looks for dependencies in the local Maven repository.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sub:maven_repo">Maven repository</link>
                </td>
                <td>A Maven repository. Can be located on the local filesystem or at some remote location.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sec:ivy_repositories">Ivy repository</link>
                </td>
                <td>An Ivy repository. Can be located on the local filesystem or at some remote location.</td>
            </tr>
            <tr>
                <td>
                    <link linkend="sec:flat_dir_resolver">Flat directory repository</link>
                </td>
                <td>A simple repository on the local filesystem. Does not support any meta-data formats.</td>
            </tr>
        </table>

        <section id='sub:maven_central'>
            <title>Maven central repository</title>
            <para>To add the central Maven 2 repository (<ulink url='http://repo1.maven.org/maven2'/>) simply add this to your build script:
            </para>
            <sample id="mavenCentral" dir="userguide/artifacts/defineRepository" title="Adding central Maven repository">
                <sourcefile file="build.gradle" snippet="maven-central"/>
            </sample>
            <para>Now Gradle will look for your dependencies in this repository.</para>
            <para>
                <emphasis>Warning:</emphasis> Be aware that the central Maven 2 repository is HTTP only and
                HTTPS is not supported. If you need a public HTTPS enabled central repository, you can use the <ulink url='http://jcenter.bintray.com'>JCenter</ulink> public repository (see <xref linkend="sub:maven_jcenter"/>).
            </para>
        </section>

        <section id='sub:maven_jcenter'>
            <title>Maven JCenter repository</title>
            <para><ulink url='http://bintray.com'>Bintray</ulink>'s JCenter is an up-to-date collection of all popular Maven OSS artifacts, including artifacts published directly to Bintray.
            </para>
            <para>To add the JCenter Maven repository (<ulink url='https://jcenter.bintray.com'/>) simply add this to your build script:
            </para>
            <sample id="mavenJcenter" dir="userguide/artifacts/defineRepository" title="Adding Bintray's JCenter Maven repository">
                <sourcefile file="build.gradle" snippet="maven-jcenter"/>
            </sample>
            <para>Now Gradle will look for your dependencies in the JCenter repository. <emphasis>jcenter()</emphasis> uses HTTPS to connect to the repository.
                If you want to use HTTP you can configure <literal>jcenter()</literal>:
            </para>
            <sample id="mavenJcenter" dir="userguide/artifacts/defineRepository" title="Using Bintrays's JCenter with HTTP">
                <sourcefile file="build.gradle" snippet="maven-jcenter-http"/>
            </sample>
        </section>

        <section id='sub:maven_local'>
            <title>Local Maven repository</title>
            <para>To use the local Maven cache as a repository you can do:</para>
            <sample id="mavenLocalRepo" dir="userguide/artifacts/defineRepository" title="Adding the local Maven cache as a repository">
                <sourcefile file="build.gradle" snippet="maven-local"/>
            </sample>
            <para>Gradle uses the same logic as Maven to identify the location of your local Maven cache. If a local repository location is defined in a <filename>settings.xml</filename>, this location
                will be used. The <filename>settings.xml</filename> in <filename><replaceable>USER_HOME</replaceable>/.m2</filename> takes precedence over the <filename>settings.xml</filename>
                in <filename><replaceable>M2_HOME</replaceable>/conf</filename>. If no <filename>settings.xml</filename> is available, Gradle uses the default location
                <filename><replaceable>USER_HOME</replaceable>/.m2/repository</filename>.
            </para>
        </section>

        <section id='sub:maven_repo'>
            <title>Maven repositories</title>
            <para>For adding a custom Maven repository you can do:
            </para>
            <sample id="mavenLikeRepo" dir="userguide/artifacts/defineRepository" title="Adding custom Maven repository">
                <sourcefile file="build.gradle" snippet="maven-like-repo"/>
            </sample>

            <para>Sometimes a repository will have the POMs published to one location, and the JARs and other artifacts published at another location.
                To define such a repository, you can do:
            </para>
            <sample id="mavenLikeRepoWithJarRepo" dir="userguide/artifacts/defineRepository" title="Adding additional Maven repositories for JAR files">
                <sourcefile file="build.gradle" snippet="maven-like-repo-with-jar-repo"/>
            </sample>
            <para>Gradle will look at the first URL for the POM and the JAR. If the JAR can't be found there, the artifact URLs are used to look for JARs.
            </para>
            <section>
                <title>Accessing password protected Maven repositories</title>
                <para>To access a Maven repository which uses basic authentication, you specify the username and password to use when you define the repository:
                </para>
                <sample id="mavenPasswordProtectedRepo" dir="userguide/artifacts/defineRepository" title="Accessing password protected Maven repository">
                    <sourcefile file="build.gradle" snippet="authenticated-maven-repo"/>
                </sample>
                <para>It is advisable to keep your username and password in <filename>gradle.properties</filename> rather than directly in the build file.
                </para>
            </section>
        </section>

        <section id='sec:flat_dir_resolver'>
            <title>Flat directory repository</title>
            <para>If you want to use a (flat) filesystem directory as a repository, simply type:
            </para>
            <sample id="flatDirMulti" dir="userguide/artifacts/defineRepository" title="Flat repository resolver">
                <sourcefile file="build.gradle" snippet="flat-dir-multi"/>
            </sample>
            <para>This adds repositories which look into one or more directories for finding dependencies. Note that
                this type of repository does not support any meta-data formats like Ivy XML or Maven POM files. Instead,
                Gradle will dynamically generate a module descriptor (without any dependency information) based on the
                presence of artifacts. However, as Gradle prefers to use modules whose descriptor has been created from
                real meta-data rather than being generated, flat directory repositories cannot be used to override
                artifacts with real meta-data from other repositories. So, for example, if Gradle finds only
                <filename>jmxri-1.2.1.jar</filename> in a flat directory repository, but <filename>jmxri-1.2.1.pom</filename>
                in another repository that supports meta-data, it will use the second repository to provide the module.
                For the use case of overriding remote artifacts with local ones consider using an Ivy or Maven repository
                instead whose URL points to a local directory.
                If you only work with flat directory repositories you don't need to set all attributes of a dependency.
                See <xref linkend='para:dependencies_with_empty_attributes'/>.
            </para>
        </section>

        <section id="sec:ivy_repositories">
            <title>Ivy repositories</title>
            <section>
                <title>Defining an Ivy repository with a standard layout</title>
                <sample id="ivyRepository" dir="userguide/artifacts/defineRepository" title="Ivy repository">
                    <sourcefile file="build.gradle" snippet="ivy-repo"/>
                </sample>
            </section>
            <section>
                <title>Defining a named layout for an Ivy repository</title>
                <para>
                    You can specify that your repository conforms to the Ivy or Maven default layout by using a named layout.
                </para>
                <sample id="ivyRepository" dir="userguide/artifacts/defineRepository" title="Ivy repository with named layout">
                    <sourcefile file="build.gradle" snippet="ivy-repo-with-maven-layout"/>
                </sample>
                <para>
                    Valid named layout values are <literal>'gradle'</literal> (the default), <literal>'maven'</literal> and <literal>'ivy'</literal>.
                    See <apilink class="org.gradle.api.artifacts.repositories.IvyArtifactRepository" method="layout(java.lang.String, groovy.lang.Closure)"/> in the API documentation for details of these named layouts.
                </para>
            </section>
            <section>
                <title>Defining custom pattern layout for an Ivy repository</title>
                <para>To define an Ivy repository with a non-standard layout, you can define a 'pattern' layout for the repository:
                </para>
                <sample id="ivyRepository" dir="userguide/artifacts/defineRepository" title="Ivy repository with pattern layout">
                    <sourcefile file="build.gradle" snippet="ivy-repo-with-pattern-layout"/>
                </sample>
                <para>To define an Ivy repository which fetches Ivy files and artifacts from different locations,
                    you can define separate patterns to use to locate the Ivy files and artifacts:
                </para>
                <para>
                    Each <literal>artifact</literal> or <literal>ivy</literal> specified for a repository adds an <emphasis>additional</emphasis> pattern to use.
                    The patterns are used in the order that they are defined.
                </para>
                <sample id="ivyRepository" dir="userguide/artifacts/defineRepository" title="Ivy repository with multiple custom patterns">
                    <sourcefile file="build.gradle" snippet="ivy-repo-with-custom-pattern"/>
                </sample>
                <para>Optionally, a repository with pattern layout can have its 'organisation' part laid out in Maven style, with
                    forward slashes replacing dots as separators. For example, the organisation <literal>my.company</literal> would then be represented as <literal>my/company</literal>.
                </para>
                <sample id="ivyRepository" dir="userguide/artifacts/defineRepository" title="Ivy repository with Maven compatible layout">
                    <sourcefile file="build.gradle" snippet="ivy-repo-with-m2compatible-layout"/>
                </sample>
            </section>
            <section>
                <title>Accessing password protected Ivy repositories</title>
                <para>To access an Ivy repository which uses basic authentication, you specify the username and password to use when you define the repository:
                </para>
                <sample id="ivyRepository" dir="userguide/artifacts/defineRepository" title="Ivy repository">
                    <sourcefile file="build.gradle" snippet="authenticated-ivy-repo"/>
                </sample>
            </section>
        </section>

        <section id='sub:supported_transport_protocols'>
            <title>Supported repository transport protocols</title>
            <para>Maven and Ivy repositories support the use of various transport protocols. At the moment the following protocols are supported:
            </para>
            <table>
                <title>Repository transport protocols</title>
                <thead>
                    <tr>
                        <td>Type</td>
                        <td>Authentication schemes</td>
                    </tr>
                </thead>
                <tr>
                    <td><literal>file</literal></td>
                    <td>none</td>
                </tr>
                <tr>
                    <td><literal>http</literal></td>
                    <td>username/password</td>
                </tr>
                <tr>
                    <td><literal>https</literal></td>
                    <td>username/password</td>
                </tr>
                <tr>
                    <td><literal>sftp</literal></td>
                    <td>username/password</td>
                </tr>
                <tr>
                    <td><literal>s3</literal></td>
                    <td>access key/secret key</td>
                </tr>
            </table>
            <para>To define a repository use the <literal>repositories</literal> configuration block. Within the <literal>repositories</literal> closure,
                a Maven repository is declared with <literal>maven</literal>. An Ivy repository is declared with <literal>ivy</literal>. The transport protocol
                is part of the URL definition for a repository. The following build script demonstrates how to create a HTTP-based Maven and Ivy repository:
            </para>
            <sample id="mavenIvyRepositoriesNoAuth" dir="userguide/artifacts/defineRepository" title="Declaring a Maven and Ivy repository">
                <sourcefile file="build.gradle" snippet="maven-ivy-repository-no-auth"/>
            </sample>
            <para>If authentication is required for a repository, the relevant credentials can be provided. The following example shows how to provide
                username/password-based authentication for SFTP repositories:
            </para>
            <sample id="mavenIvyRepositoriesAuth" dir="userguide/artifacts/defineRepository" title="Providing credentials to a Maven and Ivy repository">
                <sourcefile file="build.gradle" snippet="maven-ivy-repository-auth"/>
            </sample>
            <para>When using an AWS S3 backed repository you need to authenticate using <apilink class="org.gradle.api.credentials.AwsCredentials" />, providing access-key and a private-key.
                The following example shows how to declare a S3 backed repository and providing AWS credentials:
            </para>
            <sample id="mavenIvyS3RepositoriesAuth" dir="userguide/artifacts/defineRepository" title="Declaring a S3 backed Maven and Ivy repository">
                <sourcefile file="build.gradle" snippet="maven-ivy-s3-repository"/>
            </sample>

            <section id='sub:s3_configuration properties'>
                <title>S3 configuration properties</title>
                <para>
                    The following system properties can be used to configure the interactions with s3 repositories:
                </para>
                <table>
                    <title>S3 Configuration Properties</title>
                    <thead>
                        <tr>
                            <td>Property</td>
                            <td>Description</td>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>org.gradle.s3.endpoint</td>
                            <td>Used to override the AWS S3 endpoint when using a non AWS, S3 API compatible, storage service.</td>
                        </tr>
                        <tr>
                            <td>org.gradle.s3.maxErrorRetry</td>
                            <td>Specifies the maximum number of times to retry a request in the event that the S3 server responds with a HTTP 5xx status code. When not specified a default value of 3
                                is used.
                            </td>
                        </tr>
                    </tbody>
                </table>
            </section>

            <section id='sub:s3_url_formats'>
                <title>S3 URL formats</title>
                <para>S3 URL's are 'virtual-hosted-style' and must be in the following format
                    <literal>s3://&lt;bucketName>[.&lt;regionSpecificEndpoint>]/&lt;s3Key></literal>
                </para>
                <para>e.g.
                    <literal>s3://myBucket.s3.eu-central-1.amazonaws.com/maven/release</literal>
                </para>
                <itemizedlist>
                    <listitem>
                        <literal>myBucket</literal>
                        is the AWS S3 bucket name.
                    </listitem>
                    <listitem>
                        <literal>s3.eu-central-1.amazonaws.com</literal>
                        is the <emphasis>optional</emphasis> <ulink url='http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region'> region specific endpoint</ulink>.
                    </listitem>
                    <listitem>
                        <literal>/maven/release</literal>
                        is the AWS S3 key (unique identifier for an object within a bucket)
                    </listitem>
                </itemizedlist>
            </section>

            <section id='sub:s3_proxy_settings'>
                <title>S3 proxy settings</title>
                <para>A proxy for S3 can be configured using the following system properties:</para>
                <itemizedlist>
                    <listitem><literal>https.proxyHost</literal></listitem>
                    <listitem><literal>https.proxyPort</literal></listitem>
                    <listitem><literal>https.proxyUser</literal></listitem>
                    <listitem><literal>https.proxyPassword</literal></listitem>
                    <listitem><literal>https.nonProxyHosts</literal></listitem>
                </itemizedlist>


                <para>If the 'org.gradle.s3.endpoint' property has been specified with a http (not https) URI the following system proxy settings can be used:</para>
                <itemizedlist>
                    <listitem><literal>http.proxyHost</literal></listitem>
                    <listitem><literal>http.proxyPort</literal></listitem>
                    <listitem><literal>http.proxyUser</literal></listitem>
                    <listitem><literal>http.proxyPassword</literal></listitem>
                    <listitem><literal>http.nonProxyHosts</literal></listitem>
                </itemizedlist>
            </section>

            <section id="s3_v4_signatures">
                <title>AWS S3 V4 Signatures (AWS4-HMAC-SHA256)</title>
                <para>
                    Some of the AWS S3 regions (eu-central-1 - Frankfurt) require that all HTTP requests are signed in accordance with AWS's
                    <ulink url="http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html">signature version 4</ulink>. It is recommended to specify
                    S3 URL's containing the region specific endpoint when using buckets that require V4 signatures.
                    e.g. <literal>s3://somebucket.s3.eu-central-1.amazonaws.com/maven/release</literal>
                </para>
                <note><emphasis>NOTE:</emphasis> When a region-specific endpoint is not specified for buckets requiring V4 Signatures, Gradle will use the default AWS region (us-east-1) and the
                    following warning will appear on the console:
                    <para>
                        Attempting to re-send the request to .... with AWS V4 authentication. To avoid this warning in the future, please use region-specific endpoint to access buckets located in
                        regions that require V4 signing.
                    </para>
                    <para>
                        Failing to specify the region-specific endpoint for buckets requiring V4 signatures means:
                    </para>
                    <itemizedlist>
                        <listitem><literal>3 round-trips to AWS, as opposed to one, for every file upload and download.</literal></listitem>
                        <listitem><literal>Depending on location - increased network latencies and slower builds.</literal></listitem>
                        <listitem><literal>Increased likelihood of transmission failures.</literal></listitem>
                    </itemizedlist>
                </note>
            </section>
        </section>

        <section>
            <title>Working with repositories</title>
            <para>To access a repository:</para>
            <sample id="defineRepository" dir="userguide/artifacts/defineRepository" title="Accessing a repository">
                <sourcefile file="build.gradle" snippet="lookup-resolver"/>
            </sample>
            <para>To configure a repository:</para>
            <sample id="defineRepository" dir="userguide/artifacts/defineRepository" title="Configuration of a repository">
                <sourcefile file="build.gradle" snippet="configure-resolver"/>
            </sample>
        </section>
        <section id='sub:more_about_ivy_resolvers'>
            <title>More about Ivy resolvers</title>
            <para>Gradle is extremely flexible regarding repositories:
            </para>
            <itemizedlist>
                <listitem>
                    <para>There are many options for the protocol to communicate with the repository (e.g. filesystem, http, ssh, sftp ...)
                    </para>
                </listitem>
                <listitem>
                    <para>The protocol sftp currently only supports username/password-based authentication.
                    </para>
                </listitem>
                <listitem>
                    <para>Each repository can have its own layout.
                    </para>
                </listitem>
            </itemizedlist>
            <para>Let's say, you declare a dependency on the <literal>junit:junit:3.8.2</literal> library.
                Now how does Gradle find it in the repositories? Somehow the dependency information has to be mapped to a
                path. In contrast to Maven, where this path is fixed, with Gradle you can define a pattern that defines
                what the path will look like. Here are some examples:
                <footnote>
                    <para>At <ulink url='http://ant.apache.org/ivy/history/latest-milestone/concept.html'/> you can learn more about ivy patterns.
                    </para>
                </footnote>
            </para>
            <programlisting><![CDATA[
// Maven2 layout (if a repository is marked as Maven2 compatible, the organization (group) is split into subfolders according to the dots.)
someroot/[organisation]/[module]/[revision]/[module]-[revision].[ext]

// Typical layout for an Ivy repository (the organization is not split into subfolder)
someroot/[organisation]/[module]/[revision]/[type]s/[artifact].[ext]

// Simple layout (the organization is not used, no nested folders.)
someroot/[artifact]-[revision].[ext]
]]></programlisting>
            <para>To add any kind of repository (you can pretty easy write your own ones) you can do:
            </para>
            <sample id="fileSystemResolver" dir="userguide/artifacts/excludesAndClassifiers" title="Definition of a custom repository">
                <sourcefile file="build.gradle" snippet="file-system-resolver"/>
            </sample>
            <para>An overview of which Resolvers are offered by Ivy and thus also by Gradle can be found
                <ulink url='http://ant.apache.org/ivy/history/latest-milestone/settings/resolvers.html'>here</ulink>. With
                Gradle you just don't configure them via XML but directly via their API.
            </para>
        </section>
    </section>
    <section id='sec:dependency_resolution'>
        <title>How dependency resolution works</title>
        <para>Gradle takes your dependency declarations and repository definitions and attempts to download all of your dependencies by a process called <emphasis>dependency resolution</emphasis>.
            Below is a brief outline of how this process works.
        </para>
        <itemizedlist>
            <listitem>
                <para>
                    Given a required dependency, Gradle first attempts to resolve the <emphasis>module</emphasis> for that dependency. Each repository is inspected in order, searching
                    first for a <emphasis>module descriptor</emphasis> file (POM or Ivy file) that indicates the presence of that module. If no module descriptor is found,
                    Gradle will search for the presence of the primary <emphasis>module artifact</emphasis> file indicating that the module exists in the repository.
                </para>
                <itemizedlist>
                    <listitem>
                        <para>If the dependency is declared as a dynamic version (like <literal>1.+</literal>), Gradle will resolve this to the newest available static version (like
                            <literal>1.2</literal>) in the repository. For Maven repositories, this is done using the <literal>maven-metadata.xml</literal>
                            file, while for Ivy repositories this is done by directory listing.
                        </para>
                    </listitem>
                    <listitem>
                        <para>If the module descriptor is a POM file that has a parent POM declared, Gradle will recursively attempt to resolve each of the parent modules for the POM.
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>
            <listitem>
                <para>Once each repository has been inspected for the module, Gradle will choose the 'best' one to use. This is done using the following criteria:
                    <itemizedlist>
                        <listitem>For a dynamic version, a 'higher' static version is preferred over a 'lower' version.</listitem>
                        <listitem>Modules declared by a module descriptor file (Ivy or POM file) are preferred over modules that have an artifact file only.</listitem>
                        <listitem>Modules from earlier repositories are preferred over modules in later repositories.</listitem>
                    </itemizedlist>
                </para>
                <para>When the dependency is declared by a static version and a module descriptor file is found in a repository, there is no need to continue searching later
                    repositories and the remainder of the process is short-circuited.
                </para>
            </listitem>
            <listitem>
                <para>All of the artifacts for the module are then requested from the <emphasis>same repository</emphasis> that was chosen in the process above.
                </para>
            </listitem>
        </itemizedlist>
    </section>
    <section>
        <title>Fine-tuning the dependency resolution process</title>
        <para>In most cases, Gradle's default dependency management will resolve the dependencies that you want in your build. In some cases, however, it can be necessary to tweak
            dependency resolution to ensure that your build receives exactly the right dependencies.
        </para>
        <para>There are a number of ways that you can influence how Gradle resolves dependencies.</para>

        <section id='sec:forcing_modules'>
            <title>Forcing a particular module version</title>
            <para>Forcing a module version tells Gradle to always use a specific version for given dependency (transitive or not), overriding any version specified in a
                published module descriptor. This can be very useful when tackling version conflicts - for more information see <xref linkend='sub:version_conflicts'/>.
            </para>
            <para>
                Force versions can also be used to deal with rogue metadata of transitive dependencies.
                If a transitive dependency has poor quality metadata that leads to problems at dependency resolution time, you can force Gradle to use a newer, fixed version of this dependency.
                For an example, see the <apilink class='org.gradle.api.artifacts.ResolutionStrategy'/> class in the API documentation.
                Note that 'dependency resolve rules' (outlined below) provide a more powerful mechanism for replacing a broken module dependency. See <xref linkend='sec:blacklisting_version'/>.
            </para>
        </section>
        <section id='sec:dependency_resolve_rules'>
            <title>Using dependency resolve rules</title>
            <para>A dependency resolve rule is executed for each resolved dependency, and offers a powerful api for manipulating a requested dependency prior to that dependency being resolved.
                This feature is <link linkend="feature_lifecycle">incubating</link>, but currently offers the ability to change the group, name and/or version of a requested dependency,
                allowing a dependency to be substituted with a completely different module during resolution.
            </para>
            <para>
                Dependency resolve rules provide a very powerful way to control the dependency resolution process, and can be used to implement all sorts of advanced
                patterns in dependency management. Some of these patterns are outlined below.
                For more information and code samples see the <apilink class='org.gradle.api.artifacts.ResolutionStrategy'/> class in the API documentation.
            </para>
            <section id='sec:releasable_unit'>
                <title>Modelling releaseable units</title>
                <para>Often an organisation publishes a set of libraries with a single version; where the libraries are built, tested and published together.
                    These libraries form a 'releasable unit', designed and intended to be used as a whole. It does not make sense to use libraries from different releasable units together.
                </para>
                <para>
                    But it is easy for transitive dependency resolution to violate this contract. For example:
                    <itemizedlist>
                        <listitem><literal>module-a</literal> depends on <literal>releasable-unit:part-one:1.0</literal></listitem>
                        <listitem><literal>module-b</literal> depends on <literal>releasable-unit:part-two:1.1</literal></listitem>
                    </itemizedlist>
                    A build depending on both <literal>module-a</literal> and <literal>module-b</literal> will obtain different versions of libraries within the releasable unit.
                </para>
                <para>
                    Dependency resolve rules give you the power to enforce releasable units in your build.
                    Imagine a releasable unit defined by all libraries that have 'org.gradle' group. We can force all of these libraries to use a consistent version:
                    <sample id="releasable-unit" dir="userguide/artifacts/resolutionStrategy" title="Forcing consistent version for a group of libraries">
                        <sourcefile file="build.gradle" snippet="releasable-unit"/>
                    </sample>
                </para>
            </section>
            <section id='sec:custom_versioning_scheme'>
                <title>Implement a custom versioning scheme</title>
                <para>
                    In some corporate environments, the list of module versions that can be declared in Gradle builds is maintained and audited externally.
                    Dependency resolve rules provide a neat implementation of this pattern:
                    <itemizedlist>
                        <listitem>In the build script, the developer declares dependencies with the module group and name, but uses a placeholder version, for example: '<literal>default</literal>'.</listitem>
                        <listitem>The 'default' version is resolved to a specific version via a dependency resolve rule, which looks up the version in a corporate catalog of approved modules.</listitem>
                    </itemizedlist>

                    This rule implementation can be neatly encapsulated in a corporate plugin, and shared across all builds within the organisation.
                    <sample id="custom-versioning-scheme" dir="userguide/artifacts/resolutionStrategy" title="Using a custom versioning scheme">
                        <sourcefile file="build.gradle" snippet="custom-versioning-scheme"/>
                    </sample>
                </para>
            </section>
            <section id='sec:blacklisting_version'>
                <title>Blacklisting a particular version with a replacement</title>
                <para>
                    Dependency resolve rules provide a mechanism for blacklisting a particular version of a dependency and providing a replacement version.
                    This can be useful if a certain dependency version is broken and should not be used,
                    where a dependency resolve rule causes this version to be replaced with a known good version.
                    One example of a broken module is one that declares a dependency on a library that cannot be found in any of the public repositories,
                    but there are many other reasons why a particular module version is unwanted and a different version is preferred.
                </para>
                <para>
                    In example below, imagine that version <literal>1.2.1</literal> contains important fixes and should always be used in preference to <literal>1.2</literal>.
                    The rule provided will enforce just this: any time version <literal>1.2</literal> is encountered it will be replaced with <literal>1.2.1</literal>.
                    Note that this is different from a forced version as described above, in that any other versions of this module would not be affected.
                    This means that the 'newest' conflict resolution strategy would still select version <literal>1.3</literal> if this version was also pulled transitively.
                    <sample id="blacklisting_version" dir="userguide/artifacts/resolutionStrategy" title="Blacklisting a version with a replacement">
                        <sourcefile file="build.gradle" snippet="blacklisting_version"/>
                    </sample>
                </para>
            </section>
            <section id='sec:module_substitution'>
                <title>Substituting a dependency module with a compatible replacement</title>
                <para>At times a completely different module can serve as a replacement for a requested module dependency.
                    Examples include using '<literal>groovy</literal>' in place of '<literal>groovy-all</literal>', or using '<literal>log4j-over-slf4j</literal>' instead of '<literal>log4j</literal>'.
                    Starting with Gradle 1.5 you can make these substitutions using dependency resolve rules:
                    <sample id="module_substitution" dir="userguide/artifacts/resolutionStrategy" title="Changing dependency group and/or name at the resolution">
                        <sourcefile file="build.gradle" snippet="module_substitution"/>
                    </sample>
                </para>
            </section>
        </section>
        <section id="dependency_substitution_rules">
            <title>Dependency Substitution Rules</title>
            <para>
                Dependency substitution rules work similarly to dependency resolve rules.  In fact, many capabilities of dependency resolve rules
                can be implemented with dependency substitution rules.  They allow project and module dependencies to be transparently substituted with
                specified replacements.
                Unlike dependency resolve rules, dependency substitution rules allow project and module dependencies to be substituted interchangeably.
            </para>
            <note>
                <para>
                    <emphasis>NOTE: Adding a dependency substitution rule to a configuration changes the timing of when that configuration is resolved.</emphasis>
                    Instead of being resolved on first use, the configuration is instead resolved when the task graph is being constructed. This can have unexpected
                    consequences if the configuration is being further modified during task execution, or if the configuration relies on modules that are published during
                    execution of another task.
                </para>

                <para>
                    To explain:
                    <itemizedlist>
                        <listitem>A <literal>Configuration</literal> can be declared as an input to any Task, and that configuration can include project dependencies when it is resolved.</listitem>
                        <listitem>If a project dependency is an input to a Task (via a configuration), then tasks to built the project artifacts must be added to the task dependencies.</listitem>
                        <listitem>In order to determine the project dependencies that are inputs to a task, Gradle needs to resolve the <literal>Configuration</literal> inputs.</listitem>
                        <listitem>Because the Gradle task graph is fixed once task execution has commenced, Gradle needs to perform this resolution prior to executing any tasks.</listitem>
                    </itemizedlist>
                </para>
                <para>
                    In the absence of dependency substitution rules, Gradle knows that an external module dependency will never transitively reference a project dependency.
                    This makes it easy to determine the full set of project dependencies for a configuration through simple graph traversal.
                    With this functionality, Gradle can no longer make this assumption, and must perform a full resolve in order to determine the project dependencies.
                </para>
            </note>
            <section id='sec:module_to_project_substitution'>
                <title>Substituting an external module dependency with a project dependency</title>
                <para>
                    One use case for dependency substitution is to use a locally developed version of a module in place of one that is downloaded from
                    an external repository. This could be useful for testing a local, patched version of a dependency.
                </para>
                <para>
                    The module to be replaced can be declared with or without a version specified.
                </para>
                <sample id="module_to_project_substitution" dir="userguide/artifacts/dependency-substitution" title="Substituting a module with a project">
                    <sourcefile file="build.gradle" snippet="module_to_project_substitution"/>
                </sample>
                <para>
                    Note that a project that is substituted must be included in the multi-project build (via settings.gradle).  Dependency substitution
                    rules take care of replacing the module dependency with the project dependency and wiring up any task dependencies,
                    but do not implicitly include the project in the build.
                </para>
            </section>
            <section id='sec:project_to_module_substitution'>
                <title>Substituting a project dependency with a module replacement</title>
                <para>
                    Another way to use substitution rules is to replace a project dependency with a module in a multi-project build.
                    This can be useful to speed up development with a large multi-project build, by allowing a subset of the project
                    dependencies to be downloaded from a repository rather than being built.
                </para>
                <para>
                    The module to be used as a replacement must be declared with a version specified.
                </para>
                <sample id="project_to_module_substitution" dir="userguide/artifacts/dependency-substitution" title="Substituting a project with a module">
                    <sourcefile file="build.gradle" snippet="project_to_module_substitution"/>
                </sample>
                <para>
                    When a project dependency has been replaced with a module dependency, that project is still included in the overall multi-project build.
                    However, tasks to build the replaced dependency will not be executed in order to build the resolve the depending <literal>Configuration</literal>.
                </para>
            </section>
            <section id='sec:conditional_dependency_substitution'>
                <title>Conditionally substituting a dependency</title>
                <para>
                    A common use case for dependency substitution is to allow more flexible assembly of sub-projects within a multi-project build.
                    This can be useful for developing a local, patched version of an external dependency or for building a subset of the modules within
                    a large multi-project build.
                </para>
                <para>
                    The following example uses a dependency substitution rule to replace any module dependency with the group "org.example", but
                    only if a local project matching the dependency name can be located.
                </para>
                <sample id="project_substitution" dir="dependency-substitution" title="Conditionally substituting a dependency">
                    <sourcefile file="build.gradle" snippet="project_substitution"/>
                </sample>
                <para>
                    Note that a project that is substituted must be included in the multi-project build (via settings.gradle).  Dependency substitution
                    rules take care of replacing the module dependency with the project dependency, but do not implicitly include the project in the build.
                </para>
            </section>
        </section>
        <section id="sec:configuration_defaults">
            <title>Specifying default dependencies for a configuration</title>
            <para>
                A configuration can be configured with default dependencies to be used if no dependencies are explicitly set for the configuration.
                A primary use case of this functionality is for developing plugins that make use of versioned tools that the user might override.  By specifying
                default dependencies, the plugin can use a default version of the tool only if the user has not specified a particular version to use.
            </para>
            <sample id="configuration_default_dependencies" dir="userguide/artifacts/defineConfiguration" title="Specifying default dependencies on a configuration">
                <sourcefile file="build.gradle" snippet="configuration-default-dependencies"/>
            </sample>
        </section>
        <section id="ivy_dynamic_resolve_mode">
            <title>Enabling Ivy dynamic resolve mode</title>
            <para>
                Gradle's Ivy repository implementations support the equivalent to Ivy's dynamic resolve mode. Normally, Gradle will use the <literal>rev</literal> attribute for each dependency
                definition included in an <filename>ivy.xml</filename> file. In dynamic resolve mode, Gradle will instead prefer the <literal>revConstraint</literal> attribute over the
                <literal>rev</literal> attribute for a given dependency definition. If the <literal>revConstraint</literal> attribute is not present, the <literal>rev</literal> attribute is used
                instead.
            </para>
            <para>To enable dynamic resolve mode, you need to set the appropriate option on the repository definition. A couple of examples are shown below. Note that dynamic resolve mode is only
                available for Gradle's Ivy repositories. It is not available for Maven repositories, or custom Ivy <classname>DependencyResolver</classname> implementations.</para>
            <sample id="dynamicResolveMode" dir="userguide/artifacts/defineRepository" title="Enabling dynamic resolve mode">
                <sourcefile file="build.gradle" snippet="ivy-repo-dynamic-mode"/>
            </sample>
        </section>
        <section id="component_metadata_rules">
            <title>Component metadata rules</title>
            <para>Each module (also called <emphasis>component</emphasis>) has metadata associated with it, such as its group, name, version, dependencies, and so on.
                This metadata typically originates in the module's descriptor. Metadata rules allow certain parts of a module's metadata to be manipulated
                from within the build script. They take effect after a module's descriptor has been downloaded, but before it has been selected among all candidate versions.
                This makes metadata rules another instrument for customizing dependency resolution.
            </para>
            <para>
                One piece of module metadata that Gradle understands is a module's <emphasis>status scheme</emphasis>. This concept, also known from Ivy, models the different
                levels of maturity that a module transitions through over time. The default status scheme, ordered from least to most mature status, is <literal>integration</literal>,
                <literal>milestone</literal>, <literal>release</literal>. Apart from a status scheme, a module also has a (current) <emphasis>status</emphasis>, which must be one of
                the values in its status scheme. If not specified in the (Ivy) descriptor, the status defaults to <literal>integration</literal> for Ivy modules and Maven snapshot modules,
                and <literal>release</literal> for Maven modules that aren't snapshots.
            </para>
            <para>
                A module's status and status scheme are taken into consideration when a <literal>latest</literal> version selector is resolved. Specifically, <literal>latest.someStatus</literal>
                will resolve to the highest module version that has status <literal>someStatus</literal> or a more mature status. For example, with the default status scheme in place,
                <literal>latest.integration</literal> will select the highest module version regardless of its status (because <literal>integration</literal> is the least mature status),
                whereas <literal>latest.release</literal> will select the highest module version with status <literal>release</literal>. Here is what this looks like in code:
            </para>
            <sample id="latestSelector" dir="componentMetadataRules" title="'Latest' version selector">
                <sourcefile file="build.gradle" snippet="latest-selector"/>
                <output args="-q listConfigs"/>
            </sample>
            <para>
                The next example demonstrates <literal>latest</literal> selectors based on a custom status scheme declared in a component metadata rule that applies to all modules:
            </para>
            <sample id="customStatusScheme" dir="componentMetadataRules" title="Custom status scheme">
                <sourcefile file="build.gradle" snippet="custom-status-scheme"/>
            </sample>
            <para>
                Component metadata rules can be applied to a specified module.  Modules must be specified in the form of "group:module".
            </para>
            <sample id="customStatusSchemeModule" dir="componentMetadataRules" title="Custom status scheme by module">
                <sourcefile file="build.gradle" snippet="custom-status-scheme-module"/>
            </sample>
            <para>
                Gradle can also create component metadata rules utilizing Ivy-specific metadata for modules resolved from an Ivy repository.
                Values from the Ivy descriptor are made available via the <apilink class="org.gradle.api.artifacts.ivy.IvyModuleDescriptor"/> interface.
            </para>
            <sample id="ivyComponentMetadataRule" dir="componentMetadataRules" title="Ivy component metadata rule">
                <sourcefile file="build.gradle" snippet="ivy-component-metadata-rule" />
            </sample>
            <para>
                Note that any rule that declares specific arguments must <emphasis>always</emphasis> include a <apilink class="org.gradle.api.artifacts.ComponentMetadataDetails"/> argument
                as the first argument. The second Ivy metadata argument is optional.
            </para>
            <para>
                Component metadata rules can also be defined using a <emphasis>rule source</emphasis> object.  A rule source object
                is any object that contains exactly one method that defines the rule action and is annotated with <literal>@Mutate</literal>.
            </para>
            <para>
                This method:
            </para>
            <itemizedlist>
                <listitem>must return void.</listitem>
                <listitem>must have <apilink class="org.gradle.api.artifacts.ComponentMetadataDetails" /> as the first argument.</listitem>
                <listitem>may have an additional parameter of type <apilink class="org.gradle.api.artifacts.ivy.IvyModuleDescriptor" />.</listitem>
            </itemizedlist>
            <sample id="ruleSourceComponentMetadataRule" dir="componentMetadataRules" title="Rule source component metadata rule">
                <sourcefile file="build.gradle" snippet="rule-source-component-metadata-rule" />
            </sample>
        </section>
        <section id="component_selection_rules">
            <title>Component Selection Rules</title>
            <para>
                Component selection rules may influence which component instance should be selected when multiple versions are available that match a version selector.
                Rules are applied against every available version and allow the version to be explicitly rejected by rule.
                This allows Gradle to ignore any component instance that does not satisfy conditions set by the rule. Examples include:
            </para>
            <itemizedlist>
                <listitem>For a dynamic version like '1.+' certain versions may be explicitly rejected from selection</listitem>
                <listitem>For a static version like '1.4' an instance may be rejected based on extra component metadata such as the Ivy branch attribute, allowing an instance from a subsequent repository to be used.</listitem>
            </itemizedlist>
            <para>
                Rules are configured via the <apilink class="org.gradle.api.artifacts.ComponentSelectionRules"/> object.  Each rule configured
                will be called with a <apilink class="org.gradle.api.artifacts.ComponentSelection"/> object as an argument which contains information
                about the candidate version being considered.
                Calling <apilink class="org.gradle.api.artifacts.ComponentSelection" method="reject"/> causes the given candidate version to be explicitly rejected,
                in which case the candidate will not be considered for the selector.
            </para>
            <para>
                The following example shows a rule that disallows a particular version of a module but allows the dynamic version to
                choose the next best candidate.
            </para>
            <sample id="componentSelectionRulesReject" dir="componentSelectionRules" title="Component selection rule">
                <sourcefile file="build.gradle" snippet="reject-version-1.1" />
            </sample>
            <para>
                Note that version selection is applied starting with the highest version first.  The version selected will be the first version
                found that all component selection rules accept.  A version is considered accepted no rule explicitly rejects it.
            </para>
            <para>
                Similarly, rules can be targeted at specific modules.  Modules must be specified in the form of "group:module".
            </para>
            <sample id="componentSelectionRulesTarget" dir="componentSelectionRules" title="Component selection rule with module target">
                <sourcefile file="build.gradle" snippet="targeted-component-selection" />
            </sample>
            <para>
                Component selection rules can also consider component metadata when selecting a version.  Possible metadata arguments that can be considered are
                <apilink class="org.gradle.api.artifacts.ComponentMetadata"/> and <apilink class="org.gradle.api.artifacts.ivy.IvyModuleDescriptor"/>.
            </para>
            <sample id="componentSelectionRulesMetadata" dir="componentSelectionRules" title="Component selection rule with metadata">
                <sourcefile file="build.gradle" snippet="component-selection-with-metadata" />
            </sample>
            <para>
                Note that a <apilink class="org.gradle.api.artifacts.ComponentSelection"/> argument is <emphasis>always</emphasis> required as the first
                parameter when declaring a component selection rule with additional Ivy metadata parameters, but the metadata parameters can be declared
                in any order.
            </para>
            <para>
                Lastly, component selection rules can also be defined using a <emphasis>rule source</emphasis> object.  A rule source object
                is any object that contains exactly one method that defines the rule action and is annotated with <literal>@Mutate</literal>.
            </para>
            <para>
                This method:
            </para>
            <itemizedlist>
                <listitem>must return void.</listitem>
                <listitem>must have <apilink class="org.gradle.api.artifacts.ComponentSelection" /> as the first argument.</listitem>
                <listitem>may have additional parameters of type <apilink class="org.gradle.api.artifacts.ComponentMetadata" /> and/or <apilink class="org.gradle.api.artifacts.ivy.IvyModuleDescriptor" />.</listitem>
            </itemizedlist>
            <sample id="componentSelectionRulesRuleSource" dir="componentSelectionRules" title="Component selection rule using a rule source object">
                <sourcefile file="build.gradle" snippet="api-component-selection" />
            </sample>
        </section>
        <section id='sec:module_replacement'>
            <title>Module replacement rules</title>
            <para>
                Module replacement rules allow a build to declare that a legacy library has been replaced by a new one.
                A good example when a new library replaced a legacy one is the "google-collections" -> "guava" migration.
                The team that created google-collections decided to change the module name from "com.google.collections:google-collections" into "com.google.guava:guava".
                This a legal scenario in the industry: teams need to be able to change the names of products they maintain, including the module coordinates.
                Renaming of the module coordinates has impact on conflict resolution.
            </para>
            <para>
                To explain the impact on conflict resolution, let's consider the "google-collections" -> "guava" scenario.
                It may happen that both libraries are pulled into the same dependency graph.
                For example, "our" project depends on guava but some of our dependencies pull in a legacy version of google-collections.
                This can cause runtime errors, for example during test or application execution.
                Gradle does not automatically resolve the google-collections VS guava conflict because it is not considered as a "version conflict".
                It's because the module coordinates for both libraries are completely different and conflict resolution is activated when
                "group" and "name" coordinates are the same but there are different versions available in the dependency graph
                (for more info, please refer to the section on conflict resolution).
                Traditional remedies to this problem are:
                <itemizedlist>
                    <listitem>Declare exclusion rule to avoid pulling in "google-collections" to graph. It is probably the most popular approach.</listitem>
                    <listitem>Avoid dependencies that pull in legacy libraries.</listitem>
                    <listitem>Upgrade the dependency version if the new version no longer pulls in a legacy library.</listitem>
                    <listitem>Downgrade to "google-collections". It's not recommended, just mentioned for completeness.</listitem>
                </itemizedlist>
                Traditional approaches work but they are not general enough.
                For example, an organisation wants to resolve the google-collections VS guava conflict resolution problem in all projects.
                Starting from Gradle 2.2 it is possible to declare that certain module was replaced by other.
                This enables organisations to include the information about module replacement in the corporate plugin suite and resolve the problem
                holistically for all Gradle-powered projects in the enterprise.
                <sample id="module_replacement_declaration" dir="userguide/artifacts/componentModuleMetadata" title="Declaring module replacement">
                    <sourcefile file="build.gradle" snippet="module_replacement_declaration"/>
                </sample>
                For more examples and detailed API, please refer to the DSL reference for <apilink class="org.gradle.api.artifacts.dsl.ComponentMetadataHandler"/>.
            </para>
            <para>
                What happens when we declare that "google-collections" are replaced by "guava"?
                Gradle can use this information for conflict resolution.
                Gradle will consider every version of "guava" newer/better than any version of "google-collections".
                Also, Gradle will ensure that only guava jar is present in the classpath / resolved file list.
                Please note that if only "google-collections" appears in the dependency graph (e.g. no "guava")
                Gradle will not eagerly replace it with "guava".
                Module replacement is an information that Gradle uses for resolving conflicts. If there is no conflict
                (e.g. only "google-collections" or only "guava" in the graph) the replacement information is not used.
            </para>
            <para>
                Currently it is not possible to declare that certain modules is replaced by a set of modules.
                However, it is possible to declare that multiple modules are replaced by a single module.
            </para>
        </section>
    </section>
    <section id='sec:dependency_cache'>
        <title>The dependency cache</title>
        <para>Gradle contains a highly sophisticated dependency caching mechanism, which seeks to minimise the number of remote requests made in
            dependency resolution, while striving to guarantee that the results of dependency resolution are correct and reproducible.
        </para>
        <para>
            The Gradle dependency cache consists of 2 key types of storage:
        </para>
        <itemizedlist>
            <listitem>
                <para>A file-based store of downloaded artifacts, including binaries like jars as well as raw downloaded meta-data like POM files and Ivy files.
                    The storage path for a downloaded artifact includes the SHA1 checksum, meaning that 2 artifacts with the same name but different content can easily be cached.
                </para>
            </listitem>
            <listitem>
                <para>A binary store of resolved module meta-data, including the results of resolving dynamic versions, module descriptors, and artifacts.</para>
            </listitem>
        </itemizedlist>
        <para>Separating the storage of downloaded artifacts from the cache metadata permits us to do some very powerful things with our cache that would be difficult with a transparent,
            file-only cache layout.
        </para>
        <para>The Gradle cache does not allow the local cache to hide problems and create other mysterious and difficult to debug behavior
            that has been a challenge with many build tools. This new behavior is implemented in a bandwidth and storage efficient way.
            In doing so, Gradle enables reliable and reproducible enterprise builds.
        </para>

        <section id='sec:cache_features'>
            <title>Key features of the Gradle dependency cache</title>
            <section id='sub:cache_metadata'>
                <title>Separate metadata cache</title>
                <para>
                    Gradle keeps a record of various aspects of dependency resolution in binary format in the metadata cache.
                    The information stored in the metadata cache includes:
                    <itemizedlist>
                        <listitem>The result of resolving a dynamic version (e.g. <literal>1.+</literal>) to a concrete version (e.g. <literal>1.2</literal>).</listitem>
                        <listitem>The resolved module metadata for a particular module, including module artifacts and module dependencies.</listitem>
                        <listitem>The resolved artifact metadata for a particular artifact, including a pointer to the downloaded artifact file.</listitem>
                        <listitem>The
                            <emphasis>absence</emphasis>
                            of a particular module or artifact in a particular repository,
                            eliminating repeated attempts to access a resource that does not exist.
                        </listitem>
                    </itemizedlist>
                    Every entry in the metadata cache includes a record of the repository that provided the information as well as a timestamp that can be used for cache expiry.
                </para>
            </section>
            <section id='sub:cache_repository_independence'>
                <title>Repository caches are independent</title>
                <para>As described above, for each repository there is a separate metadata cache. A repository is identified by its URL, type and layout.
                    If a module or artifact has not been previously resolved from <emphasis>this repository</emphasis>, Gradle will attempt to resolve the module
                    against the repository. This will always involve a remote lookup on the repository, however in many cases no download will be required (see<xref
                            linkend='sub:cache_artifact_reuse'/>, below).
                </para>
                <para>Dependency resolution will fail if the required artifacts are not available in any repository specified by the build,
                    even if the local cache has a copy of this artifact which was retrieved from a different repository.
                    Repository independence allows builds to be isolated from each other in an advanced way that no build tool has done before.
                    This is a key feature to create builds that are reliable and reproducible in any environment.
                </para>
            </section>
            <section id='sub:cache_artifact_reuse'>
                <title>Artifact reuse</title>
                <para>Before downloading an artifact, Gradle tries to determine the checksum of the required artifact by downloading the sha file associated
                    with that artifact. If the checksum can be retrieved, an artifact is not downloaded if an artifact already exists with the same id and checksum.
                    If the checksum cannot be retrieved from the remote server, the artifact will be downloaded (and ignored if it matches an existing artifact).
                </para>
                <para>As well as considering artifacts downloaded from a different repository, Gradle will also attempt to reuse artifacts found in the local Maven Repository.
                    If a candidate artifact has been downloaded by Maven, Gradle will use this artifact if it can be verified to match the checksum declared by the remote server.
                </para>
            </section>
            <section id='sub:cache_checksum_storage'>
                <title>Checksum based storage</title>
                <para>
                    It is possible for different repositories to provide a different binary artifact in response to the same artifact identifier. This is often the case with Maven SNAPSHOT
                    artifacts, but can also be true for any artifact which is republished without changing it's identifier.
                    By caching artifacts based on their SHA1 checksum, Gradle is able to maintain multiple versions of the same artifact. This means that when resolving against
                    one repository Gradle will never overwrite the cached artifact file from a different repository. This is done without requiring a separate artifact file store per repository.
                </para>
            </section>
            <section id='sub:cache_locking'>
                <title>Cache Locking</title>
                <para>
                    The Gradle dependency cache uses file-based locking to ensure that it can safely be used by multiple Gradle processes concurrently. The lock is held whenever the binary
                    meta-data store is being read or written, but is released for slow operations such as downloading remote artifacts.
                </para>
            </section>
        </section>
        <section id='sec:cache_command_line_options'>
            <title>Command line options to override caching</title>
            <section id='sub:cache_offline'>
                <title>Offline</title>
                <para>The <literal>--offline</literal>
                    command line switch tells Gradle to always use dependency modules from the cache, regardless if they are due to be checked again.
                    When running with offline, Gradle will never attempt to access the network to perform dependency resolution.
                    If required modules are not present in the dependency cache, build execution will fail.
                </para>
            </section>
            <section id='sub:cache_refresh'>
                <title>Refresh</title>
                <para>At times, the Gradle Dependency Cache can be out of sync with the actual state of the configured repositories. Perhaps a repository was initially misconfigured,
                    or perhaps a “non-changing” module was published incorrectly. To refresh all dependencies in the dependency cache, use the
                    <literal>--refresh-dependencies</literal> option on the command line.
                </para>
                <para>The <literal>--refresh-dependencies</literal> option tells Gradle to ignore all cached entries for resolved modules and artifacts.
                    A fresh resolve will be performed against all configured repositories, with dynamic versions recalculated, modules refreshed, and artifacts downloaded.
                    However, where possible Gradle will check if the previously downloaded artifacts are valid before downloading again.
                    This is done by comparing published SHA1 values in the repository with the SHA1 values for existing downloaded artifacts.
                </para>
            </section>
        </section>
        <section id='sec:controlling_caching'>
            <title>Fine-tuned control over dependency caching</title>
            <para>You can fine-tune certain aspects of caching using the
                <literal>ResolutionStrategy</literal>
                for a configuration.
            </para>
            <para>By default, Gradle caches dynamic versions for 24 hours. To change how long Gradle will cache the resolved version for a dynamic version, use:
            </para>
            <sample id="dynamic-version-cache-control" dir="userguide/artifacts/resolutionStrategy" title="Dynamic version cache control">
                <sourcefile file="build.gradle" snippet="dynamic-version-cache-control"/>
            </sample>
            <para>By default, Gradle caches changing modules for 24 hours. To change how long Gradle will cache the meta-data and artifacts for a changing module, use:
            </para>
            <sample id="changing-module-cache-control" dir="userguide/artifacts/resolutionStrategy" title="Changing module cache control">
                <sourcefile file="build.gradle" snippet="changing-module-cache-control"/>
            </sample>
            <para>For more details, take a look at the API documentation for <apilink class="org.gradle.api.artifacts.ResolutionStrategy"/>.
            </para>
        </section>
    </section>
    <section id='sec:strategies_of_transitive_dependency_management'>
        <title>Strategies for transitive dependency management</title>
        <para>Many projects rely on the <ulink url='https://repo1.maven.org/maven2'>Maven Central repository</ulink>. This is not without problems.
        </para>
        <itemizedlist>
            <listitem>
                <para>The Maven Central repository can be down or can be slow to respond.
                </para>
            </listitem>
            <listitem>
                <para>The POM files of many popular projects specify dependencies or other configuration that
                are just plain wrong (for instance, the POM file of the “<literal>commons-httpclient-3.0</literal>”
                module declares JUnit as a runtime dependency).
                </para>
            </listitem>
            <listitem>
                <para>For many projects there is not one right set of dependencies (as more or less imposed by the POM format).
                </para>
            </listitem>
        </itemizedlist>
        <para>If your project relies on the Maven Central repository you are likely to need an additional custom repository,
            because:
        </para>
        <itemizedlist>
            <listitem>
                <para>You might need dependencies that are not uploaded to Maven Central yet.
                </para>
            </listitem>
            <listitem>
                <para>You want to deal properly with invalid metadata in a Maven Central POM file.
                </para>
            </listitem>
            <listitem>
                <para>You don't want to expose people to the downtimes or slow response of Maven Central, if they
                just want to build your project.
                </para>
            </listitem>
        </itemizedlist>
        <para>It is not a big deal to set-up a custom repository,
            <footnote>
                <para>If you want to shield your project from the downtimes of Maven Central things get more complicated. You
                    probably want to set-up a repository proxy for this. In an enterprise environment this is rather
                    common. For an open source project it looks like overkill.
                </para>
            </footnote>
            but it can be tedious to keep it up to date. For a new version, you always have to create the new XML
            descriptor and the directories. Your custom repository is another infrastructure element which might
            have downtimes and needs to be updated. To enable historical builds, you need to keep all the past
            libraries, not to mention a backup of these. It is another layer of indirection. Another source of information
            you have to lookup. All this is not really a big deal but in its sum it has an impact. Repository managers like
            Artifactory or Nexus make this easier, but most open source projects don't usually have a host for those products.
            This is changing with new services like <ulink url='http://bintray.com'>Bintray</ulink> that let developers host and
            distribute their release binaries using a self-service repository platform. Bintray also supports sharing approved artifacts
            though the <ulink url='http://jcenter.bintray.com'>JCenter</ulink> public repository to provide a single resolution address for
            all popular OSS Java artifacts (see <xref linkend="sub:maven_jcenter"/>).
        </para>
        <para>This is a common reason why many projects prefer to store their libraries in their version control system. This
            approach is fully supported by Gradle. The libraries can be stored in a flat directory without any XML module
            descriptor files. Yet Gradle offers complete transitive dependency management. You can use either client module
            dependencies to express the dependency relations, or artifact dependencies in case a first level dependency has no
            transitive dependencies. People can check out such a project from your source code control system and
            have everything necessary to build it.
        </para>
        <para>If you are working with a distributed version control system like Git you probably don't want to
            use the version control system to store libraries as people check out the whole history. But even here the flexibility
            of Gradle can make your life easier. For example, you can use a shared flat directory without XML descriptors and
            yet you can have full transitive dependency management, as described above.
        </para>
        <para>You could also have a mixed strategy. If your main concern is bad metadata in the POM file and maintaining custom XML descriptors,
            then <emphasis>Client Modules</emphasis> offer an alternative. However, you can still use a Maven2 repo or your custom repository as a repository for
            <emphasis>jars only</emphasis> and still enjoy <emphasis>transitive</emphasis> dependency management. Or
            you can only provide client modules for POMs with bad metadata. For the jars and the correct POMs you
            still use the remote repository.
        </para>
        <section id='sub:implicit_transitive_dependencies'>
            <title>Implicit transitive dependencies</title>
            <para>There is another way to deal with transitive dependencies <emphasis>without</emphasis> XML
            descriptor files. You can do this with Gradle, but we don't recommend it. We mention it for the sake of
            completeness and comparison with other build tools.
            </para>
            <para>The trick is to use only artifact dependencies and group them in lists. This will directly express
                your first level dependencies and your transitive dependencies (see <xref linkend="para:notation_collections"/>).
                The problem with this is that Gradle dependency management will see this as specifying all
                dependencies as first level dependencies. The dependency reports won't show your real dependency
                graph and the <literal>compile</literal> task uses all dependencies, not just the first level
                dependencies. All in all, your build is less maintainable and reliable than it could be when using
                client modules, and you don't gain anything.
            </para>
        </section>
    </section>
</chapter>
