<!--
  ~ 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='multi_project_builds'>
    <title>Multi-project Builds</title>
    <para>The powerful support for multi-project builds is one of Gradle's unique selling points. This topic is also the
        most intellectually challenging.
    </para>
    <para>
        A multi-project build in gradle consists of one root project, and one or more subprojects that may also have subprojects.
    </para>
    <section id="sec:cross_project_configuration">
        <title>Cross project configuration</title>
        <para>
            While each subproject could configure itself in complete isolation of the other subprojects, it is
            common that subprojects share common traits. It is then usually preferable to share configurations
            among projects, so the same configuration affects several subprojects.
        </para>
        <para>
            Let's start with a very simple multi-project build. Gradle is a general purpose build tool at
            its core, so the projects don't have to be Java projects. Our first examples are about marine life.
        </para>
        <section id="sec:configuration_and_execution">
            <title>Configuration and execution</title>
            <para><xref linkend="sec:build_phases"/> describes the phases of every Gradle build.
                Let's zoom into the configuration and execution phases of a multi-project build.
                Configuration here means executing the <literal>build.gradle</literal> file of a project, which
                implies e.g. downloading all plugins that were declared using '<literal>apply plugin</literal>'.
                By default, the configuration of all projects happens before any task is executed.
                This means that when a single task, from a single project is requested,
                <emphasis>all</emphasis> projects of multi-project build are configured first.
                The reason every project needs to be configured is to support
                the flexibility of accessing and changing any part of the Gradle project model.
            </para>
            <section id="sec:configuration_on_demand">
                <title>Configuration on demand</title>
                <para>The <firstterm>Configuration injection</firstterm> feature and access to the complete project model
                    are possible because every project is configured before the execution phase.
                    Yet, this approach may not be the most efficient in a very large multi-project build.
                    There are Gradle builds with a hierarchy of hundreds of subprojects.
                    The configuration time of huge multi-project builds may become noticeable.
                    Scalability is an important requirement for Gradle.
                    Hence, starting from version 1.4 a new incubating 'configuration on demand' mode is introduced.
                </para>
                <para>
                    Configuration on demand mode attempts to configure only projects that are relevant for requested
                    tasks, i.e. it only executes the <literal>build.gradle</literal> file of projects that are participating in the build.
                    This way, the configuration time of a large multi-project build can be reduced.
                    In the long term, this mode will become the default mode, possibly the only mode for Gradle build execution.
                    The configuration on demand feature is incubating so not every build is guaranteed to work correctly.
                    The feature should work very well for multi-project builds that have decoupled projects (<xref linkend="sec:decoupled_projects"/>).
                    In “configuration on demand” mode, projects are configured as follows:
                    <itemizedlist>
                        <listitem>The root project is always configured.
                            This way the typical common configuration is supported (allprojects or subprojects script blocks).</listitem>
                        <listitem>The project in the directory where the build is executed is also configured, but only when Gradle is executed without any tasks.
                            This way the default tasks behave correctly when projects are configured on demand.</listitem>
                        <listitem>The standard project dependencies are supported and makes relevant projects configured.
                            If project A has a compile dependency on project B then building A causes configuration of both projects.</listitem>
                        <listitem>The task dependencies declared via task path are supported and cause relevant projects to be configured.
                            Example: someTask.dependsOn(":someOtherProject:someOtherTask")
                        </listitem>
                        <listitem>A task requested via task path from the command line (or Tooling API) causes the relevant project to be configured.
                            For example, building 'projectA:projectB:someTask' causes configuration of projectB.
                        </listitem>
                    </itemizedlist>
                </para>
                <para>
                    Eager to try out this new feature? To configure on demand with every build run see <xref linkend="sec:gradle_configuration_properties"/>.
                    To configure on demand just for a given build please see <xref linkend="gradle_command_line"/>.
                </para>
            </section>
        </section>
        <section id="sec:defining_common_behavior">
            <title>Defining common behavior</title>
            <para>Let's look at some examples with the following project tree. This is a multi-project build with a root project
                named <literal>water</literal> and a subproject named <literal>bluewhale</literal>.
            </para>
            <sample id="multiprojectFirstExample" dir="userguide/multiproject/firstExample/water" includeLocation="true" title="Multi-project tree - water &amp; bluewhale projects">
                <layout>
                    build.gradle
                    settings.gradle
                    bluewhale/
                </layout>
                <sourcefile file="settings.gradle"/>
            </sample>
            <para>And where is the build script for the <literal>bluewhale</literal> project? In Gradle build scripts are optional.
                Obviously for a single project build, a project without a build script doesn't make much sense. For
                multiproject builds the situation is different. Let's look at the build script for the <literal>water</literal> project and
                execute it:
            </para>
            <sample id="multiprojectFirstExample" dir="userguide/multiproject/firstExample/water" title="Build script of water (parent) project">
                <sourcefile file="build.gradle"/>
                <output args="-q hello"/>
            </sample>
            <para>Gradle allows you to access any project of the multi-project build from any build script. The Project
                API provides a method called <literal>project()</literal>, which takes a path as an argument and returns
                the Project object for this path. The capability to configure a project build from any build script we
                call <firstterm>cross project configuration</firstterm>. Gradle implements this via
                <firstterm>configuration injection</firstterm>.
            </para>
            <para>We are not that happy with the build script of the <literal>water</literal>  project. It is inconvenient to add the task
                explicitly for every project. We can do better. Let's first add another project called
                <literal>krill</literal> to our multi-project build.
            </para>
            <sample id="multiprojectAddKrill" dir="userguide/multiproject/addKrill/water" includeLocation="true" title="Multi-project tree - water, bluewhale  &amp; krill projects">
                <layout>
                    build.gradle
                    settings.gradle
                    bluewhale/
                    krill/
                </layout>
                <sourcefile file="settings.gradle"/>
            </sample>
            <para>Now we rewrite the <literal>water</literal> build script and boil it down to a single line.</para>
            <sample id="multiprojectAddKrill" dir="userguide/multiproject/addKrill/water" title="Water project build script">
                <sourcefile file="build.gradle"/>
                <output args="-q hello"/>
            </sample>
            <para>Is this cool or is this cool? And how does this work? The Project API provides a property
                <literal>allprojects</literal>
                which returns a list with the current project and all its subprojects underneath it. If you call
                <literal>allprojects</literal>
                with a closure, the statements of the closure are delegated to the projects associated with <literal>
                    allprojects</literal>. You could also do an iteration via <literal>allprojects.each</literal>, but
                that would be more verbose.
            </para>
            <para>Other build systems use inheritance as the primary means for defining common behavior. We also offer
                inheritance for projects as you will see later. But Gradle uses configuration injection as the usual way
                of defining common behavior. We think it provides a very powerful and flexible way of configuring
                multiproject builds.
            </para>
            <para>
                Another possibilty for sharing configuration is to use a common external script.
                See <xref linkend="sec:configuring_using_external_script"/> for more information.
            </para>
        </section>
    </section>
    <section id="sec:subproject_configuration">
        <title>Subproject configuration</title>
        <para>The Project API also provides a property for accessing the subprojects only.
        </para>
        <section id="sec:defining_common_behavior_subprojects">
            <title>Defining common behavior</title>
            <sample id="multiprojectUseSubprojects" dir="userguide/multiproject/useSubprojects/water" title="Defining common behavior of all projects and subprojects">
                <sourcefile file="build.gradle"/>
                <output args="-q hello"/>
            </sample>
            <para>
                You may notice that there are two code snippets referencing the “<literal>hello</literal>” task.
                The first one, which uses the “<literal>task</literal>” keyword, constructs the task and provides it's base configuration.
                The second piece doesn't use the “<literal>task</literal>” keyword, as it is further configuring the existing “<literal>hello</literal>” task.
                You may only construct a task once in a project, but you may add any number of code blocks providing additional configuration.
            </para>
        </section>
        <section id="sub:adding_specific_behavior">
            <title>Adding specific behavior</title>
            <para>You can add specific behavior on top of the common behavior. Usually we put the project specific
                behavior in the build script of the project where we want to apply this specific behavior. But as we
                have already seen, we don't have to do it this way. We could add project specific behavior for the
                <literal>bluewhale</literal> project like this:
            </para>
            <sample id="multiprojectSubprojectsAddFromTop" dir="userguide/multiproject/subprojectsAddFromTop/water" title="Defining specific behaviour for particular project">
                <sourcefile file="build.gradle"/>
                <output args="-q hello"/>
            </sample>
            <para>As we have said, we usually prefer to put project specific behavior into the build script of this
                project. Let's refactor and also add some project specific behavior to the <literal>krill</literal>
                project.
            </para>
            <sample id="multiprojectSpreadSpecifics" dir="userguide/multiproject/spreadSpecifics/water" includeLocation="true" title="Defining specific behaviour for project krill">
                <layout>
                    build.gradle
                    settings.gradle
                    bluewhale/build.gradle
                    krill/build.gradle
                </layout>
                <sourcefile file="settings.gradle"/>
                <sourcefile file="bluewhale/build.gradle"/>
                <sourcefile file="krill/build.gradle"/>
                <sourcefile file="build.gradle"/>
                <output args="-q hello"/>
            </sample>
        </section>
        <section id="sub:project_filtering">
            <title>Project filtering</title>
            <para>To show more of the power of configuration injection, let's add another project
                called <literal>tropicalFish</literal> and add more behavior to the build via the build script of the
                <literal>water</literal> project.
            </para>
            <section id="ssub:filtering_by_name">
                <title>Filtering by name</title>
                <sample id="multiprojectAddTropical" dir="userguide/multiproject/addTropical/water" includeLocation="true" title="Adding custom behaviour to some projects (filtered by project name)">
                    <layout>
                        build.gradle
                        settings.gradle
                        bluewhale/build.gradle
                        krill/build.gradle
                        tropicalFish/
                    </layout>
                    <sourcefile file="settings.gradle"/>
                    <sourcefile file="build.gradle"/>
                    <output args="-q hello"/>
                </sample>
                <para>The <literal>configure()</literal> method takes a list as an argument and applies the
                    configuration to the projects in this list.
                </para>
            </section>
            <section id="ssub:filtering_by_properties">
                <title>Filtering by properties</title>
                <para>Using the project name for filtering is one option. Using extra project properties is another.
                    (See <xref linkend='sec:extra_properties'/> for more information on extra properties.)
                </para>
                <sample id="multiprojectTropicalWithProperties" dir="userguide/multiproject/tropicalWithProperties/water" includeLocation="true" title="Adding custom behaviour to some projects (filtered by project properties)">
                    <layout>
                        build.gradle
                        settings.gradle
                        bluewhale/build.gradle
                        krill/build.gradle
                        tropicalFish/build.gradle
                    </layout>
                    <sourcefile file="settings.gradle"/>
                    <sourcefile file="bluewhale/build.gradle"/>
                    <sourcefile file="krill/build.gradle"/>
                    <sourcefile file="tropicalFish/build.gradle"/>
                    <sourcefile file="build.gradle"/>
                    <output args="-q hello"/>
                </sample>
                <para>In the build file of the <literal>water</literal> project we use an <literal>afterEvaluate</literal>
                    notification. This means that the closure we are passing gets evaluated <emphasis>after</emphasis>
                    the build scripts of the subproject are evaluated. As the property <literal>arctic</literal>
                    is set in those build scripts, we have to do it this way. You will find more on this topic in
                    <xref linkend='sec:dependencies_which_dependencies'/>
                </para>
            </section>
        </section>
    </section>
    <section id="sec:execution_rules_for_multi_project_builds">
        <title>Execution rules for multi-project builds</title>
        <para>When we executed the <literal>hello</literal> task from the root project dir, things behaved in an
            intuitive way. All the <literal>hello</literal> tasks of the different projects were executed. Let's switch
            to the <literal>bluewhale</literal> dir and see what happens if we execute Gradle from there.
        </para>
        <sample id="multiprojectSubBuild" dir="userguide/multiproject/tropicalWithProperties/water/bluewhale" title="Running build from subproject">
           <output args='-q hello'/>
        </sample>
        <para>The basic rule behind Gradle's behavior is simple. Gradle looks down the hierarchy, starting with the
            <emphasis>current dir</emphasis>, for tasks with the name
            <literal>hello</literal>
            and executes them. One thing is very important to note. Gradle
            <emphasis>always</emphasis>
            evaluates
            <emphasis>every</emphasis>
            project of the multi-project build and creates all existing task objects. Then, according to the task name
            arguments and the current dir, Gradle filters the tasks which should be executed. Because of Gradle's
            cross project configuration <emphasis>every</emphasis> project has to be evaluated before <emphasis>any</emphasis>
            task gets executed. We will have a closer look at this in the next section. Let's now have our last marine
            example. Let's add a task to <literal>bluewhale</literal> and <literal>krill</literal>.
        </para>
        <sample id="multiprojectPartialTasks" dir="userguide/multiproject/partialTasks/water" title="Evaluation and execution of projects">
            <sourcefile file="bluewhale/build.gradle"/>
            <sourcefile file="krill/build.gradle"/>
            <output args="-q distanceToIceberg"/>
        </sample>
        <para>Here's the output without the <literal>-q</literal> option:</para>
        <sample id="multiprojectPartialTasksNotQuiet" dir="userguide/multiproject/partialTasks/water" title="Evaluation and execution of projects">
            <output args="distanceToIceberg"/>
        </sample>
        <para>The build is executed from the <literal>water</literal> project. Neither <literal>water</literal> nor
            <literal>tropicalFish</literal> have a task with the name <literal>distanceToIceberg</literal>. Gradle does
            not care. The simple rule mentioned already above is: Execute all tasks down the hierarchy which have this
            name. Only complain if there is <emphasis>no</emphasis> such task!
        </para>
    </section>
    <section id="sec:running_partial_build_from_the_root">
        <title>Running tasks by their absolute path</title>
        <para>As we have seen, you can run a multi-project build by entering any subproject dir and execute the build
            from there. All matching task names of the project hierarchy starting with the current dir are executed. But
            Gradle also offers to execute tasks by their absolute path (see also <xref linkend='sec:project_and_task_paths'/>):
        </para>
        <sample id="multiprojectAbsoluteTaskPaths" dir="userguide/multiproject/tropicalWithProperties/water/tropicalFish" title="Running tasks by their absolute path">
            <output args="-q :hello :krill:hello hello"/>
        </sample>
        <para>The build is executed from the <literal>tropicalFish</literal> project. We execute the <literal>hello</literal>
            tasks of the <literal>water</literal>, the <literal>krill</literal> and the <literal>tropicalFish</literal>
            project. The first two tasks are specified by their absolute path, the last task is executed using the name
            matching mechanism described above.
        </para>
    </section>
    <section id="sec:project_and_task_paths">
        <title>Project and task paths</title>
        <para>A project path has the following pattern: It starts
        with an optional colon, which denotes the root project.  The root
        project is the only project in a path that is not specified by
        its name. The rest of a project path is a colon-separated
        sequence of project names, where the next project is a subproject of the previous project.
        </para>
        <para>The path of a task is simply its project path plus the task name, like “<literal>:bluewhale:hello</literal>”. Within a project you can address a task of the same project just by its name.
            This is interpreted as a relative path.
        </para>
    </section>
    <section id="sec:dependencies_which_dependencies">
        <title>Dependencies - Which dependencies?</title>
        <para>The examples from the last section were special, as the projects had no <emphasis>Execution
            Dependencies</emphasis>. They had only <emphasis>Configuration Dependencies</emphasis>. The following sections illustrate the differences between these two types of dependencies.
        </para>
        <section id="sub:execution_time_dependencies">
            <title>Execution dependencies</title>
            <section id="ssub:dependencies_and_execution_order">
                <title>Dependencies and execution order</title>
                <sample id="multiprojectFirstMessages" dir="userguide/multiproject/dependencies/firstMessages/messages" includeLocation="true" title="Dependencies and execution order">
                    <layout>
                        settings.gradle
                        consumer/build.gradle
                        producer/build.gradle
                    </layout>
                    <sourcefile file="settings.gradle"/>
                    <sourcefile file="consumer/build.gradle"/>
                    <sourcefile file="producer/build.gradle"/>
                    <output args="-q action"/>
                </sample>
                <para>This didn't quite do what we want. If nothing else is defined, Gradle executes the task in alphanumeric order.
                    Therefore, Gradle will execute
                    “<literal>:consumer:action</literal>”
                    before “<literal>:producer:action</literal>”. Let's try to solve this with a hack and
                    rename the producer project to “<literal>aProducer</literal>”.
                </para>
                <sample id="multiprojectMessagesHack" dir="userguide/multiproject/dependencies/messagesHack/messages" title="Dependencies and execution order">
                    <layout>
                        settings.gradle
                        aProducer/build.gradle
                        consumer/build.gradle
                    </layout>
                    <sourcefile file="settings.gradle"/>
                    <sourcefile file="aProducer/build.gradle"/>
                    <sourcefile file="consumer/build.gradle"/>
                    <output args="-q action"/>
                </sample>
                <para>We can show where this hack doesn't work if we now switch to the <literal>consumer</literal> dir and
                    execute the build.
                </para>
                <sample id="multiprojectMessagesHackBroken" dir="userguide/multiproject/dependencies/messagesHack/messages/consumer" title="Dependencies and execution order">
                    <output args="-q action"/>
                </sample>
                <para>The problem is that the two
                    “<literal>action</literal>”
                    tasks are unrelated. If you execute the build from the
                    “<literal>messages</literal>”
                    project Gradle executes them both because they have the same name and they are down the hierarchy.
                    In the last example only one
                    “<literal>action</literal>” task
                    was down the hierarchy and therefore it was the only task that was executed. We need something
                    better than this hack.
                </para>
            </section>
            <section id="ssub:declaring_dependencies">
                <title>Declaring dependencies</title>
                <sample id="multiprojectMessagesDependencies" dir="userguide/multiproject/dependencies/messagesWithDependencies/messages" includeLocation="true" title="Declaring dependencies">
                    <layout>
                        settings.gradle
                        consumer/build.gradle
                        producer/build.gradle
                    </layout>
                    <sourcefile file="settings.gradle"/>
                    <sourcefile file="consumer/build.gradle"/>
                    <sourcefile file="producer/build.gradle"/>
                    <output args="-q action"/>
                </sample>
                <para>Running this from the <literal>consumer</literal> directory gives:</para>
                <sample id="multiprojectMessagesDependenciesSubBuild" dir="userguide/multiproject/dependencies/messagesWithDependencies/messages/consumer" title="Declaring dependencies">
                    <output args="-q action"/>
                </sample>
                <para>This is now working better because we have declared that the
                    “<literal>action</literal>” task in the “<literal>consumer</literal>”
                    project has an
                    <emphasis>execution dependency</emphasis>
                    on the “<literal>action</literal>” task in the
                    “<literal>producer</literal>”
                    project.
                </para>
            </section>
            <section id="ssub:the_nature_of_cross_project_task_dependencies">
                <title>The nature of cross project task dependencies</title>
                <para>Of course, task dependencies across different projects are not limited to tasks with the same name.
                    Let's change the naming of our tasks and execute the build.
                </para>
                <sample id="multiprojectMessagesTaskDependencies" dir="userguide/multiproject/dependencies/messagesTaskDependencies/messages" title="Cross project task dependencies">
                    <sourcefile file="consumer/build.gradle"/>
                    <sourcefile file="producer/build.gradle"/>
                    <output args="-q consume"/>
                </sample>
            </section>
        </section>
        <section id="sub:configuration_time_dependencies">
            <title>Configuration time dependencies</title>
            <para>Let's see one more example with our producer-consumer build before we enter
                <emphasis>Java</emphasis>
                land. We add a property to the “<literal>producer</literal>” project and create a configuration time dependency from
                “<literal>consumer</literal>” to “<literal>producer</literal>”.
            </para>
            <sample id="multiprojectMessagesConfigDependenciesBroken" dir="userguide/multiproject/dependencies/messagesConfigDependenciesBroken/messages" title="Configuration time dependencies">
                <sourcefile file="consumer/build.gradle"/>
                <sourcefile file="producer/build.gradle"/>
                <output args="-q consume"/>
            </sample>
            <para>The default
                <emphasis>evaluation</emphasis>
                order of projects is alphanumeric (for the same nesting level). Therefore the
                “<literal>consumer</literal>”
                project is evaluated before the
                “<literal>producer</literal>”
                project and the
                “<literal>producerMessage</literal>”
                value is set
                <emphasis>after</emphasis>
                it is read by the
                “<literal>consumer</literal>”
                project. Gradle offers a solution for this.
            </para>
            <sample id="multiprojectMessagesConfigDependencies" dir="userguide/multiproject/dependencies/messagesConfigDependencies/messages" title="Configuration time dependencies - evaluationDependsOn">
                <sourcefile file="consumer/build.gradle"/>
                <output args="-q consume"/>
            </sample>
            <para>The use of the
                “<literal>evaluationDependsOn</literal>” command
                results in the evaluation of
                the “<literal>producer</literal>” project
                <emphasis>before</emphasis> the
                “<literal>consumer</literal>” project
                is evaluated. This example is a bit contrived to show the mechanism. In
                <emphasis>this</emphasis>
                case there would be an easier solution by reading the key property at execution time.
            </para>
            <sample id="multiprojectMessagesConfigDependenciesAltSolution" dir="userguide/multiproject/dependencies/messagesConfigDependenciesAltSolution/messages" title="Configuration time dependencies">
                <sourcefile file="consumer/build.gradle"/>
                <output args="-q consume"/>
            </sample>
            <para>Configuration dependencies are very different from execution dependencies. Configuration dependencies
                are between projects whereas execution dependencies are always resolved to task dependencies. Also note that all projects are always configured, even when you start the build from a subproject.
                The default configuration order is top down, which is usually what is needed.
            </para>
            <para>
                To change the default configuration order to “bottom up”, use the “<literal>evaluationDependsOnChildren()</literal>” method instead.
            </para>
            <para>On the same nesting level the configuration order depends on the alphanumeric position. The most
                common use case is to have multi-project builds that share a common lifecycle (e.g. all projects use the
                Java plugin). If you declare with
                <literal>dependsOn</literal>
                a
                <emphasis>execution dependency</emphasis>
                between different projects, the default behavior of this method is to also create a
                <emphasis>configuration</emphasis>
                dependency between the two projects. Therefore it is likely that you don't have to define configuration
                dependencies explicitly.
            </para>
        </section>
        <section id="sub:real_life_examples">
            <title>Real life examples</title>
            <para>Gradle's multi-project features are driven by real life use cases. One good example consists of two web application projects and a parent project that creates a distribution including the two web applications.
                <footnote>
                    <para>The real use case we had, was using <ulink url='http://lucene.apache.org/solr'/>, where you
                        need a separate war for each index you are accessing. That was one reason why we have created a
                        distribution of webapps. The Resin servlet container allows us, to let such a distribution point
                        to a base installation of the servlet container.
                    </para>
                </footnote>
                For the example we use only one build script and do <emphasis>cross project configuration</emphasis>.
            </para>
            <sample id="webdist" dir="userguide/multiproject/dependencies/webDist" includeLocation="true" title="Dependencies - real life example - crossproject configuration">
                <layout>
                    settings.gradle
                    build.gradle
                    date/
                    date/src/main/java/
                    date/src/main/java/org/gradle/sample/DateServlet.java
                    hello/
                    hello/src/main/java/
                    hello/src/main/java/org/gradle/sample/HelloServlet.java
                </layout>
                <sourcefile file="settings.gradle"/>
                <sourcefile file="build.gradle"/>
            </sample>
            <para>We have an interesting set of dependencies. Obviously the
                <literal>date</literal>
                and
                <literal>hello</literal>
                projects have a
                <emphasis>configuration</emphasis>
                dependency on <literal>webDist</literal>, as all the build logic for the webapp projects is injected by
                <literal>webDist</literal>. The
                <emphasis>execution</emphasis>
                dependency is in the other direction, as
                <literal>webDist</literal>
                depends on the build artifacts of
                <literal>date</literal>
                and <literal>hello</literal>. There is even a third dependency.
                <literal>webDist</literal>
                has a
                <emphasis>configuration</emphasis>
                dependency on
                <literal>date</literal>
                and
                <literal>hello</literal>
                because it needs to know the <literal>archivePath</literal>. But it asks for this information at
                <emphasis>execution time</emphasis>. Therefore we have no circular dependency.
            </para>
            <para>Such dependency patterns are daily bread in the problem space of multi-project builds. If a
                build system does not support these patterns, you either can't solve your problem or you need to do ugly
                hacks which are hard to maintain and massively impair your productivity as a build master.
            </para>
        </section>
    </section>
    <section id="sec:project_jar_dependencies">
        <title>Project lib dependencies</title>
        <para>What if one project needs the jar produced by another project in its compile path, and not just the jar
            but also the transitive dependencies of this jar? Obviously this is a very common use case for Java
            multi-project builds. As already mentioned in <xref linkend='sub:project_dependencies'/>, Gradle
            offers project lib dependencies for this.
        </para>
        <sample id="javadependencies_1" dir="userguide/multiproject/dependencies/java" includeLocation="true" title="Project lib dependencies">
            <layout>
                settings.gradle
                build.gradle
                api/
                api/src/main/java/
                api/src/main/java/org/gradle/sample/api/Person.java
                api/src/main/java/org/gradle/sample/apiImpl/PersonImpl.java
                services/personService/
                services/personService/src/main/java/
                services/personService/src/main/java/org/gradle/sample/services/PersonService.java
                services/personService/src/test/java/
                services/personService/src/test/java/org/gradle/sample/services/PersonServiceTest.java
                shared/
                shared/src/main/java/
                shared/src/main/java/org/gradle/sample/shared/Helper.java
            </layout>
        </sample>
        <para>We have the projects “<literal>shared</literal>”, “<literal>api</literal>” and “<literal>personService</literal>”.
            The “<literal>personService</literal>” project has a lib dependency on the other two projects. The “<literal>api</literal>” project
            has a lib dependency on the “<literal>shared</literal>” project.
            <footnote>
                <para>
                    “<literal>services</literal>”
                    is also a project, but we use it just as a container. It has no build script and gets nothing
                    injected by another build script.
                </para>
            </footnote>
        </para>
        <sample id="javadependencies_2" dir="userguide/multiproject/dependencies/java" title="Project lib dependencies">
            <sourcefile file="settings.gradle"/>
            <sourcefile file="build.gradle"/>
        </sample>
        <para>All the build logic is in the
            “<literal>build.gradle</literal>” file of the root project.
            <footnote>
                <para>We do this here, as it makes the layout a bit easier. We usually put the project specific stuff
                    into the build script of the respective projects.
                </para>
            </footnote>
            A “<emphasis>lib</emphasis>”
            dependency is a special form of an execution dependency. It causes the other project to be built first and
            adds the jar with the classes of the other project to the classpath. It also adds the dependencies of the
            other project to the classpath. So you can enter the
            “<literal>api</literal>”
            directory and trigger a “<userinput>gradle compile</userinput>”. First
            the “<literal>shared</literal>” project
            is built and then
            the “<literal>api</literal>” project
            is built. Project dependencies enable partial multi-project builds.
        </para>
        <para>If you come from Maven land you might be perfectly happy with this. If you come from Ivy land, you might
            expect some more fine grained control. Gradle offers this to you:
        </para>
        <sample id="javaWithCustomConf" dir="userguide/multiproject/dependencies/javaWithCustomConf" title="Fine grained control over dependencies">
            <sourcefile file="build.gradle"/>
        </sample>
        <para>The Java plugin adds per default a jar to your project libraries which contains all the classes. In this
            example we create an
            <emphasis>additional</emphasis>
            library containing only the interfaces of the
            “<literal>api</literal>”
            project. We assign this library to a new <emphasis>dependency configuration</emphasis>. For the person
            service we declare that the project should be compiled only against the
            “<literal>api</literal>”
            interfaces but tested with all classes from “<literal>api</literal>”.
        </para>
        <section id="disable_dependency_projects">
            <title>Disabling the build of dependency projects</title>
            <para>Sometimes you don't want depended on projects to be built when doing a partial build.
                To disable the build of the depended on projects you can run Gradle with the <code>-a</code> option.
            </para>
        </section>
    </section>
    <section id="sec:parallel_execution">
        <title>Parallel project execution</title>
        <para>With more and more CPU cores available on developer desktops and CI servers,
            it is important that Gradle is able to fully utilise these processing resources.
            More specifically, the parallel execution attempts to:
            <itemizedlist>
                <listitem>Reduce total build time for a multi-project build where execution is IO bound or otherwise does not consume all available CPU resources.</listitem>
                <listitem>Provide faster feedback for execution of small projects without awaiting completion of other projects.</listitem>
            </itemizedlist>
            Although Gradle already offers parallel test execution via <apilink class="org.gradle.api.tasks.testing.Test" method="setMaxParallelForks"/>
            the feature described in this section is parallel execution at a project level.
            Parallel execution is an incubating feature. Please use it and let us know how it works for you.
        </para>
        <para>
            Parallel project execution allows the separate projects in a decoupled multi-project build to be executed in parallel
            (see also: <xref linkend="sec:decoupled_projects"/>).
            While parallel execution does not strictly require decoupling at configuration time,
            the long-term goal is to provide a powerful set of features that will be available for fully decoupled projects.
            Such features include:
            <itemizedlist>
                <listitem><xref linkend="sec:configuration_on_demand"/>.</listitem>
                <listitem>Configuration of projects in parallel.</listitem>
                <listitem>Re-use of configuration for unchanged projects.</listitem>
                <listitem>Project-level up-to-date checks.</listitem>
                <listitem>Using pre-built artifacts in the place of building dependent projects.</listitem>
            </itemizedlist>
        </para>
        <para>
            How does parallel execution work? First, you need to tell Gradle to use the parallel mode.
            You can use the command line argument (<xref linkend='gradle_command_line'/>) or configure your build environment (<xref linkend="sec:gradle_configuration_properties"/>).
            Unless you provide a specific number of parallel threads Gradle attempts to choose the right number based on available CPU cores.
            Every parallel worker exclusively owns a given project while executing a task.
            This means that 2 tasks from the same project are never executed in parallel.
            Therefore only multi-project builds can take advantage of parallel execution.
            Task dependencies are fully supported and parallel workers will start executing upstream tasks first.
            Bear in mind that the alphabetical scheduling of decoupled tasks, known from the sequential execution, does not really work in parallel mode.
            You need to make sure the task dependencies are declared correctly to avoid ordering issues.
        </para>
        <para>
            <emphasis>Warning:</emphasis> Be aware that task ordering is not strictly enforced when using parallel execution and can lead to unexpected results. A common case that surfaces this
            limitation is the use of the <literal>clean</literal> task provided by the <literal>base</literal> plugin in combination with any other task producing an output for a multi-project build
            if executed in parallel. For example let us assume a multi-project build with project A and project B where B depends on A. Running <literal>gradle clean build --parallel</literal>
            could lead to the following situation:
            <itemizedlist>
                <listitem><literal>A:clean</literal> is executed after <literal>A:jar</literal>.</listitem>
                <listitem>B depends on A and needs the JAR file of A. However, <literal>B:classes</literal> fails as it was executed after <literal>A:clean</literal> which deleted the JAR
                    file B depends on for compilation.
                </listitem>
            </itemizedlist>
            Furthermore, the tasks <literal>clean</literal> and <literal>classes</literal> could run at the same time and delete files that are needed for compilation across project boundaries. Gradle
            emits a warning for those situations. Future versions of Gradle will provide an appropriate fix.
        </para>
    </section>
    <section id="sec:decoupled_projects">
        <title>Decoupled Projects</title>
        <para>Gradle allows any project to access any other project during both the configuration and execution phases.
            While this provides a great deal of power and flexibility to the build author, it also limits the flexibility that Gradle has when building those projects.
            For instance, this effectively prevents Gradle from correctly building multiple projects in parallel, configuring only a subset of projects, or from substituting
            a pre-built artifact in place of a project dependency.
        </para>
        <para>Two projects are said to be <emphasis>decoupled</emphasis> if they do not directly access each other's project model. Decoupled projects may only interact in terms of
            declared dependencies: project dependencies (<xref linkend='sub:project_dependencies'/>) and/or task dependencies (<xref linkend='sec:task_dependencies'/>).
            Any other form of project interaction (i.e. by modifying another project object or by reading a value from another project object) causes the projects to
            be coupled. The consequence of coupling during the configuration phase is that if gradle is invoked with the 'configuration on demand' option, the result of the build can be flawed
            in several ways. The consequence of coupling during execution phase is that if gradle is invoked with the parallel option,
            one project task runs too late to influence a task of a project building in parallel.
            Gradle does not attempt to detect coupling and warn the user, as there are too many possibilities to introduce coupling.
        </para>
        <para>
            A very common way for projects to be coupled is by using configuration injection (<xref linkend='sec:cross_project_configuration'/>). It may not be immediately apparent, but using key
            Gradle features like the <literal>allprojects</literal> and <literal>subprojects</literal> keywords automatically cause your projects to be coupled.
            This is because these keywords are used in a <literal>build.gradle</literal> file, which defines a project. Often this is a “root project” that does nothing more than
            define common configuration, but as far as Gradle is concerned this root project is still a fully-fledged project, and by using <literal>allprojects</literal>
            that project is effectively coupled to all other projects. Coupling of the root project to subprojects does not impact 'configuration on demand', but using the
            <literal>allprojects</literal> and <literal>subprojects</literal> in any subproject's <literal>build.gradle</literal> file will have an impact.
        </para>
        <para>This means that using any form of shared build script logic or configuration injection (<literal>allprojects</literal>, <literal>subprojects</literal>, etc.)
            will cause your projects to be coupled. As we extend the concept of project decoupling and provide features that take advantage of decoupled projects,
            we will also introduce new features to help you to solve common use cases (like configuration injection) without causing your projects to be coupled.
        </para>
        <para>In order to make good use of cross project configuration without running into issues for parallel and 'configuration on demand' options, follow these recommendations:
        <itemizedlist>
            <listitem>
                Avoid a subproject's <literal>build.gradle</literal> referencing other subprojects; prefering cross configuration from the root project.
            </listitem>
            <listitem>
                Avoid changing the configuration of other projects at execution time.
            </listitem>
        </itemizedlist>
        </para>
    </section>
    <section id="sec:multiproject_build_and_test">
        <title>Multi-Project Building and Testing</title>
        <para>The <literal>build</literal> task of the Java plugin is typically used to compile, test, and perform
            code style checks (if the CodeQuality plugin is used) of a single project.  In multi-project builds
            you may often want to do all of these tasks across a range of projects.  The <literal>buildNeeded</literal>
            and <literal>buildDependents</literal> tasks can help with this.
        </para>
        <para>Look at <xref linkend='javadependencies_2'/>.  In this
            example, the “<literal>:services:personservice</literal>” project depends on both the “<literal>:api</literal>” and “<literal>:shared</literal>” projects.  The “<literal>:api</literal>” project also depends on the “<literal>:shared</literal>” project.
        </para>
        <para>Assume you are working on a single project, the “<literal>:api</literal>” project.  You have been making changes, but
            have not built the entire project since performing a clean.  You want to build any necessary supporting
            jars, but only perform code quality and unit tests on the project you have changed.
            The <literal>build</literal> task does this.
        </para>
        <sample id="multitestingBuild" dir="userguide/multiproject/dependencies/java" title="Build and Test Single Project">
            <output args=":api:build"/>
        </sample>

        <para>While you are working in a typical development cycle repeatedly building and testing changes to
            the “<literal>:api</literal>” project (knowing that you are only changing files in this one project), you may not want to
            even suffer the expense of building “<literal>:shared:compile</literal>” to see what has changed in the “<literal>:shared</literal>” project.
            Adding the “<literal>-a</literal>” option will cause Gradle to use cached jars to resolve any project lib
            dependencies and not try to re-build the depended on projects.
        </para>
        <sample id="multitestingBuildDashA" dir="userguide/multiproject/dependencies/java" title="Partial Build and Test Single Project">
            <test args=":shared:assemble"/>
            <output args="-a :api:build"/>
        </sample>

        <para>If you have just gotten the latest version of source from your version control system which included changes
            in other projects that “<literal>:api</literal>” depends on, you might want to not only build all the projects you depend on,
            but test them as well. The <literal>buildNeeded</literal> task also tests all the projects from the
            project lib dependencies of the testRuntime configuration.
        </para>
        <sample id="multitestingBuildNeeded" dir="userguide/multiproject/dependencies/java" title="Build and Test Depended On Projects">
            <output args=":api:buildNeeded"/>
        </sample>

        <para>You also might want to refactor some part of the “<literal>:api</literal>” project that is used in other projects.
            If you make these types of changes, it is not sufficient to test just the “<literal>:api</literal>”
            project, you also need to test all projects that depend on the “<literal>:api</literal>” project.
            The <literal>buildDependents</literal> task also tests all the projects that have a project lib dependency
            (in the testRuntime configuration) on the specified project.
        </para>
        <sample id="multitestingBuildDependents" dir="userguide/multiproject/dependencies/java" title="Build and Test Dependent Projects">
            <output args=":api:buildDependents"/>
        </sample>
        <para>Finally, you may want to build and test everything in all projects. Any task you run in the root project folder
        will cause that same named task to be run on all the children. So you can just run
        “<literal>gradle build</literal>” to build and test all projects.
        </para>
    </section>
    <section id="sec:multi_project_and_buildsrc">
        <title>Multi Project and buildSrc</title>
        <para>
            <xref linkend="sec:build_sources"/> tells us that we can place build logic to be compiled and tested in the special <literal>buildSrc</literal> directory.
            In a multi project build, there can only be one <literal>buildSrc</literal> directory which must be located in the root directory.
        </para>

    </section>
    <section id="sec:property_and_method_inheritance">
        <title>Property and method inheritance</title>
        <para>Properties and methods declared in a project are inherited to all its subprojects. This is an alternative
            to configuration injection. But we think that the model of inheritance does not reflect the problem space of
            multi-project builds very well. In a future edition of this user guide we might write more about this.
        </para>
        <para>Method inheritance might be interesting to use as Gradle's
            <emphasis>Configuration Injection</emphasis>
            does not support methods yet (but will in a future release).
        </para>
        <para>You might be wondering why we have implemented a feature we obviously don't like that much. One reason is
            that it is offered by other tools and we want to have the check mark in a feature comparison :). And we like
            to offer our users a choice.
        </para>
    </section>
    <section id="sec:multiproject_summary">
        <title>Summary</title>
        <para>Writing this chapter was pretty exhausting and reading it might have a similar effect. Our final message
            for this chapter is that multi-project builds with Gradle are usually
            <emphasis>not</emphasis>
            difficult. There are five elements you need to remember: <literal>allprojects</literal>, <literal>
            subprojects</literal>, <literal>evaluationDependsOn</literal>, <literal>evaluationDependsOnChildren</literal>
            and project lib dependencies.
            <footnote>
                <para>So we are well in the range of the
                    <ulink url='http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two'>7 plus 2
                        Rule
                    </ulink>
                    :)
                </para>
            </footnote>
            With those elements, and keeping in mind that Gradle has a distinct configuration and execution phase, you
            already have a lot of flexibility. But when you enter steep territory Gradle does not become an obstacle and
            usually accompanies and carries you to the top of the mountain.
        </para>
    </section>
</chapter>
