让开发自动化: 使用 Raven 构建 Java 项目告别表达乏力,使用 Ruby 构建 Java 应用程序 ![]() | ![]() |
![]() |
级别: 初级 Paul Duvall, CTO, Stelligent Incorporated 2007 年 11 月 22 日 Ant 无疑是用于 Java™ 平台的标准构建工具;但是,其它一些构建工具也可以为 XML 提供它一直所缺乏的更具表达性的范例。在这一期的 让开发自动化 中,自动化专家介绍了构建在 Ruby 之上的构建平台 Raven,它可以利用功能全面的编程语言和以构建为中心的域特定语言(Domain Specific Language)的简单性。 我手头上有一个 Java 项目,在过去几年的时间里,我小心翼翼地为之维护一个 Ant 构建脚本。Ant 能够执行大量任务,这一点我十分欣赏;然而,我常常发现,Ant 脚本的 XML 语法编写起来有些麻烦。而且,在 可表达性 方面,Ant 的 XML 部分还存在限制。实际上,当我发现自己需要更高程度的灵活性(例如在条件逻辑方面)时,我常常不得不在 Ant 的
数年前,当我在寻找可表达性更强的软件构建工具时,我听说过 Rake。Rake 是用于使用功能全面的 Ruby 编程语言构建软件的一种域特定语言。通过 Rake,我可以轻松获得正在寻找的可表达性。例如,我不必编写定制任务,因为 Rake 构建脚本是 Ruby(而不是 XML);因此,如果我需要某种条件逻辑,那么很容易在需要的地方编写这种逻辑。而且,Rake 采用基于依赖的任务系统,这类似于 Ant 及其前辈 make 中的任务系统。例如,如果输入 对于大多数 Java 项目来说,Rake 本身并不能提供多大帮助;然而,一个相对较新的项目 Raven 将 Rake 的功能和可表达性与用于构建 Java 应用程序的特定任务结合起来。有了 Raven,Java 开发人员就有了一个真正可行的构建平台,该平台可提供特定于 Java 的特性,例如使用
在将 Raven 用于 Java 项目之前,理解 Raven 与 Rake 之间的关系会有所帮助。图 1 显示了 Raven 的一个逻辑图,可以看到,Raven 使用 Rake、RubyGems 和 Ruby。相应地,在使用 Raven 时,可以使用本地 Rake 任务。而且,还可以在 Raven 脚本中使用 Ruby。RubyGems 是类似于 CPAN、RPM 或 APT 的一个包管理器,用于下载必需的 Ruby 包(以及 Java jar)和任何依赖包。 图 1. Raven 的逻辑图 ![]() 虽然还不确定 Raven 是不是构建 Java 项目的最佳 平台,但是可以发现,在转向更自然的编程语言方面,Raven 提供了一个简单而强大的组合。要是让我来说,单凭不必依赖 XML 就可构建 Java 项目这一点,足以使 Raven 获得更多关注。
有两种方法可安装和配置 Raven,第一种方法是 Ruby 方法,第二种方法则更倾向于 Java,即使用 JRuby。我推荐 Java 方法,因为这样更容易配置。安装 Raven 和使之运行需要以下步骤:
当然,下载和安装 Raven 只是小菜一碟。真正有趣的是在创建构建脚本时 Raven 具有的灵活性。在 Raven 术语中,构建文件被称作 Rakefiles,它们有一个简单的格式。实际上,如果您用 Ruby 编写过程序(或者见过 Ruby 代码),那么这些文件看上去会很熟悉。这正是 Raben 的美妙之处:它就是 Ruby — 只不过在其中添加了一些特殊的词。 为了尽快使用 Raven ,毫无疑问,首先我要执行最基本(但是也很重要)的任务,即编译。图 2 中的目录结构表示了我的 Java 项目的布局。如果知道第三方库和源代码所在的位置,就能更快上手了。 图 2. 现有 Java 项目的目录结构 ![]() 注意图 2 中的 lib 结构,第三方 JAR 就在其中。在开始编译之前,必须创建一个路径,使用 Raven 做这件事再容易不过了,因为它支持通过它的 清单 1. 使用 Raven 创建类路径
根据清单 1 中的定义, 在清单 1 中,我特意在路径中包括了 lib 目录中的所有东西。我将这个任务命名为 清单 2. 编译很容易
可以看到,我通过 Raven 的 魔力就发生在
为了测试 Raven 脚本,需要打开一个命令提示符,然后输入: 这里要弄清楚一点。我不必编写很多代码就可以完成编译,因为 Raven 在幕后处理了一些事情,例如创建 target/classes 目录并将生成的类文件复制到这个位置。实际上,您可能已经忘了 清单 1 和 清单 2 中对应的 Ant 脚本是什么样子。这里提示一下,清单 3 显示了一个典型的使用 Ant 构建脚本的编译: 清单 3. 使用 Ant 编译 Java 源代码
将清单 3 与 清单 1 和 清单 2 比较,可以看出一些明显的不同。Raven 不但废除了 XML,而且还假定一些基本的属性,使您在定义任务时需要指定的东西更少。而且,如清单 2 所示,如果有必要,Raven 允许重写假定的属性。 虽然从比较的角度来看清单 1 和清单 2 确实比较有趣,但编译只是构建脚本的有趣之处的一个开始。让我们来看一个更有趣的特性:打包 Java Web 应用程序。
Web 归档(Web Archive,WAR)文件用于打包 Web 应用程序,其中包含诸如 servlet、第三方库和图像之类的各种资源。这些归档文件使用标准的目录命名模式,并且只接受某些文件,例如 web.xml(该文件映射 servlet 名称和其它配置方面),放置在 WEB-INF 目录中。 Raven 使 WAR 文件的创建变得非常简单。在清单 4 中,我以 清单 4. 创建部署到 Web 容器的 WAR
注意,在创建 WAR 文件之前,Raven 必须首先运行 不管您信不信,Raven 就这么简单 — Raven 的
生成项目文档对于向团队成员宣传有用信息通常会有所帮助。如果别人计划使用您正在编写的框架代码或实用程序,那么您最终需要发布 Javadoc,这些 Javadoc 是描述相关源代码中的类、方法和公共实例变量的一些 HTML 文件。 通过 Raven,可以很快地利用 Javadoc 机制生成文档,如清单 5 所示: 清单 5. 使用 Raven 生成 JavaDoc 文档
请再次注意,由于我的项目没有遵循 Raven 假定的模型,因此必须修改 至此,您大概已经意识到,如果项目遵循 Raven 假定的布局,那么构建脚本甚至比我的还要简单!
虽然我只谈到了 Raven 中提供的一部分特性,但是还可以用这个创新的构建平台做更多的事情。特别地,Raven 为使用 RubyGems 机制处理构建依赖(即第三方库)提供了广泛的支持,RubyGems 在构建时自动下载版本化的二进制文件,而不是引用共享驱动。RubyGems 以类似于 Maven 或 Ivy 的方式处理第三方库。 除了 RubyGems 之外,Raven 还可以运行 JUnit 测试,构建一般的 JAR 文件,并且还可以清理目录。表 1 列出了 Raven 中一些较流行的、可方便构建 Java 项目的任务: 表 1. 流行(并且有用)的 Raven 任务
随着 Raven 的成熟,表 1 中的列表会进一步扩大。此外,如果 Raven 中还缺少某种您需要的功能,您完全可以自己编写它!
本文演示了 Raven 的强大功能,其美妙之处在于,您可以在构建脚本中利用 Ruby 语言的强大功能和灵活性。Raven 是否会成为构建 Java 项目的流行平台不是我能决定的,但是我相信 Raven 是在推动业界朝着正确的方向前进。特别是,Raven 通过一种功能全面的命令式编程语言(而不是像 XML 那样的说明性语言)支持基于依赖的任务。尝试一下,您就会明白我的意思。 学习
获得产品和技术 讨论
|