『构建工具-Gradle』相关内容整理

Gradle

Gradle - 简介:

Gradle是一个基于Apache AntApache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML

当前其支持的语言限于JavaGroovyScala,计划未来将支持更多的语言。Gradle,这是一个构建系统(工具),我们认为这是Java(JVM)世界中构建技术的巨大飞跃。

Gradle提供了:

  • 一个非常灵活的通用构建工具,如Ant。

  • 一种可切换的,像 maven 一样的基于约定约定优于配置的构建框架

  • 强大的多工程构建支持

  • 强大的依赖管理(基于 ApacheIvy)

  • 对已有的 maven 和 ivy 仓库的全面支持

  • 支持传递性依赖管理,而不需要远程仓库或者 pom.xml 或者 ivy 配置文件

  • ant 式的任务和构建是 gradle 的第一公民

  • 基于 groovy,其 build 脚本使用 groovy dsl 编写

  • 具有广泛的领域模型支持你的构建

    Reference:https://docs.gradle.org/4.1/userguide/introduction.html

Gradle - 概述:

基于声明的构建和基于约定的构建

Gradle的核心是基于Groovy的丰富的可扩展的域特定语言(DSL)。Gradle通过提供可以根据需要进行组合的声明性语言元素将声明式构建推送到一个新的层次。这些元素还为Java,Groovy,OSGi,Web和Scala项目提供了逐个常规的支持。更重要的是,这种声明性语言是可扩展的。添加您自己的新语言元素或增强现有的元素,从而提供简洁,可维护和易于理解的构建。

为以依赖为基础的编程方式提供语言支持

声明性语言优点在于通用任务图,你可以将其充分利用在构建中. 它提供了最大限度的灵活性,以让 Gradle 适应你的特殊需求。

构建结构化

Gradle 的灵活和丰富性最终能够支持在你的构建中应用通用的设计模式。 例如,它可以很容易地将你的构建拆分为多个可重用的模块,最后再进行组装,但不要强制地进行模块的拆分。 不要把原本在一起的东西强行分开(比如在你的项目结构里),从而避免让你的构建变成一场噩梦。 最后,你可以创建一个结构良好,易于维护,易于理解的构建。

深度 API

Gradle 允许你在构建执行的整个生命周期,对它的核心配置及执行行为进行监视并自定义。

Gradle 的扩展

Gradle 有非常良好的扩展性。 从简单的单项目构建,到庞大的多项目构建,它都能显著地提升你的效率。 这才是真正的结构化构建。通过最先进的增量构建功能,它可以解决许多大型企业所面临的性能瓶颈问题。

多项目构建

Gradle 对多项目构建的支持非常出色。项目依赖是首先需要考虑的问题。 我们允许你在多项目构建当中对项目依赖关系进行建模,因为它们才是你真正的问题域。 Gradle 遵守你的布局。

Gradle 提供了局部构建的功能。 如果你在构建一个单独的子项目,Gradle 也会帮你构建它所依赖的所有子项目。 你也可以选择重新构建依赖于特定子项目的子项目。 这种增量构建将使得在大型构建任务中省下大量时间。

多种方式管理依赖

不同的团队喜欢用不同的方式来管理他们的外部依赖。 从 Maven 和 Ivy 的远程仓库的传递依赖管理,到本地文件系统的 jar 包或目录,Gradle 对所有的管理策略都提供了方便的支持。

Gradle 是第一个构建集成工具

Ant tasks 是最重要的。而更有趣的是,Ant projects 也是最重要的。 Gradle 对任意的 Ant 项目提供了深度导入,并在运行时将 Ant 目标(target)转换为原生的 Gradle 任务(task)。 你可以从 Gradle 上依赖它们(Ant targets),增强它们,甚至在你的 build.xml 上定义对 Gradle tasks 的依赖。Gradle 为属性、路径等等提供了同样的整合。

Gradle 完全支持用于发布或检索依赖的 Maven 或 Ivy 仓库。 Gradle 同样提供了一个转换器,用于将一个 Maven pom.xml 文件转换为一个 Gradle 脚本。Maven 项目的运行时导入的功能将很快会有。

易于移植

Gradle 能适应你已有的任何结构。因此,你总可以在你构建项目的同一个分支当中开发你的 Gradle 构建脚本,并且它们能够并行进行。 我们通常建议编写测试,以保证生成的文件是一样的。 这种移植方式会尽可能的可靠和减少破坏性。这也是重构的最佳做法。

Groovy

Gradle 的构建脚本是采用 Groovy 写的,而不是用 XML。 但与其他方法不同,它并不只是展示了由一种动态语言编写的原始脚本的强大。 那样将导致维护构建变得很困难。 Gradle 的整体设计是面向被作为一门语言,而不是一个僵化的框架。 并且 Groovy 是我们允许你通过抽象的 Gradle 描述你个人的 story 的黏合剂。 Gradle 提供了一些标准通用的 story。这是我们相比其他声明性构建系统的主要特点。 我们的 Groovy 支持也不是简单的糖衣层,整个 Gradle 的 API 都是完全 groovy 化的。只有通过 Groovy才能去运用它并对它提高效率。

The Gradle wrapper

Gradle Wrapper 允许你在没有安装 Gradle 的机器上执行 Gradle 构建。 这一点是非常有用的。比如,对一些持续集成服务来说。 它对一个开源项目保持低门槛构建也是非常有用的。 Wrapper 对企业来说也很有用,它使得对客户端计算机零配置。 它强制使用指定的版本,以减少兼容支持问题。

自由和开源

Gradle 是一个开源项目,并遵循 ASL 许可。

Reference:https://docs.gradle.org/4.1/userguide/overview.html

Gradle - 安装:

关于 Gradle 的安装官网上为我们提供了非常详细的过程,如果你使用的是 MacOS,那么建议使用 Homebrew 进行安装,简单快捷。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  ~ brew install gradle  # 安装Gradle
➜ ~ gradle -v # 查看版本信息

------------------------------------------------------------
Gradle 4.1
------------------------------------------------------------

Build time: 2017-08-07 14:38:48 UTC
Revision: 941559e020f6c357ebb08d5c67acdb858a3defc2

Groovy: 2.4.11
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_121 (Oracle Corporation 25.121-b13)
OS: Mac OS X 10.12.6 x86_64

配置Gradle的环境变量:

1
GRADLE_HOME=/usr/local/gradle

Reference:https://docs.gradle.org/4.1/userguide/installation.html

Gradle - 构建基础:

Projects & tasks:

projects 和 tasks是 Gradle 中最重要的两个概念。

任何一个 Gradle 构建都是由一个或多个 projects 组成。每个 project 包括许多可构建组成部分。 这完全取决于你要构建些什么。举个例子,每个 project 或许是一个 jar 包或者一个 web 应用,它也可以是一个由许多其他项目中产生的 jar 构成的 zip 压缩包。一个 project 不必描述它只能进行构建操作。它也可以部署你的应用或搭建你的环境。不要担心它像听上去的那样庞大。 Gradle 的 build-by-convention 可以让您来具体定义一个 project 到底该做什么。

每个 project 都由多个 tasks 组成。每个 task 都代表了构建执行过程中的一个原子性操作。如编译,打包,生成 javadoc,发布到某个仓库等操作。

build.gradle文件:

示例代码:

1
2
3
4
5
task hello {
doLast {
println 'Hello world!'
}
}

在命令行里, 进入脚本所在的文件夹然后输入 gradle -q hello 来执行构建脚本,示例代码:

1
gradle -q hello Hello world!

这里发生了什么? 这个构建脚本定义了一个独立的 task, 叫做 hello, 并且加入了一个 action. 当你运行 gradle hello, Gradle 执行叫做 hello 的 task, 也就是执行了你所提供的 action. 这个 action 是一个包含了一些 Groovy 代码的闭包(closure 这个概念不清楚的同学好好谷歌下).

如果你认为这些看上去和 Ant 的 targets 很相像, 好吧, 你是对的. Gradle tasks 和 Ant 的 targets 是对等的. 但是你将会会看到, Gradle tasks 更加强大. 我们使用一个不同于 Ant 的术语 task, 看上去比 target 更加能直白. 不幸的是这带来了一个术语冲突, 因为 Ant 称它的命令, 比如 javac 或者 copy, 叫 tasks. 所以当我们谈论 tasks, 是指 Gradle 的 tasks. 如果我们讨论 Ant 的 tasks (Ant 命令), 我们会直接称呼 ant task.

-q. 代表 quite 模式. 它不会生成 Gradle 的日志信息 (log messages), 所以用户只能看到 tasks 的输出. 它使得的输出更加清晰. 你并不一定需要加入这个选项.

Gradle - 构建项目:

创建项目目录:

示例代码:

1
2
➜  ~ mkdir gradle-app
➜ ~ cd gradle-app

使用 Gradle Wrapper构建:

示例代码:

1
2
3
4
➜  gradle-app gradle wrapper

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

以下是 Gradle Wrapper 生成的文件。

示例代码:

1
2
3
4
5
6
7
8
9
10
➜  gradle-app tree
.
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat

2 directories, 4 files
  • gradlew : 这是一个可执行文件,应用于运行gradle构建任务
  • gradlew.bat : 同上,运行再 windows/doc 平台。
  • gradle/wrapper/gradle-wrapper.properties :gradle包装器配置文件

gradle-wrapper.properties:

示例代码:

1
2
3
4
5
6
➜  gradle-app cat gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip

初始化你创建的项目:

示例代码:

1
2
3
4
5
6
7
8
9
10
➜  gradle-app ./gradlew init
Downloading https://services.gradle.org/distributions/gradle-4.1-bin.zip
................................................................
Unzipping /Users/UName/.gradle/wrapper/dists/gradle-4.1-bin/c3kp51zwwt108wc78u68yt7vs/gradle-4.1-bin.zip to /Users/UName/.gradle/wrapper/dists/gradle-4.1-bin/c3kp51zwwt108wc78u68yt7vs
Set executable permissions for:
/Users/UName/.gradle/wrapper/dists/gradle-4.1-bin/c3kp51zwwt108wc78u68yt7vs/
gradle-4.1/bin/gradle

BUILD SUCCESSFUL in 18s
2 actionable tasks: 1 executed, 1 up-to-date

现在可以再次查看下项目:

1
2
3
4
5
6
7
8
9
10
11
12
➜  gradle-app tree
.
├── build.gradle
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

2 directories, 6 files

相较于之前,则多了build.gradlesettings.gradle两个文件。

build.gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
  * 此构建文件是由Gradle'init'任务生成的。
  *
  * 这个生成的文件包含一个注释掉的示例Java项目,让你开始。
  * 有关更多详细信息,请参阅Gradle中的Java Quickstart一章
  * 用户指南可在https://docs.gradle.org/4.1/userguide/tutorial_java_projects.html
  */

/*
// 应用 JAVA 插件来添加项目对 JAVA 的支持
apply plugin: 'java'

// 此处可以声明在何处找到项目的依赖关系
repositories {
//项目空间引用远程仓库--- jcenter(),您可以在这里声明任何Maven / Ivy /文件库。
jcenter()
}

// 声明生产和测试代码的依赖关系
dependencies {
// 生产代码在编译时使用SLF4J logging API
compile 'org.slf4j:slf4j-api:1.7.25'

// 声明您希望在测试中使用的最喜欢的测试框架的依赖关系.
// Gradache测试任务也支持TestNG. 只需要testCompile 依赖于
// testCompile 'org.testng:testng:6.8.1' ,和添加
// 'test.useTestNG()' 到你的构建脚本中。
testCompile 'junit:junit:4.12'
}
*/

settings.gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
➜  gradle-app cat settings.gradle
/*
* 此设置文件是由Gradle'init'任务生成的。
*
* 设置文件用于指定要在构建中包含哪些项目,在单个项目中构建此文件可以为空或甚至删除。
*
* 在用户指南中可以找到有关在Gradle中配置多项目构建的详细信息
* https://docs.gradle.org/4.1/userguide/multi_project_builds.html
*/

/*
// 作为多项目构建的一部分 来声明项目使用'include'方法
include 'shared'
include 'api'
include 'services:webservice'
*/

rootProject.name = 'gradle-app'

继续完善项目:

整个项目的目录结构如下,与 Maven 工程目录结构无差别:

目录 说明
src/main/java JAVA 源码
src/main/resources 生产资源文件
src/test/java 测试源码
src/test/resources 测试资源文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
➜  gradle-app tree
.
├── build.gradle
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradle-app.iml # 导入 IDEA 后生成的文件
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
│   └── java
│   └── ws
│   └── object
│   └── gradle
│   └── App.java
└── test
└── java
└── ws
└── object
└── gradle
└── AppTest.java

13 directories, 9 files

App.java

1
2
3
4
5
6
7
8
9
10
11
12
package ws.object.gradle;
public class App
{
public String getAppId() {
return "hello-world";
}

public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}

AppTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package ws.object.gradle;

import junit.framework.TestCase;

/**
* Unit test for simple App.
*/
public class AppTest extends TestCase {

public void testAppId() {
App app = new App();
assertEquals("App ID", "hello-world", app.getAppId());
}

}

构建创建的项目:

现在我们已经创建了App.java和AppTest.java,我们准备好构建项目。 这可以通过执行如下所示的构建任务来完成。示例代码:

1
2
3
4
➜  gradle-app ./gradlew build

BUILD SUCCESSFUL in 1s
4 actionable tasks: 4 executed

让项目跑起来:

使用内置的jar库运行应用程序,示例代码:

1
2
➜  gradle-app java -cp build/libs/gradle-app.jar ws.object.gradle.App
Hello World!

或者您可以使用内置的类文件夹运行,示例代码:

1
2
➜  gradle-app java -cp build/classes/java/main/  ws.object.gradle.App
Hello World!

参考资料:

Gradle Official Website

Gradle Wikipedia

Gradle Github

Building Java Projects with Gradle