开发人员:J2EE
管理 Ant 工厂 作者:Sudhakar Ramakrishnan
使用 Ant 自动化构建的最佳实践
过去的几年中涌现了一些构建自动化工具,每个工具都有自身的优点和缺点。 Ant 便是其中的一员。对于 Java 开发人员而言,它肯定是这些工具中比较突出的一个。 在最近的 OTN 调查(参见侧边条 1“OTN 开放源代码调查”)中,有 45.1% 的被调查开发人员说 Ant 是他们最常用的开放源代码工具。
到底是什么使它如此具有吸引力呢? 毫无疑问,原因有很多。 它是一个跨平台的构建工具(与 Make 不同);它的配置文件基于 XML(因此,具有低学习曲线);它可以用于各种 IDE(包括 Oracle JDeveloper);并且它可以无需任何定制即可自动执行大量构建任务(尽管它还可以使用 Java 类进行扩展)。 (有关更多详细信息,请参见侧边条 2“全面了解 Ant”。)
更具体地说,Ant 可以自动执行的基本任务包括创建和删除目录、使用 FTP 下载和复制文件、将文件压缩成 JAR 或 ZIP,以及创建文档。 Ant 还提供了更高级的功能,Michel Casabianca 在 OTN 上其他地方的文章“Ant 入门”(Oracle Magazine,2002 年 11/12 月)中对这些功能进行了介绍。 这些功能包括从源代码控制系统(如 CVS、Clearcase、SourceSafe 等)中读取源代码;以及执行 SQL 查询和脚本、将 XML 转换为易读的 HTML 和生成 stub 文件以进行远程方法调用。
尽管具备这些功能,但使用 Ant 自动执行大型构建还是需要仔细的谋划。 我认为,任何在 Ant 中用脚本实现的构建自动化都应完全消除用户交互。 它应具有高效的设计,以减少冗余或重复任务所占用的时间和促进脚本的重用。 并且它应可扩展和易于管理,同时还要在一定程度上考虑构建文件的可读性。 在本文中,我将详细介绍这些主题,并重点介绍一些最佳实践以及自动化构建时要注意的事项,同时尽可能地指出 Ant 的实用性。 本文最后还提供了一个资源列表,其中包含我所参考文章的超链接,以便对使用 Ant 自动执行构建感兴趣的读者可以集中获得各种建议和工具来帮助他们进行构建。 其中的许多文章都可以在 OTN 上找到。
自动构建: 消除用户交互
根据定义,自动构建意味着消除用户在运行时的大多数(要不是所有的话)交互。 理想情况是实现一个自始至始终都顺利运行的“一键式”构建。 它的理论根据很明显: 构建自动化提高开发人员的生产力,缩短发布时间。 随着构建和重构的改进,它还可以提高代码的质量。 实际上,源代码越复杂,构建所需自动化工作量越大。 说着容易做着难。设置这样的构建需要事先进行安排、研究和规划。 实际上,设计构建自动化过程意味着先要“把握全局”。 这涉及到一些问题,下文介绍一些关键问题。
首先,您需要收集用于构建的相应工具、文件和库。 Ant 不仅能够执行基本的源代码控制操作(如签入、签出和标记代码),而且目前还支持一些可以添加到工具集的源控制系统,包括 Clearcase、Continuous/Synergy、CVS、Perforce、PVCS、StarTeam 和 Visual SourceSafe。 可选的测试程序包中提供对所有系统(CVS 除外)的支持。 请注意,开始之前,可能需要更新或修补依赖于 Ant 的组件,并且当您使用多个库时应考虑集成问题。
然后,您需要对目录结构以及源文件、目标和将控制脚本的相依性有一个很好的基本了解。 构建目录和文件层次结构有一些公认的形式。 Ant 从目录中获取源文件,从库中提取组件,然后执行一个生成目标的过程。 同时,该过程的执行可能依赖于上一过程的目标(结果)。 因此,需要映射相依性关系。 您肯定不希望创建循环相依性(即,脚本一再返回到某个过程)这种情况的发生。
然后,您将开始自动执行您的步骤,并避免使用强制用户干预的工具,同时监视可能中断构建过程的更改。 由于 Ant 是一个用 Java 编写的跨平台工具(与 Make 不同),因此消除了必须为不同的平台构建脚本所导致的用户干预要求。 同样,您还需要避免使用要求在 GUI 输入屏幕中进行输入的工具。 设想一个等待构建者从屏幕输入而挂起的构建。 因此,构建自动化应尽可能地使用命令行输入。 某些工具还允许您构建通过参数修改的可重用组件,以减少过多的脚本编写。 并且您将需要根据标准规则管理脚本更改。
您必须注意对构建的本地化。 目前生产的许多产品的构建只考虑本地的使用,而许多产品还要提供国际版本。 这确保当软件被加载后,所有使用说明、产品中的所有菜单以及所有帮助文件和字体均采用本地语言。 这时需要使用 NLS 变量和留意一些 Unicode 格式。 构建需要识别这些变量和格式。
某些用户可能还要必须执行各种任务以最大限度地实现构建自动化。 您需要安装优化代码以提高效率吗? 您需要使用一个新的运行时吗? 执行服务器操作前需要启动某些服务吗? 出色的构建自动化还意味着需要了解一些服务器端的开发。 开发服务器端 Java 应用程序的开发人员通常对 servlet 的编译、JSP 文件的部署以及 HTML 文件、配置文件和图像的部署感兴趣。
|
OTN 开放源代码调查
问题:您最常使用哪种开放源代码工具?
|
| Ant: 2093 票 | 45.1% |
| CVS: 1147 票 | 24.7% |
| Xdoclet: 423 票 | 9.1% |
| Eclipse: 348 票 | 7.5% |
| Jalopy: 252 票 | 5.4% |
| Jtidy: 8 票 | 0.2% |
| Lomboz: 6 票 | 0.1% |
| 其他: 362 票 | 7.8% |
| 总计: 4639 票 | 99.9% |
| 调查发布时间: 2004 年 2 月 17 日。此次调查在 OTN Java 中心持续了大约 2 到 3 周。 |
毫无疑问,您还必须在构建中添加安全的登录功能。 这与通过注册的供应商保证服务(例如,当您下载一个插件时,将弹出一个显示“是否信任此供应商?”的对话框)提供安全性的代码有关,并与包括确保安全登录的公钥有关。
您可能还必须应用混淆 (obfuscation)。 混淆是一个确保代码安全的过程,因此得到的代码是不可读的。 每当源代码无法按原样提供并需要一些安全性时,就需要在构建结束时在体系结构和部署级决定应用某种混淆。
大多数情况下,您还将必须生成文档并通过电子邮件和 Web 发布该版本的通知。 也就是说生成一些可以标示构建版本、描述错误修复情况的文档,然后,您将给开发人员们发送电子邮件,告知构建已完成并可以在某某网站中下载。
一个艰巨的任务是将构建与产品发布进程 (PRP) 同步和集成。 这就需要事先与 QA 小组和发布小组协同工作,以最大限度地减少构建时的用户交互。 此时,构建设计者应知道极限编程工作的进展情况。 ThoughtWorks 的首席科学家 Martin Fowler 在这方面做得很出色。他采用了一个名为“连续集成”的方法,即将构建自动化和多个日常构建与构建脚本的构建单元测试相结合来减少集成问题。 使用这种方法,当某人以该单元所不允许的方式更改构建过程时,测试单元可以指示您构建过程是否遭到破坏以及何处遭到破坏。 有关更多详细信息,请参见 Martin Fowler 和 Matthew Foemmel 的文章“连续集成”(参见下面的链接)。
提高构建的效率
构建设计者在自动化构建时的主要目标是消除用户交互,但同时还需要考虑一个并不明显的次级目标,即效率。 提高效率可以藉由减少重复任务耗费的时间(例如,尽可能地消除冗余)以及重用组件,以便在组合构建时避免“重新构建”。 想象一个机器人,让它在执行其主要任务的同时完成次要任务,而不是反复回到起点。 或者,如果要为某个模块生成文档,为何不同时为多个模块生成文档呢? 为什么不将所有可重用的步骤放在一个位置来提高构建脚本的效率,以便它们同时执行以减少构建时间呢?
|
全面了解 Ant
Ant 的独特之处是什么? 与 Make 使用模型(使用基于 shell 的计算机特有的命令扩展构建)不同,Ant 使用基于 XML 配置文件,而 XML 是跨平台的。 Ant 中的每个构建项目都是一个目标集合。 而每个目标则是一个任务的集合。 每个任务都包含一组属性。 因此,可以通过编程方式在相对较少的代码行中调用每个 Ant 任务并以相同方式扩展每个任务。
正如 John Kirkley 在“Ant 构建”(参见下面的“参考”部分以获得 Kirkeys 的文章以及许多其他人的文章)中指出,开发人员使用 Ant 和它的基于 XML 的构建文件“编译、运行单元测试、使用 FTP 或 Telnet 部署到远程应用服务器以及使用单个命令运行部署测试”。 “其他 Ant 功能包括发出 SQL 语句、压缩日志文件副本以及将该副本作为 MIME 附件通过电子邮件发送。 如果开发人员确实需要添加一些操作系统特有的 shell 命令,则可以使用 Ant 包含的 exec 任务功能,该功能允许基于 Ant 运行在的操作系统执行不同的操作系统特有的命令。” |
还可以通过向通常采用的晚间构建中加入另一个极限编程策略:连续构建来最大化效率。 这意味着,将构建脚本签入到构建项目中时,您尝试能否尽快提供一个供应商所认为的项目将要呈现的外观。这意味着您要不断地构建,并将计算机处于空闲状态的空闲时间(可能是在误餐时间)用于其他编程任务。 您还可以设计构建级别,即第 1 级到第 n 级(从更容易到更复杂的构建),其中第 1 级构建连续进行(因为它们比较简单),而第 6 级构建在夜晚进行(因为它们比较复杂且需要更多时间)。
提高效率还意味着将构建代码参数化。 此时可以利用 Ant 1.6 的导入功能,该功能使您能够构建可重用的库,然后对该库进行“参数化”。 将 Ant 构建宏和脚本参数化也就是构建一个特殊种类的任务作为构建模块,然后将新参数发送给此模块以实现重用。 设想一个喷有白色底漆的车身,根据该车是标准模型还是定制模型来为它加上不同的涂料。 (参见下面参考的 Stefan Bodewig 编写的有关此过程的文章。)
最后,一种使构建自动化过程更有效的方法是使用某种工具(如 Maven,从某种意义上说,它是 Ant 的竞争对手)来管理它。 根据 Apache Maven 项目的官方站点(参见以下链接)中的介绍,Maven 是一个在很大程度上依赖于项目对象模型 (POM)(在该模型中,所有 Maven 产品 如文档、源代码公制和报表 都由 POM 控制)概念的 Java 项目管理工具。 通过提供一个定义良好的项目结构和开发过程,以及使开发人员和客户了解项目的最新进度的文档,简化了开发人员的工作。 Maven 减少了日常枯燥的构建自动化工作,使开发人员可以全神贯注于手头的实际编程任务。 它的好处体现在不需要很多人来专门从事记录和传播项目主要信息的工作。 为帮助您判断哪个工具更适合您的项目(Ant 还是 Maven),可以先从 OTN 上阅读 Julien Dubois 的文章“掌握并精通”。 下面提供了此链接。
使构建易于管理和具有扩展性
最终,您的构建文件必须易于管理并具有可扩展性。 由于目标是实现“一键式”构建,因此在您拥有上百个源文件时开发一个构建并非一个简单的任务。 它需要从整体上思考和考虑 Ant 的 XML 格式。XML 格式既可以更容易地加快速度,同时也有可能使管理成为噩梦(如果您考虑不周的话)。 随着构建越来越复杂,如果您不为构建文件加上注解,那么构建文件中的尖括号(假如它们位于 XML 的层级式声明结构中)会很快变得难以操纵和难以辨认。 您的最后一个目标是使构建成为编程中的主要焦点。 (James Duncan Davidson 在他最近的文章“Ant 和 XML”中谈到了这个问题,而 Stefan Bodewig 的文章“为大型项目提供的 Ant 1.6 新特性”也在一定程度上介绍了它,文中作者介绍了未来将如何解决此类问题。 下面提供了这两个链接。)
最后,您需要考虑在构建任务无法执行您所需的操作时应采取的措施。此时真正体现了 Ant 的优点之一,既它能够创建定制任务并能够根据您的需要对它进行扩展。 即使您没有支持构建进程的公共运行时库集,也可以使用一个称作“更改 Apache 工具 Ant 任务”的特殊功能创建它们。 它的作用是为您提供一个插件机制,以便您当机立断地创建定制的脚本。 有关这方面的更多概念,请阅读 Stefan Bodewig 的文章“为任务编写者提供的 Ant 1.6”,他在该文章中介绍了定制和可扩展性。
就是这样。 如果您着手消除用户交互,构建脚本以实现高效性,并使构建具有可管理性和可扩展性,同时记住 Ant 的优点和不足,则您将在通往自动化构建的道路上走得更远。
|
Ant: 参考和链接
Apache Ant 项目。 在官方站点上全面了解 Ant 的信息,包括 Ant 的背景信息、当前的文档和当前可供下载的版本(1.6.2,2004 年 7 月 16 日发布)以及来自 Ant 社区的文章。
Ant 构建作者:by John Kirkley. 这是一篇介绍此跨平台构建工具诞生的幕后信息的文章。
Ant 和 XML。x180: James Duncan Davidson 的杂志(2004 年 3 月 31 日)。Ant 的创建者回顾并介绍了选择 XML 作为 Ant 的构建文件格式的优点和缺点。 层次结构不错,但当构建文件增加到上千行代码时,XML 的角括号不能像您在脚本语言中所期望的那样灵活。
试用: 使用 Ant 进行构建。 这个 viewlet 演示了已拥有 Ant 项目的用户如何能够在 JDeveloper 内部使用这些项目。
Ant 入门(第 1 部分),作者:Michel Casabianca。 本文将帮助您开始使用这个宝贵的工具构建和部署 Java 项目。本文介绍了在 Java 开发过程中您可能要执行的一些基本 Ant 任务。
有关 Ant 的更多内容(第 2 部分),作者:Michel Casabianca。 这是 Michel 编写的有关如何使用 Ant 构建和部署 Java 项目的系列文章的第 2 部分。本文讨论在 Ant 的两个任务程序包(核心的任务程序包和可选的任务程序包)中提供的一些 Ant 的更高级的特性。
启动 Linux 平台上的 Java 开发(第 2 部分: 开始启动),作者:Robert Clevenger。 本文可用作使用 Ant 在 Linux 上开发和部署 Java 客户端应用程序的一个不错的上机操作指南。 参见“获取并安装 Ant”部分。
连续集成,作者:Martin Fowler 和 Matthew Foemmel。 在本文中,ThoughtWorks 构建专家介绍了如何构建一个完全自动化的构建和测试过程,以便小组一天能够多次构建和测试它们的软件。
为大型项目提供的 Ant 1.6 新特性(第 1 部分),作者:Stefan Bodewig。了解 Ant 1.6 的新特性以及它们如何影响您组织构建过程的方式。
为任务编写者提供的 Ant 1.6(第 2 部分),作者:Stefan Bodewig。 利用 Ant 1.6 的内部更改编写任务甚至任务库。
将 Ant 部署到 OC4J(Buttso 的网志)。 “将 Ant 脚本部署到 OC4J 单独实例非常容易,并且我相信有很多人都曾这样做过。 我总是忘记语法,因此必须通过旧的构建文件获得命令的正确格式。 因此为了易于使用,我在此处提供了用于从 Ant 脚本执行部署操作的 Ant 目标。”
在 Oracle JDeveloper 中使用 CVS。 这个 viewlet 说明如何执行一些操作,包括创建 CVS 连接、导入项目、修改代码、比较版本、监视版本历史以及签入更改。
Oracle JDeveloper 和 Apache Ant。 Oracle JDeveloper 中的 Ant 集成可通过向 JDeveloper 项目中添加 Ant 构建文件或从现有的 JDeveloper 项目生成一个新的 Ant 构建文件来完成。 此处演示了操作方法。
使用 JUnit 进行容器内测试 作者:Julien Dubois。 在本文中,您将了解使用 JUnit 的容器内测试如何优于使用模仿对象的集成测试,以及如何使用 Oracle JDeveloper 实现该技术。
Apache Maven 项目。 它是 Apache Maven 项目(可以用作 Ant 的补充的 Java 项目管理和项目理解工具)的官方站点。
掌握并精通 作者:Julien Dubois。 Maven 和 Ant 都是由 Apache Software Foundation 提供的开放源代码构建工具,在它们之间进行选择是项目主管要做的最重要的决策之一。 在本文中,Dubois 提供了一个高级比较来帮助您进行选择。
|
Sudhakar Ramakrishnan (sudhakar.ramakrishnan@oracle.com) 是 Oracle 技术网的高级技术编辑。他担任中间件体系结构系列和 PHP 漫游者指南的管理编辑。 在本文中,Sudhakar 概述了一些在使用 Ant 进行自动化构建时要注意的最佳实践和事项。
|