解释编译器输出
您可能已经注意到,典型的 Workshop 应用程序使用很多不同的工具来编译应用程序,每种工具都有自己的输出格式。这是设法集成 CruiseControl 和 Workshop 应用程序时问题的关键所在。 CruiseControl 根据命令的返回值(对于 Unix-savvy ,该值是 $? )来确定构建是否成功,如果返回值为 0 ,则说明成功,如果为其他值,则说明失败。好极了!但是开发人员需要返回值以外的更多信息,如果构建失败的话。 CruiseControl 可以解释普通 Java 编译器( javac 和 javelin )的输出,但是它不知道如何解释 EJB/RMI/JSP 编译器输出。因此,我们必须教会它如何执行该操作。第一步是将编译器输出(或者构建日志)转换为简单的 XML 文件,如下所示:
<?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>
创建该文件的方法是捕获一份文件( build.log )中的构建输出,然后运行自定义 Ant 任务,将该输出转换为具有上述格式的 XML 文件,从而生成在 CruiseControl's config.xml 文件中的 <log/> 节( stanza )引用的 build.log.xml 文件。清单 1 说明了该输出文件是如何被引用的。 CruiseControl 可以将 build.log.xml 文件与它可能已经收集的其他任何输出进行合并,这些输出中包括 JUnit 测试结果和部署输出。
Ant 任务(在附带的下载中作为 WlwBuildToXml.java 提供)是反复试验的结果,其可以捕获各种错误以及编写代码来捕获错误。它最初以 Text2Xml Ant 任务 为基础。代码一点也不优美(至少不如我已经添加的代码),但是它非常适用。 80/20 (或者 90/10 )规则在这里也很适用。该 Ant 任务捕获大约 90% 的编译错误,足以使我们保持轻松的心情。剩余 10% 的错误很少发生,所以仔细研读构建日志比试图通过编写代码来捕获和正确地报告这些错误要简单得多。
使用以下命令行编译 Ant 任务,假设 WebLogic 的 安装目录是 
然后,创建类的 JAR :
jar cf WlwBuildToXml.jar WlwBuildToXml.class
下一节将展示如何使用这种新的 Ant 任务。
CruiseControl Masterbuild脚本
我们现在可以创建一份主 Ant 脚本(在本示例中称为 masterbuild.xml ), CruiseControl 可以使用该脚本运行构建。乍看上去,使用两份构建脚本似乎有些古怪,但是其优势是可以区分应用程序特定的构架逻辑,包括 wlwBuild 任务和 CruiseControl 的特殊信息,例如,如何解释构建输出。您获得的好处可能有所不同。
默认情况下, Ant 只将构建输出发送到 stdout 。 WlwBuildToXml Ant 任务仅可以处理日志文件,但是 <record/> Ant 任务可以在日志文件中保存所有的输出。
Ant 是使用 Java 编写的,并且一次失败被看作是一个 Java 异常。如果 Ant 任务出现一个异常,则该异常就会返回给调用方,并且其并发任务会被忽略。这种行为需要进行调整,因为 Ant 需要调用自定义任务,而不用考虑 wlwBuild 任务中发生了什么,然后,仅传递所有可能已经发生的异常。幸运的是,收集 Ant-Contrib 任务 的那些善良的人们预见到这种需求,并包含了一个 <trycatch/> 任务。由此而生成的构建文件如下所示,它在 <finally/> 任务中具有重要位置。
<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>
!-- here's a good place to tag CVS if you want to.
Ant will only get here if the build was successful. -->
</target>
</project>
一旦创建了该文件,就可以使用目标为 BuildMikesProject 的 Ant 在构建服务器上测试该文件。