By this point in this Chapter, you should be able to successfully invoke the basic build commands: freshStart, quickStart, and all.junit under normal conditions. This section explains what is happening "under the hood" when building Hackystat with its basic target: freshStart. Understanding the sequence of actions performed to build Hackystat is important for diagnosing and repairing errors when the build fails, and for designing your own modules to integrate with the Hackystat Build System.
Let's begin by reviewing the 12 primary subtargets of a freshStart as indicated by running "ant -q freshStart":
c:\svn\hackyCore_Build>ant -q freshStart
[echo] (17:00:53) Completed hackyCore_Build.checkModuleAvailability
[echo] (17:00:53) Completed hackyCore_Build.hotUndeployHackystat
[echo] (17:01:00) Completed hackyCore_Build.clean
[echo] (17:01:07) Completed all.checkstyle
[echo] (17:01:17) Completed all.compile
[echo] (17:01:23) Completed all.install.pre-sensorshell
[echo] (17:01:40) Completed hackyCore_Build.unjarSensorShellFiles
[echo] (17:01:42) Completed hackyCore_Build.installSensorShell
[echo] (17:02:08) Completed all.install.post-sensorshell
[echo] (17:02:08) Completed hackyCore_Build.deployTestData
[echo] (17:02:09) Completed hackyCore_Build.hotDeployHackystat
[echo] (17:02:11) Completed hackyCore_Build.deploySoap
BUILD SUCCESSFUL
Total time: 1 minute 21 seconds
The following subsections explains each of these targets. Each subsection begins with an excerpt from running freshStart without the -q option, which reveals additional targets and output useful in understanding the underlying process of the build.
Note that the following example is based upon a hackystat.build.properties in which only the hackyCore_* modules are indicated as available, as illustrated by Example 13.1, “hackystat.build.properties file (builds hackyCore subsystem only)”.
hackyCore_Build.warnAboutModulesFile:
checkProperties:
hackyCore_Build.checkModuleAvailability:
[echo] (17:22:51) Completed hackyCore_Build.checkModuleAvailability
This task checks for basic consistency in the build system. First, it checks to see the modules.build.xml file is up to date, and if not, generates the warning discussed above to rerun the AutoConfig system. Second, if a module is indicated as available in hackystat.build.properties, the module should actually exist in the file system. Third, if a module is indicated as available, then all of its "dependent" modules are also available. (Dependent modules of each module are defined in its local.build.xml file in a manner we will discuss below). For example, if you indicate that the hackyStdExt module is available, then you must also have the hackyKernel module available, because hackyStdExt depends upon this module.
hackyCore_Build.checkModuleAvailability fails the build if any modules required are not found.
hackyCore_Build.checkTomcat:
[get] Getting: http://localhost:8080//manager/list
[get] To: C:\svn\hackyCore_Build\list-results.tmp
[delete] Deleting: C:\svn\hackyCore_Build\list-results.tmp
hackyCore_Build.hotUndeployHackystat:
[echo] Pausing 0 seconds to let tomcat release file handles.
[echo] Starting hot undeploy of hackystat from tomcat.
[get] Getting: http://localhost:8080//manager/undeploy?path=/hackystat
[get] To: C:\svn\hackyCore_Build\remove-results.tmp
[echo] FAIL - No context exists for path /hackystat
[delete] Deleting: C:\svn\hackyCore_Build\remove-results.tmp
[echo] (17:22:51) Completed hackyCore_Build.hotUndeployHackystat
This task first checks to make sure that it can find a Tomcat process running at the location specified in the hackystat.site.properties file and then attempts to login to the Tomcat Manager interface using that account name and password supplied in the hackystat.site.properties file. Next, it undeploys Hackystat from that Tomcat process if there is a Hackystat application currently deployed. In this example, there was no Hackystat application already deployed, so the undeploy "failed", which is OK.
hackyCore_Build.hotUndeployHackystat fails the build if Tomcat is not running or if the Tomcat manager account and password supplied in the hackystat.site.properties file is not valid.
hackyCore_Build.clean:
[delete] Deleting directory C:\svn\hackyCore_Build\build
[echo] (17:23:10) Completed hackyCore_Build.clean
makeInstallDirs:
[mkdir] Created dir: C:\svn\hackyCore_Build\build\tmp
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\META-INF
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\doc
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\download
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\download\eclipse
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\lib
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\classes
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\changelog
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\command
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\dailyanalysis
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\sdt
[mkdir] Created dir: C:\svn\hackyCore_Build\build\war\WEB-INF\sensor
[mkdir] Created dir: C:\svn\hackyCore_Build\build\sensorshell
[mkdir] Created dir: C:\svn\hackyCore_Build\build\sensorshell\src\org\hackystat\lib\ext\sdt
[mkdir] Created dir: C:\svn\hackyCore_Build\build\testdata\users\testdataset
[mkdir] Created dir: C:\svn\hackyCore_Build\build\docbook
This task deletes the hackyCore_Build/build directory. After deleting the build directory, the directory structure is recreated.
hackyCore_Kernel.checkstyle:
[mkdir] Created dir: C:\svn\hackyCore_Build\build\reports\checkstyle
[mkdir] Created dir: C:\svn\hackyCore_Build\build\reports\checkstyle\hackyCore_Kernel
[style] Processing C:\svn\hackyCore_Build\build\reports\checkstyle\hackyCore_Kernel.xml to C:\svn\hackyCore_Build\build\reports\checkstyle\hackyCore_Kernel\index.html
[style] Loading stylesheet C:\apache-ant-1.6.5\etc\checkstyle-noframes.xsl
[hacky-checkstyle] Sensor enabled?: true
[hacky-checkstyle] Processing file: C:\svn\hackyCore_Build\build\reports\checkstyle\hackyCore_Kernel.xml
[hacky-checkstyle] Failed to send Hackystat Code Issue data. See log for details.
:
[60 or so additional <module>.checkstyle targets deleted]
:
hackySensor_Locc.checkstyle:
hackySensor_Cvs.checkstyle:
all.checkstyle:
[echo] (17:23:18) Completed all.checkstyle
The previous targets were named with the prefix "hackyCore_Build.", indicating that they were implemented using build code within the hackyCore_Build module. This target is named "all.checkstyle", which indicates that this target effectively represents a collection of targets from all of the modules in the system.
When a target is named with the prefix "all.", it indicates that there exists a set of module-specific versions of this target. So, "all.checkstyle" indicates that there exists a hackyCore_Build.checkstyle target, hackyCore_Kernel.checkstyle target, and so forth: one for each module discovered by AutoConfig. When you invoke an "all." target, you are effectively invoking all of the module-specific versions of this target that have been indicated as available in the hackystat.build.properties file.
As you can see from the abbreviated output, invoking all.checkstyle resulted in the invocation of 65 checkstyle "subtargets": one for each module in the system. However, only those defined as available in hackystat.build.properties (such as hackyCore_Kernel.checkstyle) were actually executed; those not available (such as hackySensor_CVS.checkstyle) were not.
Checkstyle is a source code format checking system. We use it to ensure that basic formatting conventions are followed by all Hackystat developers. The conventions include two space indentation, the use of JavaDocs, consistent spacing between operators, placement of curly braces, and so forth. Our Checkstyle definition file is located in hackyCore_Build/lib/checkstyle for your reference. Typically, the error messages printed by Checkstyle are sufficient to indicate how to fix a formatting violation.
The target all.checkstyle fails the build if any source code formatting violations are found.
hackyCore_Build.initializeHackystatDataDir:
[echo] Deleting c:\public_hackystat\hackystatdataTMP/users/test* directories.
[delete] Deleting directory C:\public_hackystat\hackystatdataTMP\users\testdataset
[delete] Deleting directory C:\public_hackystat\hackystatdataTMP\users\testprojectdataset
hackyCore_Build.initializeTestData:
[delete] Deleting directory C:\svn\hackyCore_Build\build\testdata
[mkdir] Created dir: C:\svn\hackyCore_Build\build\testdata
[copy] Copying 1 file to C:\svn\hackyCore_Build\build\testdata\users\testdataset
Hackystat provides a testing framework (to be documented in a Developer Guide chapter Real Soon Now) which simplifies the testing of new modules. As part of this framework, module developers can define directories containing test data for various "test" users (such as a Hackystat user account called "testdataset").
The hackyCore_Build.initializeTestData target is responsible for setting up several default test data accounts.
hackyCore_Build.compile:
hackyCore_Kernel.compile:
[copy] Copying 11 files to C:\svn\hackyCore_Build\build\war\WEB-INF\lib
[hackyCore_Build.javac] Compiling 113 source files to C:\svn\hackyCore_Build\build\war\WEB-INF\classes
hackyCore_Statistics.compile:
[hackyCore_Build.javac] Compiling 10 source files to C:\svn\hackyCore_Build\build\war\WEB-INF\classes
:
[60 or so additional <module>.compile targets deleted]
:
hackySensor_Locc.compile:
hackySensor_Cvs.compile:
all.compile:
[echo] (17:23:27) Completed all.compile
Like all of the "all." targets, the all.compile target is a target that invokes module-specific versions, of which only the available ones will actually execute. In this case, the available module-specific "compile" targets might do nothing when there is no Java code to compile (as is the case with hackyCore_Build). If there is Java code, they compile it into the build/war/WEB-INF/classes directory. Finally, if a module contains any third party libraries that are needed by the web application at run time, they are copied into the build/war/WEB-INF/lib directory.
The all.compile target will fail if any of the modules fail to compile successfully.
hackyCore_Build.install.pre-sensorshell:
[copy] Copying 1 file to C:\svn\hackyCore_Build\build\war\WEB-INF\lib
hackyCore_Kernel.install.pre-sensorshell:
[copy] Copying 52 files to C:\svn\hackyCore_Build\build\war
[copy] Copying 1 file to C:\svn\hackyCore_Build\build\war\WEB-INF\sdt
[copy] Copying 1 file to C:\svn\hackyCore_Build\build\sensorshell\src\org\hackystat\lib\ext\sdt
[copy] Copying 3 files to C:\svn\hackyCore_Build\build\war\WEB-INF\classes
[copy] Copying 8 files to C:\svn\hackyCore_Build\build\sensorshell
hackySensor_Cvs.install.pre-sensorshell:
:
[60 or so additional <module>.install.pre-sensorshell targets deleted]
:
all.install.pre-sensorshell:
[echo] (17:23:33) Completed all.install.pre-sensorshell
One of the products of the build is a file called "sensorshell.jar", which is a kind of "middleware" system that is used by sensors on the client-side to collect and send sensor data type instances to the server. Some modules (such as sensor data type defining modules) need to copy files to certain build directories for inclusion in the construction of the sensorshell.jar file. Such actions can be performed in the implementation of a target called <module>.install.presensorshell, which the build system will invoke over all available modules prior to construction of the sensorshell.jar file.
In the example above, the hackyCore_Kernel.install.pre-sensorshell target copies a variety of files over to various build directories in advance of the creation of the sensorshell.jar file.
hackyCore_Build.updateSensorShellClasses:
[copy] Copying 668 files to C:\svn\hackyCore_Build\build\sensorshell\src
hackyCore_Build.checkSensorShellJarFilesUnpacked:
hackyCore_Build.unjarSensorShellFiles:
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\Tidy.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\activation.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\concurrent.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\httpunit.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\jdom.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\mail.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\soap.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[unjar] Expanding: C:\svn\hackyCore_Build\build\sensorshell\xml-apis.jar into C:\svn\hackyCore_Build\build\sensorshell\src
[echo] (17:23:51) Completed hackyCore_Build.unjarSensorShellFiles
Once each of the individual modules has had a chance to update build directories with files related to sensorshell via the previous target (all.install.pre-sensorshell), the construction of the sensorshell.jar file begins. This target uncompresses various third-party libraries that need to be included in sensorshell.jar into a common directory.
Note that this target is typically time-consuming during the build, and thus operates differently in the case of freshStart and quickStart. In the case of freshStart, the unjarring of libraries occurs every time (since the build directory has been deleted); in the case of quickStart, the unjarring does not occur unless changes have been made to the jar files.
hackyCore_Build.checkSensorShellJarUpToDate:
hackyCore_Build.installSensorShell:
[echo] Creating sensorshell.jar.
[jar] Building jar: C:\svn\hackyCore_Build\build\war\download\sensorshell.jar
[echo] (17:23:53) Completed hackyCore_Build.installSensorShell
This target creates the sensorshell.jar file. Like the previous target, it will always perform the jar operation for a freshStart; in the case of a quickStart, it will only perform the jar operation if a change has been made to the files contained within it.
hackyCore_Build.install.post-sensorshell:
hackyCore_Kernel.install.post-sensorshell:
hackyCore_Statistics.install.post-sensorshell:
hackyCore_Installer.unjarFiles:
[unjar] Expanding: C:\svn\hackyCore_Installer\lib\jar\forms-1.0.5.jar into C:\svn\hackyCore_Build\build\installer\classes
[unjar] Expanding: C:\svn\hackyCore_Installer\lib\jar\looks-1.3.1.jar into C:\svn\hackyCore_Build\build\installer\classes
[unjar] Expanding: C:\svn\hackyCore_Installer\lib\jar\xerces.jar into C:\svn\hackyCore_Build\build\installer\classes
[unjar] Expanding: C:\svn\hackyCore_Build\build\war\WEB-INF\lib\httpunit.jar into C:\svn\hackyCore_Build\build\installer\classes
hackyCore_Installer.install.post-sensorshell:
[copy] Copying 1604 files to C:\svn\hackyCore_Build\build\installer\classes
[jar] Building jar: C:\svn\hackyCore_Build\build\war\download\hackyInstaller.jar
:
[60 or so additional <module>.install.post-sensorshell targets deleted]
:
hackySensor_Cvs.install.post-sensorshell:
all.install.post-sensorshell:
[echo] (17:24:18) Completed all.install.post-sensorshell
The all.install.post-sensorshell target runs all of the <module>.install.post-sensorshell targets from the available modules. The motivation for this target is to allow modules that need access to the completed sensorshell.jar file to have an access point during the build to this file.
Most modules do not need access to sensorshell.jar as part of their build activity; the exceptions are sensor-oriented modules that need to explicitly incorporate sensorshell.jar into their package. The module hackyCore_Installer is an example of such a module, as illustrated above.
hackyCore_Build.deployTestData:
[copy] Copying 3 files to C:\public_hackystat\hackystatdataTMP\users
[echo] (17:24:18) Completed hackyCore_Build.deployTestData
As part of the <module>.install.pre-sensorshell task, each module has copied any test data that it needs for correct execution of its unit tests to a directory in the build/ area. This task is responsible for deploying the complete set of test data to the current hackystat test data directory as indicated in the hackystat.site.properties file.
hackyCore_Build.setupTomcatConf:
hackyCore_Build.hotDeployHackystat:
[echo] Installing hackystat web app to tomcat.
[get] Getting: http://localhost:8080/manager/deploy?path=/hackystat&config=file://C:\svn\hackyCore_Build/hackystat.xml&war=
[get] To: C:\svn\hackyCore_Build\install-results.tmp
[echo] Install results: OK - Deployed application from context file file://C:\svn\hackyCore_Build/hackystat.xml
[delete] Deleting: C:\svn\hackyCore_Build\install-results.tmp
[echo] (17:24:19) Completed hackyCore_Build.hotDeployHackystat
[delete] Deleting: C:\svn\hackyCore_Build\hackystat.xml
This task takes the completed hackystat web application in the hackyCore_Build/build/war directory and deploys it to the running Tomcat instance.
hackyCore_Build.deploySoap:
[echo] Deploying soap services.
[java] Deployed Services:
[java] urn:hackystat.SoapNotification
[echo] (17:24:21) Completed hackyCore_Build.deploySoap
The final target in a freshStart is hackyCore_Build.deploySoap, which sets up the Hackystat web application to support receipt of sensor data via the Soap protocol.