Building the Apache Tuscany SCA source distribution
===================================================

Initial Setup
-------------

1) Install J2SE 6.x JDK, which can be downloaded from 
   http://java.sun.com/javase/downloads/index.jsp. 

2) Make sure that your JAVA_HOME environment variable is set to the newly installed 
   JDK location, and that your PATH includes %JAVA_HOME%\bin (windows) or 
   $JAVA_HOME/bin (unix).

3) Install Maven 2.0.7 or higher (2.2.1 recommended), which can be downloaded from 
   http://maven.apache.org/download.html. Make sure that your PATH includes 
   the MVN_HOME/bin directory. 

4) Make sure that your MAVEN_OPTS environment variable has -Xmx128M (or more),
   you can manually do this by executing the following in your prompt :
   Windows users:
      set MAVEN_OPTS=-Xmx128M
   Unix users:
      export MAVEN_OPTS=-Xmx128M


Building
--------

1) Change to the top level directory of Apache Tuscany source distribution.
2) Run

      $> mvn

   This will compile Apache Tuscany and run all of the tests in the source
   distribution. 

   Depending on the load of remote Maven 2.0 repositories, you may have 
   to run "mvn" several times utill the required dependencies are 
   all located in your local maven repository. It usually takes some time for 
   maven to download required dependencies in the first build. Once all the 
   dependencies have been downloaded you may use the -o option to run maven
   in offline mode, for example, 'mvn clean install -o'.


