Working Example

This topic contains a working example for setting up a build server.

In a working environment, changes will be necessary to tailor this example to the actual application, release, and version control system (VCS). The following would be changed to reflect the requirements for a specific project:

The following directory structure is assumed:

Untitled: image13

where

BuildServer contains the build server files.

spl - contains the appserver installation.

SPLSDK - contains the SDK installation.

The corresponding Perforce structure is as follows:

Untitled: image14

It is assumed that the test source files are in C:\svn\CCB_​240_​101\java\source\cm\test and the test properties file are in C:\svn\CCB_​240_​101\java\source\cm\test\properties.

Steps to perform:

  1. Download CruiseControl 2.5 and extract to C:\BuildServer directory

  2. Download Maven 1.0.2 and extract to C:\BuildServer directory

  3. Create a directory for the reporting application in the C:\BuildServer\project_​web_​site

  4. Download Tomcat 4 and extract into the C:\BuildServer\project_​web_​site directory

  5. Download Java 2 SDK and extract into the C:\BuildServer\project_​web_​site directory

  6. Copy the reporting app from C:\BuildServer\cruisecontrol-2.5\webapps\cruisecontrol to the C:\BuildServer\project_​web_​site\project_​content

  7. In the C:\BuildServer\maven-1.0.2\bin directory, create a batch file that will launch Maven called cmMaven.bat with the following contents:

    set PATH=C:\spl\CCB_​205_​101\runtime;%PATH%
    set COBSW=(+S5)
    set MAVEN_​HOME=C:\BuildServer\maven-1.0.2
    set BUILD_​DIR=C:\spl\CCB_​205_​101\build
    cd /d %BUILD_​DIR%
    call %MAVEN_​HOME%\bin\maven.bat %*
    
  8. In the C:\BuildServer\ cruisecontrol-2.5 directory, create a batch file that will launch CruiseControl called cmCruiseControl.bat with the following contents:

    SET JAVA_​HOME=C:\Program Files\Java\jdk1.5.0_​10
    cd /d C:\BuildServer\cruisecontrol-2.5
    call cruisecontrol.bat -projectname cmbuild -configfile config.xml
    
  9. Create a file called C:\BuildServer\ cruisecontrol-2.5\config.xml with the following contents:

    <cruisecontrol>
       <system>
          <configuration>
             <threads count="1"/>
          </configuration>
       </system>
       <project name="cmbuild">
          <listeners>
             <currentbuildstatuslistener file="logs/cmbuild/status.txt"/>
          </listeners>
          <bootstrappers>
             <P4Bootstrapper p4port="SF-PDNT-006:1686" client="CMClientSpec" p4user="fjocson" path="//SDK/..." />
          </bootstrappers>
          <modificationset requiremodification="true">
             <!-- trigger a build for any code change -->
             <P4 port="SF-PDNT-006:1686" client="CMClientSpec" user="fjocson" view="//SDK/..." />
          </modificationset>
          <schedule interval="240">
            <!-- Schedule the regular build -->
            <maven mavenscript="C:/BuildServer/maven-1.0.2/bin/cmMaven.bat" 
                  projectfile="C:/BuildServer/maven-1.0.2/bin/project.xml"
                  goal="cmBuild"
                  multiple="1" />
          </schedule>
          <log encoding="UTF-8">
             <merge dir="c:/spl/CCB_​205_​101/build/cm/target/test-reports" /> 
          </log>
          <publishers>
             <email mailhost="sf-smtp1.splwg.com"
                    returnname="CM Project Build Server"
                    returnaddress="CMBuildServer@splwg.com"
                    defaultsuffix="@splwg.com"
                    buildresultsurl="http://localhost:20230/index.jsp">
                <!--always address="buildmasters" /-->
                <!--failure address="developers" reportWhenFixed="true" /-->
                <failure address="buildmasters" reportWhenFixed="true" />
                <map alias="buildmasters" address="fjocson@splwg.com" />
                <!-- Map perforce usernames to email names -->
                <map alias="fjocson" address="fjocson@splwg.com" />
            </email>
          </publishers>
       </project>
    </cruisecontrol>
    
  10. Modify the file C:\BuildServer\project_​web_​site\tomcatBase\conf\server.xml to add the line:

    <Context path="" docBase="C:\BuildServer\project_​web_​site\project_​content" debug="0"/>
    
  11. Modify the file C:\BuildServer\project_​web_​site\project_​content\WEB-INF\web.xml to add the lines:

    <param-name>logDir</param-name>
    <param-value>logs</param-value>
    

    to

    <param-name>logDir</param-name>
    <param-value>C:/BuildServer/CruiseControl-2.5/logs</param-value>
    
  12. Create a file called C:\spl\CCB_​205_​101\build\project.xml with the following contents:

    <?xml version="1.0"?>
    <project>
      <name>CM Dev</name>
      <groupId>cm</groupId>
      <id>cm</id>
      <currentVersion>SNAPSHOT</currentVersion>
      <package>com.splwg.cm</package>
    
      <shortDescription>CM Java Development</shortDescription>
      <description>CM Java Development</description>
    
      <dependencies>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>spl-ccb</artifactId>
          <jar>spl-ccb-2.0.5.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>spl-shared</artifactId>
          <jar>spl-shared-2.0.10.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>spl-base</artifactId>
          <jar>spl-base-2.0.10.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>spl-charter</artifactId>
          <jar>spl-charter-2.0.10.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>commons-lang</artifactId>
          <jar>commons-lang-2.1.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>hibernate</artifactId>
          <jar>hibernate-3.0.5.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>log4j</artifactId>
          <jar>log4j-1.2.11.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>picocontainer</artifactId>
          <jar>picocontainer-1.1.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>dom4j</artifactId>
          <jar>dom4j-1.6.1.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>commons-collections</artifactId>
          <jar>commons-collections-2.1.1.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>xstream</artifactId>
          <jar>xstream-1.1.2.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>cglib</artifactId>
          <jar>cglib-2.1.3.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>asm-attrs</artifactId>
          <jar>asm-attrs-1.5.3.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>asm</artifactId>
          <jar>asm-1.5.3.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>icu4j</artifactId>
          <jar>icu4j-3.4.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>commons-logging</artifactId>
          <jar>commons-logging-1.0.4.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>c3p0</artifactId>
          <jar>c3p0-0.9.0.4.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>ehcache</artifactId>
          <jar>ehcache-1.1.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>commons-beanutils</artifactId>
          <jar>commons-beanutils-1.6.1.jar</jar>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>concurrent</artifactId>
          <version>1.3.4</version>
        </dependency>
        <dependency>
          <groupId>cm-dep</groupId>
          <artifactId>commons-httpclient</artifactId>
          <jar>commons-httpclient-2.0.2.jar</jar>
        </dependency>
      </dependencies>
    
      <build>
    
        <sourceDirectory>
           ${build.dir}/source/java
        </sourceDirectory>
    
        <unitTestSourceDirectory>
           ${build.dir}/source/test
        </unitTestSourceDirectory>
    
        <resources>
          <resource>
            <directory>${build.dir}/source/java/com/splwg/cm/domain</directory>
            <targetPath>com/splwg/cm/domain</targetPath>
            <includes>
              <include>**/contextManagedObjects.xml</include>
            </includes>
          </resource>
          <resource>
            <directory>${spl.build.root.dir}/source/java/com/splwg/cm/domain</directory>
            <targetPath>com/splwg/cm/domain</targetPath>
            <includes>
              <include>**/packageMetaInfo.xml</include>
            </includes>
          </resource>
          <resource>
            <directory>${spl.build.root.dir}/source/java/com/splwg/cm/cobol</directory>
            <targetPath>com/splwg/cm/cobol</targetPath>
            <includes>
              <include>**/packageMetaInfo.xml</include>
            </includes>
          </resource>
          <resource>
            <directory>${spl.build.root.dir}/source/java/com/splwg</directory>
            <targetPath>com/splwg</targetPath>
            <includes>
              <include>**/*.hbm.xml</include>
            </includes>
          </resource>
          <resource>
            <directory>${spl.build.root.dir}/source/java/com/splwg</directory>
            <targetPath>com/splwg</targetPath>
            <includes>
              <include>**/*.info.xml</include>
            </includes>
          </resource>
          <!-- service mapping files -->
          <resource>
            <directory>${spl.build.root.dir}/source/java/services</directory>
            <targetPath>services</targetPath>
            <includes>
              <include>**/*.xml</include>
            </includes>
          </resource>
          <resource>
            <directory>${build.dir}/source/java/cobolServices</directory>
            <targetPath>cobolServices</targetPath>
            <includes>
              <include>*.xml</include>
            </includes>
          </resource>
          <resource>  
            <directory>${build.dir}/source/java/com/splwg/cm</directory>
            <targetPath>com/splwg/cm</targetPath>
            <includes>
               <include>dbregex.txt</include>
            </includes>
          </resource>
        </resources>
    
        <unitTest> 
    
          <includes>
            <include>com/splwg/AllTests.java</include>
          </includes>
    
          <resources>
            <resource>
              <directory>${build.dir}/source/test/com/splwg/cm/domain</directory>
              <targetPath>com/splwg/cm/domain</targetPath>
              <includes>
                <include>**/contextManagedObjects.xml</include>
              </includes>
            </resource>
          <resource>
            <directory>${build.dir}/source/test/com/splwg/cm/domain</directory>
            <targetPath>com/splwg/cm/domain</targetPath>
            <includes>
              <include>**/packageMetaInfo.xml</include>
            </includes>
          </resource>
          <resource>
            <directory>${build.dir}/source/test/com/splwg/cm/cobol</directory>
            <targetPath>com/splwg/cm/cobol</targetPath>
            <includes>
              <include>**/packageMetaInfo.xml</include>
            </includes>
          </resource>
           <resource>
              <directory>${build.dir}/source/test/com/splwg</directory>
              <targetPath>com/splwg</targetPath>
              <includes>
                <include>**/*.hbm.xml</include>
              </includes>
            </resource>
            <resource>
              <directory>${build.dir}/source/test/com/splwg</directory>
              <targetPath>com/splwg</targetPath>
              <includes>
                <include>**/*.info.xml</include>
              </includes>
            </resource>
            <!-- service mapping files -->
            <resource>
              <directory>${build.dir}/source/test/com/splwg/cm/services</directory>
              <targetPath>services</targetPath>
              <includes>
                <include>**/*.xml</include>
              </includes>
            </resource>
            <resource>
              <directory>${build.dir}/source/test/cobolServices</directory>
              <targetPath>cobolServices</targetPath>
              <includes>
                <include>*.xml</include>
              </includes>
            </resource>
            <resource>  
              <directory>${build.dir}/TestProperties</directory>
              <includes>
                <include>hibernate.properties</include>
                <include>log4j.properties</include>
              </includes>
            </resource>   
          </resources>
        </unitTest>
      </build>
    </project>
    
  13. Create a file called C:\spl\CCB_​205_​101\build\maven.xml with the following contents:

    <project
      default="reactor-exec"
      xmlns:ant="jelly:ant"
      xmlns:j="jelly:core"
      xmlns:u="jelly:util"
      xmlns:maven="jelly:maven">
    
      <goal name="cmBuild">
        <echo message="Copying source files to build location for CM project"/>
        <attainGoal name="refresh-build-dir" />
    
        <!-- Generate and compile -->
        <attainGoal name="cmGenerate" />
        <attainGoal name="jar:jar" />
        <copy todir="${build.dir}/repository/cm/jars" >
           <fileset dir="${build.dir}/target">
              <include name="*.jar"/>
           </fileset>
        </copy>
    
        <!--Copy files for appserver refresh -->
        <attainGoal name="save-files" />
      </goal>
    
      <goal name="refresh-build-dir">
          <echo message="Refreshing build directory for project CM" />
          <echo message="Source root directory is ${java.source.dir}" />
    
        <delete dir="${build.dir}/source"  />
        <delete dir="${build.dir}/target"  />
        <!-- Copy over the "java" directories -->
        <copy todir="${build.dir}/source/java" >
           <fileset dir="${java.source.dir}" />
        </copy>
        <!-- Copy over the "test" directories -->
        <copy todir="${build.dir}/source/test" failonerror="false" >
           <fileset dir="${java.source.dir}/test" />
        </copy>  
        <!-- Copy over the properties -->
        <copy todir="${build.dir}/properties"
            file="${web.root.dir}/WEB-INF/classes/hibernate.properties" overwrite="true" failonerror="false" />
        <copy todir="${build.dir}/properties"
            file="${web.root.dir}/WEB-INF/classes/log4j.properties" overwrite="true" failonerror="false" />
        <copy todir="${build.dir}/properties"
            file="${web.root.dir}/WEB-INF/classes/spl.properties" overwrite="true" failonerror="false" />
        <!-- Copy over the Test properties -->
        <!-- Copy over the Test properties -->
        <copy todir="${build.dir}/TestProperties"
    	  file="${java.source.dir}/test/properties/hibernate.properties" overwrite="true" failonerror="false" />
        <copy todir="${build.dir}/TestProperties"
            file="${java.source.dir}/test/properties/log4j.properties" overwrite="true" failonerror="false" />
        <copy todir="${build.dir}/TestProperties"
            file="${java.source.dir}/test/properties/spl.properties" overwrite="true" failonerror="false" />
        <!-- Refresh the Cobol Runtime files -->
        <delete dir="${build.dir}/runtime"/>
        <copy todir="${build.dir}/runtime" preservelastmodified="true" >
    
    	     <fileset dir="${dev.root.dir}/runtime ">
            		<include name="cm*.dll"/>
            		<include name="CM*.dll"/>
            </fileset>
    
        </copy>
      </goal>
    
      <goal name="cmGenerate">
        <!-- Generate the classes -->
      	<property name="generated.artifact.dir" 
      		 value="${build.dir}/source/java"/>
      		 <echo message="Generated artifact directory is ${generated.artifact.dir}" />
    
    
      	<java classname="com.splwg.tools.artifactgen.ArtifactGenerator" fork="true" failonerror="true" maxmemory="512m">
    		 <arg line="-appDirs ${generated.artifact.dir} -appJars ${build.dir}/repository/cm-dep/jars/spl-base-2.0.10.jar ${build.dir}/repository/cm-dep/jars/spl-ccb-2.0.5.jar" /> 
      		 <classpath>
               <pathelement path="${build.dir}/properties" />
               <fileset dir="${build.dir}/repository/cm-dep/jars">
                  <include name="*.jar"/>
               </fileset>
               <fileset dir="${dev.root.dir}/SPLSDKCommon/tools">
                  <include name="*.jar"/>
               </fileset>
             </classpath>
             <sysproperty key="spl.tools.artifact.manual.sourcedir"     value="${generated.artifact.dir}"/>
             <sysproperty key="spl.tools.artifact.cobol.sourcedir" value="${dev.root.dir}/cobol/source"/>
             <sysproperty key="spl.tools.artifact.generated.sourcedir"  value="${generated.artifact.dir}"/>
             <sysproperty key="spl.tools.loaded.applications" value="base,ccb,cm"/>
             <sysproperty key="log4j.logger.com.splwg" value="info"/>        
             <sysproperty key="log4j.logger.org.hibernate.cfg" value="warn"/>        
             <sysproperty key="log4j.logger.org.hibernate.util" value="warn"/>        
             <sysproperty key="log4j.logger.com.splwg.tools.artifactgen.LookupGenerator" value="warn"/>       
             <sysproperty key="log4j.logger.com.splwg.tools.artifactgen.sourceparser.JavaSourceProcessor" value="warn"/>       
        </java>
      </goal>
    
      <goal name="save-files">
        <echo message="Deleting previous saved files..." />
        <!-- Put a marker that files are in the process of being saved -->
        <!-- so the appserver refresh won't try to refresh -->
        <copy file="${dev.root.dir}/etc/SPLVERSION.txt" tofile="${build.dir}/~saving_​files"/>
        <delete dir="${build.dir}/saved"  />
        <echo message="Saving files from successful build..." />
        <!-- Copy over the root directory -->
        <copy todir="${build.dir}/saved/root/cm">
           <fileset dir="${web.root.dir}/cm" />
        </copy>  
        <copy todir="${build.dir}/saved/lib" >
           <fileset dir="${build.dir}/repository/cm/jars" />
        </copy>
        <!-- Copy over the dlls -->
        <copy todir="${build.dir}/saved/runtime" >
           <fileset dir="${build.dir}/runtime">
                <include name="CM*.dll" />
                <include name="cm*.dll" />
           </fileset>
        </copy>
    	<delete file="${build.dir}/~saving_​files"/>
      </goal>
    </project>
    
  14. Create a properties file in the build directory called C:\spl\CCB_​205_​101\build\project.properties with the following contents:

    # The top level directories
    dev.root.dir=c:/spl/CCB_​205_​101
    build.dir=${dev.root.dir}/build
    java.source.dir=${dev.root.dir}/java/source/cm
    web.root.dir=${dev.root.dir}/splapp/applications/root
    
    ## Properties used during the build process
    maven.pmd.cpd.enable=true
    
    ## JUnit testing properties
    log4j.logger.com.splwg=info
    log4j.logger.org.hibernate.cfg=warn
    log4j.logger.org.hibernate.util=warn
    log4j.logger.com.splwg.base.context.ApplicationContextImpl=warn
    log4j.logger.com.splwg.base.context.PicoComponentContainer=warn
    maven.junit.sysproperties=spl.tools.loaded.applications log4j.logger.com.splwg log4j.logger.org.hibernate.cfg log4j.logger.org.hibernate.util log4j.logger.com.splwg.base.context.ApplicationContextImpl log4j.logger.com.splwg.base.context.PicoComponentContainer
    maven.junit.jvmargs=-Xms128m -Xmx512m -XX:MaxPermSize=512m
    
    # Define the set of applications to be loaded
    spl.tools.loaded.applications=base,ccb
    
    ## These "built-in" maven properties need to be here because the property inheritance of this type is broken in maven 1.0.1
    ## Should be fixed in 1.0.2 (hopefully).
    ##maven.repo.remote.enabled	= false
    maven.site.deploy.method    = fs
    maven.repo.local            = ${build.dir}/repository
    maven.junit.fork            = true 
    maven.jar.override = on
    
  15. Create a script to start Tomcat for the build status website by creating a file called C:\BuildServer\project_​web_​site\starttcat.bat with the following contents:

    REM This script calls the tomcat startup script in tomcathome\bin.
    
    set SITE_​BASE=C:\BuildServer\project_​web_​site
    set JAVA_​HOME=%SITE_​BASE%\j2sdk1.4.2_​11
    set JAVA_​OPTS=-Xms384m -Xmx384m
    set CATALINA_​BASE=%SITE_​BASE%\tomcatBase
    set CATALINA_​HOME=%SITE_​BASE%\tomcatHome\jakarta-tomcat-4.1.29
    
    pushd %CATALINA_​HOME%\bin
    call startup.bat
    popd
    
    :endofbat
    
  16. Create a script to stop Tomcat for the build status website by creating a file called C:\BuildServer\project_​web_​site\stoptcat.bat with the following contents:

    @REM This script calls the tomcat shutdown script in tomcathome\bin.
    
    set SITE_​BASE=C:\BuildServer\project_​web_​site
    set JAVA_​HOME=%SITE_​BASE%\j2sdk1.4.2_​11
    set JAVA_​OPTS=-Xms384m -Xmx384m
    set CATALINA_​BASE=%SITE_​BASE%\tomcatBase
    set CATALINA_​HOME=%SITE_​BASE%\tomcatHome\jakarta-tomcat-4.1.29
    
    if not exist %SITE_​BASE%\tomcatHome\jakarta-tomcat-4.1.29\bin echo Unable to find directory %SITE_​BASE%\tomcatHome\jakarta-tomcat-4.1.29\bin.&&pause&&goto endofbat
    pushd %SITE_​BASE%\tomcatHome\jakarta-tomcat-4.1.29\bin
    call shutdown.bat
    popd
    
    :endofbat
    
    
  17. Create a Perforce client spec named CMClientSpec for this example. The Root should be c:\spl and has the following view defined:

    //SDK/2.0.10/AppSvrs/CCB_​205_​101/... //CMClientSpec/CCB_​205_​101/...
  18. Start the build status website by executing the file C:\BuildServer\project_​web_​site\starttcat.bat

  19. Start CruiseControl by executing the file C:\BuildServer\ cruisecontrol-2.5\cmCruiseControl.bat. Once it completes, the console should state that is waiting for the next time to build:

    Untitled: image15

  20. Once the build finishes in the CruiseControl console, view the build status by opening a web browser to http://localhost:20230. The following status page should be displayed:

    Untitled: image16

  21. If successful, the resulting cm jar file can be found at c:\spl\CCB_​205_​101\build\target\cm-SNAPSHOT.jar.