Integrating CruiseControl With WebLogic Workshop Applications
Pages: 1, 2, 3

The Workshop Build Process

The next step in setting up the build process (this is similar for nightly/weekly/continuous builds) is to be able to compile the Workshop application using Ant, from the command line. Workshop provides a handy Ant task called wlwBuild; even better, Workshop will create a simple Ant script for you that will give you a good place to start. In Workshop, from the Tools menu choose Application Properties. In the presented dialog, select the Build node and click on the Export to Ant file button on the right. Workshop will save the Ant file in the application directory, called exported_build.xml, which is typically renamed to build.xml. The resulting script will call the wlwBuild Ant task and reference (in our example) the project's MikesProject.work file when compiling.

This script will need some editing to make it work in more places than on your desktop. By default it will contain hard-coded paths to where the application resides on your workstation. Workshop will generate two property tags with hard-coded paths with the names app.local.directory and project.local.directory. By default Ant uses the project directory (actually the directory where the build.xml file lives) as its working directory, and sets the ${basedir} variable accordingly . Therefore, the two tags should be changed to relative paths:

<property name="app.local.directory" value="${basedir}/../" />

<property name="project.local.directory" value="${basedir}" />

Because our workstations are Windows-based and our build server is running HP-UX, we've added two files to the project, Windows 2000.build.properties and HPUX.build.properties. These two files contain two property name/value pairs referencing the BEA install directory and the WebLogic install directory. The second line in the Ant script then looks like:

<property file="${os.name}.build.properties"/>

and Ant will load the appropriate file and properties. You'll have to be disciplined when creating the Ant file to make sure all references to WebLogic-related paths use the properties in the property files.

Once you've created the Ant script, you'll want to test it from the command line on your workstation. For example, since WebLogic is installed on C:\bea\weblogic81 on my workstation, the command from a Windows command prompt will look like:

C:\MikesProject>\bea\weblogic81\server\bin\ant -f build.xml build

A word of caution here: Even though Workshop allows you to run the Ant script through the Workshop IDE, don't rely on this as your test. Running in a command-line environment is sufficiently different from compiling from Workshop; I've spent many hours trying to sort out what magic Workshop is performing to successfully compile the same application that won't compile from the command line.

Once the application compiles from your workstation, check it into your source control system. On your build system, check out the entire application, and try to compile it from the command line. This may seem tedious, but it will prevent grief further down the road.

Interpreting Compiler Output

You may have noticed that a typical Workshop application uses many different tools to compile an application, each of which has its own output format. This is the crux of the matter when trying to integrate CruiseControl with Workshop applications. CruiseControl determines the success of the build by the return value ( $?, for the Unix-savvy) of the command, where 0 indicates success and all else is a failure. That's great, but a developer needs more information than the return value if a build fails. CruiseControl can interpret the output of the normal Java compiler (javac and javelin), but it doesn't know how to interpret the EJB/RMI/JSP compiler output. So we have to teach it how to do this. The first step is to translate the compiler output (or build log) into a simple XML file that looks something like this:

<?xml version="1.0" encoding="UTF-8"?>

<build error="error message text but only if build failed" 

      time="1 hour 40 minutes 23 seconds">

   <target name="ignored" time="ignored">

      <task location="ignored" name="javac" time="ignored">

         <message priority="warn">

            <![CDATA[preformatted compiler warning messages]]>

         </message>

         <message priority="error">

            <![CDATA[preformatted compiler error messages]]>

         </message>

      </task>

      <task location="ignored" name="jar" time="ignored">

         <message priority="info">

            <![CDATA[message w/name of jar or war file]]>

         </message>

      </task>

   </target>

</build>

The way to create this file is to capture the build output in a file ( build.log), and then run a custom Ant task to convert that output to an XML file with the above format, resulting in the build.log.xml file referenced by the <log/> stanza in CruiseControl's config.xml file. See Listing 1 for how this output file is referenced. CruiseControl will merge the build.log.xml file with any other output it may have gathered, including JUnit test results and deployment output.

The Ant task (available in the accompanying download as WlwBuildToXml.java) is the result of trial and error, catching various errors and writing code to capture them. It was originally based on the Text2Xml Ant task. The code is by no means pretty (at least not the bits I've added), but it is functional. The 80/20 (or 90/10) rule applies here. This Ant task catches about 90 percent of compilation errors, enough to keep us happy. The other 10 percent occurs so infrequently that it was much easier to peruse the build log than try to write code to catch and properly report these errors.

Compile the Ant task by using the following command line, assuming that your WebLogic installation is in C:\bea\weblogic81:

javac -classpath "C:\bea\weblogic81\server\lib\ant.jar" WlwBuildToXml.java

Then create a JAR of the class:

jar cf WlwBuildToXml.jar WlwBuildToXml.class

The following section shows to use this new Ant task.

The CruiseControl Masterbuild Script

We can now create a master Ant script (called masterbuild.xml in this example) that CruiseControl will use to run a build. At first glance it may seem odd to use two build scripts, but this has the advantage of separating the application-specific build logic, including the wlwBuild task, and CruiseControl's specific information, such as how to interpret the build output. Your mileage may vary.

By default Ant only sends the build output to stdout. The WlwBuildToXml Ant task can only process a log file, but the <record/> Ant task will save all output to a logfile.

Ant is written in Java, and a failure is treated like a Java exception. If an Ant task throws an exception, the exception is passed back to the caller, and subsequent tasks are skipped. That behavior needs to be tweaked, since Ant needs to invoke the custom task regardless of what happens in the wlwBuild task, and only then pass along any exceptions that may have occurred. Thankfully, the kind folks who put together the Ant-Contrib Tasks foresaw this need and include a <trycatch/> task. The resulting build file is below, with the important bits within the <finally/> task.

<project name="masterbuild" default="BuildMikesProject" basedir=".">

   <property name="MikesProject.home" value="${basedir}/checkout/MikesProject"/>

   <property name="MikesProject.build.log" value="${MikesProject.home}/build.log"/>



   <!-- our custom wlwBuild output to xml class -->

   <taskdef name="wlwBuild2xml" classname="WlwBuildToXml">

      <classpath>

         <pathelement location="WlwBuildToXml.jar"/>

      </classpath>

   </taskdef>





   <!-- Ant contributed tasks from http://ant-contrib.sourceforge.net/-->

   <taskdef resource="net/sf/antcontrib/antcontrib.properties">

      <classpath>

         <pathelement location="ant-contrib.jar"/>

      </classpath>

   </taskdef>

   <target name="BuildMikesProject">

      <trycatch>

         <try>

            <!-- record stdout to a logfile -->

            <record name="${MikesProject.build.log}" action="start" loglevel="info"/>

            <ant dir="${MikesProject.home}" antfile="build.xml" inheritAll="false"/>

         </try>

         <!--ignore all exceptions, they'll get passed back after 

            the /finally completes -->

         <finally>

            <!-- stop recording -->

            <record name="${MikesProject.build.log}" action="stop"/>

            <!-- run custom task to convert to xml file for CC -->

            <wlwBuild2xml srcfile="${MikesProject.build.log}" 

               destfile="${MikesProject.build.log}.xml"/>

         </finally>





      </trycatch>

      <!-- here's a good place to tag CVS if you want to. 

                  Ant will only get here if the build was successful. -->

   </target>

</project>

Once this file is created, test this file on your build server using Ant with the target being BuildMikesProject.

Pages: 1, 2, 3

Next Page ยป