Generated by:
Craftsman

Craftsman Module Dependency (<dependency>)

This page describes the features provided by Craftsman Module Dependency tags (<dependency>). It explains the mechanics of Craftsman dependency tags and how they interact with dependent modules and their source.

What is <dependency>?

A dependency is another module (project, application, library, component, etc) that is required in order to build the current module. A dependency allows you to link the build lifecycles of two modules to one another, telling Craftsman what order they should be built in and what kind of relationship is represented by the dependency.

If the dependency has not been built (that is, if Craftsman cannot find the build artifacts like a .jar file), Craftsman calls Ant to build the dependency. So if module bar depends on module foo, Craftsman will look for foo.jar in foo's build/jar directory. If it doesn't find it, it will call the build for foo. Once the build for foo finishes, Craftsman looks for the foo.jar again. If it finds it, it makes a out of it and adds it to the list of libraries needed to build bar. Then it continues with the build process of bar--foo is now one of the jars used in compiling, testing, and packaging.

A dependency can be thought of a "sub Ant" or a "recursive Make" call. It chains the build process to other build processes, allowing you to just focus on your current module and let the build process take care of building or satisfying any dependencies.

How to declare a <dependency>

Here's a simple example:
    <!-- Libraries common to all modules -->
    <library id="rsh-commons" name="rsh-commons" externaldir="../lib/rsh-commons"/>
    <library id="log4j" name="log4j" externaldir="../lib/log4j"/>
    <library id="junit" name="junit" externaldir="../lib/junit" testlib="true"/>
    
    <!-- define the modules for this package -->
    <craftsmandef>
        <module moduleid="foo">
            <library refid="rsh-commons"/>
            <library refid="log4j"/>
            <library refid="junit"/>
        </module>
        <module moduleid="bar">
            <dependency moduleid="foo"/>
        </module>
    </craftsmandef>
When bar is built, Craftsman checks foo to see if it has been built. It then reuses the artifacts from the foo build as libraries for building bar. It also looks up the libraries used in "foo" and adds them to the libraries for "bar" (its as if you declared the library tags in both foo and bar).

This means that if foo creates a foo.jar, and bar was a java-app module (which has Class-Path entries in the final jar), foo.jar would appear in the Class-Path entry along with log4 and rsh-commons.

<dependency> attributes

While the above is a simple example, there are often some attributes you want (or need) to set in order to clarify the relationship of your module to your dependency.

dir

This specifies where to find the dependency (much like the <library> tag's externaldir attribute). Setting "dir" implies that the other module is not "in this Project space". By project space, we mean this Ant build's runtime. So if the two builds were not linked (as in a Master-Child configuration), dir will help you find the module and build it. This is useful when you have a complex build tree. If you specify the dir, it must be the exact location of the module's main directory (where its src, test, and build dirs live).

NOTE: When the "dir" attribute is specified, Craftsman cannot automatically use the libs from the dependency. So if the dependency uses "dir", you will need to specify any libraries the dependency depends on manually in your dependent module.

Please see the recommendations at the end before you make a very complicated dependency with dir.

type

Specifies the type of dependency: either "module" or "test". A "module" dependency means the library is needed to build the module itself. A "test" dependency means the library is used to build the test cases only, and should not be used in packaging or processing the module itself. The default value is "module".

Marking a module dependency as "test" is like specifying a library that has testlib set to "true".

includetest

Specifies whether to include any test jars in the list of the modules build artifacts. Valid values are "true" or "false". Default value is false. If you set this for dependency foo, Craftsman would then look for both foo.jar and foo-test.jar. This allows you to declare utilities in the test case source of module foo and then use those utilities in module bar.

Consider a Master-Child Build File Setup

Before you get too far into configuring dependencies, consider using a Master-Child setup for your modules. This will create one master file in a parent directory above the modules, allowing it to refer to modules and dependent modules without having to specify the dir attribute. A Master-Child setup also allows your to leverage the module definitions to automatically provide the libraries to use with dependents. It will also simplify how many build files you have to maintain and cut down on copy and paste errors. You can find more information at the Master-Child page.