Configure your RichFaces 4 project to use ANT and IVY for dependency management

This article will help you get your project to use Apache ANT and Apache Ivy as your build/dependency manager tool. Just to clarify this is not an Apache ANT or Ivy tutorial, here you will only find the information needed to setup this tools to work with the latest version of RichFaces.

 

The first step is to have your enviornment ready. you will need an installation of ANT properly configured, as well as an installation of Ivy. Follow the instruction on each project site to configure these tools.

 

Creating the structure of the project

 

After having ANT and Ivy installed, you will need to create a new project. For this tutorial we will use the directory structure generated for a JSF project using Eclipse+Jboss Tools. The structure used is as follows.

 

 

MyProject/
    src/
    WebContent/
        META-INF/
        pages/
        resources/
        templates/
        WEB-INF/
            lib/
            faces-config.xml
            web.xml
        index.html

 

Now, in order to use Ivy to handle all dependencies for us, we will need to create two files which tell Ivy how to retrieve the dependencies.

 

ivy.xml File

 

In our case we will create the ivy.xml file inside the project's root directory (that is under MyProject/). the ivy.xml file is the one that specifies the dependencies you need in order to build or execute your program (that includes testing of course).

 

Create your ivy.xml file and write the content of the snippet below into it:

 

 

<ivy-module version="2.0">
    <info organisation="org.apache" module="IvyTestProject" />
    <dependencies>
        <dependency org="commons-lang" name="commons-lang" rev="2.0" conf="default"/>
        <dependency org="commons-cli" name="commons-cli" rev="1.0" conf="default" />
        <dependency org="javax.servlet" name="servlet-api" rev="2.4" conf="default"/>
        <dependency org="javax.servlet" name="jstl" rev="1.2" conf="default"/>
        <dependency org="org.apache.myfaces.core" name="myfaces-api" rev="2.0.4" conf="default" />

        <dependency org="org.richfaces.ui" name="richfaces-components-ui" rev="4.1.0.Final" conf="default" />
        <dependency org="org.richfaces.core" name="richfaces-core-impl" rev="4.1.0.Final" conf="default" />
    </dependencies>
</ivy-module>

 

 

 

Note that last two dependency definitions are  richfaces-core and richfaces-ui dependencies, other dependencies are needed for a JSF application. In this case we are using MyFaces as the JSF implementation.

 

Now it is time to tell ivy where to find those dependencies we just defined. For this, we must create a new file that can be placed wherever you want in your file system (or outside if you prefer so). The only rule here is that we must be able to reach that file from our build script. For this tutorial we are going to put this file inside the project's root directory (that is MyProject/ ) as that way we wont need to define the location in build.xml.

 

ivysettings.xml File

 

Create a new file and name it ivysettings.xml. Here we will specify the resolvers that will retreive our dependencies. In case you need more information on how to do so, it's recomended to take a look at the oficial Ivy documentation. For our project we will need to define a chain resolver which will contain a series of maven based repositories from where it will download the files.

 

 

<ivysettings>
    <settings defaultResolver="chain-example" />
    <resolvers>
        <chain name="chain-example">
            <ibiblio name="ibiblio" m2compatible="true" />
            <ibiblio name="Jboss" m2compatible="true" root="http://repository.jboss.org/nexus/content/groups/public-jboss/" pattern="[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
            <ibiblio name="JSF" m2compatible="true" root="http://download.java.net/maven/2/" />
            <ibiblio name="java.net" m2compatible="true" root="http://repository.codehaus.org/" />
        </chain>
    </resolvers>
    <modules>
        <module organisation="javax.servlet" name="jstl" resolver="ibiblio" />
    </modules>
</ivysettings>

 

In the second line we have specified the resolver that will be the default one (in this case chain-example); chain-example is a resolver which specifies a series of resolvers to look for your dependencies. In our case we have defined all our resolvers to be ibiblio based with maven 2 compatibility mode (m2compatible parameter).

 

The first ibiblio line is the default ibiblio resolver for ivy which points to the official maven 2 repository. The second one is the one that we are more interested in. It is the Jboss public repository which contains the RichFaces arctifacts as well as the BOM. Eventhough Ivy was not developed with Maven in mind, it integrates very well with maven repositories. Having this will tell Ivy to look for the RichFaces dependency in the all of those resolvers. After ivy finds the RichFaces arctifacfs in the Jboss repository, it will also look for the BOM which defines dependencies for RichFaces itself needed at runtime, and it will retrieve them as well.

 

Integrating Ivy with ANT

 

Everything is ready to integrate our ivy configuration with our build script. The first thing to do is to set ANT to use ivy as a dependency resolver by defining the ivy namespace in your project's build script, then you can create a task that will execute ivy's retrieve command.

 

Take a look at the following snippet and use it as a base for you build.xml file.

 

 

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="IvyTestProject" default="run" basedir=".">
    ...
    <property name="ivy.lib.dir" value="WebContent/WEB-INF/lib/"/>

    <target name="retrieve">
         <ivy:retrieve />
    </target> 

    <target name="run" depends="retrieve">
          ...
          <!-- do your stuff here -->       
          ...
    </target>
    ...
</project>

 

Notice three things. First, we defined the ivy namespace in the <project> tag. Second, we defined an Ivy property which will tell Ivy where to put the retreived dependencies (in this case inside /WebContent/WEB-INF/lib/ ). And third, we have created a retrieve task that executes the Ivy retrieve command.

 

Now you can define your default task to be dependant of the retrieve task so everytime you build your application, ivy looks for your dependencies, and if they are not present, It will download them for you.