下一代构建工具:Gradle

2020-06-11 15:12:53 浏览数 (1)

多年来,构建只有编译和打包的简单需求。但是现代软件开发的规模改变了,因此有了对自动化构建的需求。

今天,大多数项目都包含有多而杂的技术栈、混合的多种编程语言,并使用多种测试策略。随着敏捷实践的崛起,构建不得不更早地支持代码集成,以及频繁和简单地交付软件到测试和产品环境。

现有的构建工具不能够以一种简单但是可定制的方式去满足这些要求。多少次你注视着XML 文件,只是想要弄清楚构建是怎么工作的?而且为什么不能以更简单的方式向构建中添加定制逻辑?通常,当你向一个构建脚本中添加逻辑时,总摆脱不了一种使用了变通方式或者非常规方式实现的感觉。我深知你的痛苦。一定有一种更好的方式,即以一种可表达且可维护的方式去做这些事情。确实有这样的方式,那就是Gradle。

Gradle是基于JVM 构建工具的新一代版本。

它从现有的构建工具如Ant 和Maven 中学到了很多东西,并且把它们的最优思想提升到更高层次。遵循基于约定的构建方式,Gradle可以用一种声明式的方式为你的问题领域建模,它使用一种强大的且具有表达性的基于Groovy 的领域特定语言(DSL),而不是XML。因为Gradle是基于JVM 的,它允许你使用自己最喜欢的Java 或者Groovy 语言来编写定制逻辑。

在Java 世界里,有大量类库和框架可以使用。依赖管理可以自动地从仓库中下载工件,并为项目代码所用。Gradle从现有的依赖管理解决方案的缺点中学习,提供了一套自己的依赖管理实现方式。不仅高度可配置,而且也尽可能地与现有的依赖管理设施(如Maven 和Ivy)相兼容。Gradle管理依赖的能力不仅限于外部库。随着项目大小和复杂度的增加,你会想要以模块的方式来组织代码,以清晰地定义它们的职责。Gradle对多项目构建的定义和组织提供了强有力的支持,以及对项目之间的依赖建模。

我知道,所有这些听起来都让你感觉看到了希望,但是你当前还陷在遗留的构建当中。Gradle不会把你留在烂摊子里面,它会让你的迁移变得简单。Ant 可以在运行时装载,因此不需要任何额外的设置。Gradle允许团队利用他们已经累积的Ant 知识,以及在已有构建基础设施中的投入。想象一下,在Gradle构建脚本中直接使用已经存在的Ant 任务和脚本的可能性。遗留的构建逻辑能够被重用或者逐渐迁移。Gradle的确减轻了你不少的负担。

要开始使用Gradle,你所需要的就是对Java 编程语言有一个较好的理解.之后,你会了解到Gradle是如何在持续交付的部署管道中帮助你实现自动化软件交付的。要初次体验使用Gradle的感觉,你需要首先安装Gradle,然后编写一个简单的构建脚本,并在命令行中运行它。现在,跟我一起去探索振奋人心的Gradle世界吧。

为什么要用Gradle,为什么是现在

如果你曾经与构建系统打过交道,那么当你想到曾经遇到过的挑战时,沮丧也许是其中一种感觉。难道构建工具不应该很自然地帮助你完成项目自动化的目标吗?相反,你不得不向可维护性、可用性、灵活性、可扩展性或者性能妥协。

假设当前的情况是你在给项目构建一个发布版本,而你想要拷贝一个文件到特定的位置。为了确定版本,你需要在描述项目的元数据中检查一个字符串。如果它匹配某种数字模式(例如,1.0-RELEASE),你就将文件从A 点拷贝到B 点。从局外人的观点看,这也许听起来像是一件不太重要的事情。如果你不得不依赖于XML,许多传统构建工具的构建语言,那么用它来表达逻辑就变成噩梦。构建工具给出的答案是通过非标准扩展机制来添加脚本功能。最终变成将脚本代码与XML混合或者从构建逻辑中触发外部脚本。可以想象,你将会需要越来越多的定制代码。结果就是,你不可避免地引入了偶然的复杂性,而降低了构建的可维护性。难道不应该一开始就使用一种具有可表达性的语言来定义构建逻辑吗?

再举一个例子。Maven 遵循约定优于配置的规范,为Java 项目引入了一个标准化的项目布局和构建生命周期。如果你想要确保一个待开发的项目——一个对之前的工作没有任何限制的项目,具有统一的项目结构,那么这是一个非常棒的方式。然而,你也许比较幸运,需要在许多遵循不同约定的遗留项目上工作。Maven 严格遵循的约定之一就是一个项目需要生成一个工件,比如JAR 文件。但是你如何在不改变项目结构的情况下,从一个项目源中生成两个不同的JAR 文件呢?仅仅为了这个目的,你就不得不创建两个分开的项目。而且,即使你大费周折地这么做了,也无法改变构建过程需要适应工具,而不是工具去适应构建过程的事实。

也许在现有的解决方案中,你只遇到一部分问题。通常,你需要牺牲非功能性的需求来为企业级自动化领域建模。但是,还是别忍受这些缺点了——让我们看看Gradle是如何解决这些问题的。

Java 构建工具的演变

让我们看看这些年构建工具是如何演变的。有两个工具统领着Java 项目的构建:Ant 和Maven。经过这么多年,这两个工具都有大步提高和扩展的特性集。虽然它们都非常流行而且变成行业标准,但是却有一个弱点:构建逻辑必须用XML 描述。XML 是非常好的层级数据描述语言,但是对于描述程序流程和构建逻辑却存在不足之处。随着构建脚本复杂度的增加,维护构建代码就成为了噩梦。

Ant 的第一个正式版本是在2000 年发布的。每一个工作元素(在Ant 的术语中叫target)可以被组合和重用。多个target 可以被链接,将单个的工作单元组合成一个完整的工作流。例如,你也许有一个target 是Java 源代码编译,另外一个target是将class 文件打包创建JAR 文件。构建一个JAR 文件只有在完成代码编译之后才有意义。在Ant 中,你让打包JAR 的target 依赖于编译的target。Ant 在如何组织项目结构方面没有给出任何指导。虽然它拥有最大程度的灵活性,但是Ant 使得每个构建脚本都是唯一的而且很难理解。项目中需要的外部库通常要提交到版本控制__系统中,因为没有高级的机制可以自动地将它们从一个中心位置下载下来。早期的Ant 版本需要很多的准则以避免重复代码。它的扩展机制很弱。结果就是,复制和粘贴,这样很差的编码实践成为了唯一的选择。为了统一项目布局,企业需要强制推行一些标准。

Maven 1 发布于2004 年7 月,它尝试去简化这个过程。它提供了一个标准化的项目和目录结构,以及依赖管理。遗憾的是,定制逻辑太难实现了。如果你想要打破Maven 的约定,则需要写插件,叫作Mojo,这通常是唯一的解决方案。Mojo这个名字暗示了这是一种直接、简单和迷人的方式来扩展Maven。但事实上,在Maven 中写插件是累赘和非常复杂的。

后来,Ant 通过Apache 的类库Ivy 引入了依赖管理来追赶Maven 的脚步,它可以完全和Ant 集成,声明式地指定项目编译和打包过程中所需要的依赖。Maven 的依赖管理器,和Ivy 一样,支持解析传递依赖。当我谈到传递依赖时,指的是你指定的依赖自身所需类库。一个典型的传递依赖的例子是,XML 解析库Xerces需要XML API 库才能正常工作。Maven 2 发布于2005 年10 月,它让约定优于配置的思想更进一步。由多个模块组成的项目可以将模块定义成相互的依赖。

这段时间有很多人在寻找现有构建工具的替代品。我们看到了从使用XML 到更具表达性和可读性构建语言的转移。Gant 是带有这种思想的构建工具,它是在Ant 的基础上用Groovy 写的DSL。使用Gant,用户可以将Groovy 语言的特性与现有的Ant 知识结合而不需要写任何XML。即使它不是Maven 核心项目的一部分,项目Maven Polyglot 也提出了相似的方法,允许你写自己构建定义逻辑,该逻辑使用Groovy、Ruby、Scala或者Clojure语言编写在项目对象模型(POM)文件中。我们正处在应用开发新纪元的开端:多语言编程。今天许多应用都使用了多种编程语言,每一种语言都最适合实现一个特定的问题领域。很常见的一种情况是,使用客户端语言比如JavaScript 与混合的多种后端语言如Java、Groovy 和Scala进行通信,而这些后端语言进而会调用由C 编写的遗留系统。最重要的是使用正确的工具做正确的事情。尽管结合多种编程语言有很多好处,但是你的构建工具也需要流畅地支持基础设施。JavaScript 需要被合并、最小化和压缩,而你的服务器端和遗留代码则需要被编译、打包和部署。

Gradle恰好符合这一代的构建工具,满足现代构建工具的许多需求。它提供了具有表达性的DSL、约定优于配置的方法和强大的依赖管理。它摒弃了XML,引入了动态语言Groovy 来定义构建逻辑。听起来很不错,不是吗?

为什么应该选择Gradle

如果你是一个开发者,那么自动化项目就是你日常开发的一部分。难道你就不想把构建代码看作和其他软件代码一样,让它能够被扩展、测试和维护吗?让我们把软件工程搬回到构建中。Gradle构建脚本是声明式的、可读的,并且清晰地表达它们的意图。用Groovy 而不是XML 写代码,挥洒着Gradle基于约定构建的哲理,大大地降低构建脚本的大小而且更易读。

看到用Gradle实现相同的目标所需要编写的代码时确实让人感到惊讶。使用Gradle时,你不需要做出妥协。而像Maven 这样的构建工具提出的项目布局就是“要么我的方式,要么复杂的方式”,Gradle的DSL 提供了灵活性去适应非约定项目布局。

不要改变一个正在运行的系统,你说呢?你的团队已经花费大量的时间来建立项目构建代码基础设施。Gradle并不强迫你完全迁移所有的构建逻辑。它和其他构建工具如Ant 和Maven 有非常好的集成,这是Gradle优先级列表中的最高优先级。

市场似乎注意到了Gradle。在Spring 2010 会议上,Gradle因为最具创新性开源项目被授予Springy 大奖(http://www.springsource.org/node/2871)。ThoughtWorks,一个声誉很好的软件开发咨询公司,会周期性地发布关于新技术、语言和工具的报告——他们称作技术雷达。技术雷达的目的是帮助软件行业的决策者理解发展趋势和他们对市场的影响。在2013 年5 月出版的最新报告中(http://thoughtworks.fileburst.com/assets/technology-radar-may-2013.pdf),Gradle被标记为采纳状态,说明这项技术应该被行业所采纳。

Gradle很早就有采纳者了,甚至在1.0 版本发布之前。像Groovy 和Hibernate这样流行的开源项目已经完全切换到Gradle并作为它们构建的支柱。每一个Android 项目都使用Gradle作为默认的构建系统。Gradle给商业市场也带来了影响。像Orbitz、EADS 和Software AG 这样的公司也使用Gradle,这里只列出了几个公司。VMware,作为Spring 和Grails 背后的公司,对选择Gradle做出了巨大的投资。他们的许多软件产品,比如Spring 框架和Grails,都是建立在对Gradle能够完成交付的信任上的。

————本文节选自《实战Gradle》

0 人点赞