Gradle

Table of Contents

1 Gradle简介

Gradle is an open source build automation system that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based domain-specific language (DSL) instead of the XML form used by Apache Maven for declaring the project configuration.

参考:
Gradle Website: https://gradle.org/
Gradle Documentation: https://gradle.org/docs
Gradle User Guide: https://docs.gradle.org/current/userguide/userguide.html

1.1 Using Gradle Eclipse

为了在Eclipse中新建或者打开Gradle工程,你需要安装一个叫 Buildship 的工具。安装完成后,你可以通过“File -> New -> Other”创建一个Gradle工程,或者通过“File -> Import -> Gradle”打开一个已有的Gradle工程。

参考:
Eclipse Buildship: Eclipse Plug-ins for Gradle: https://projects.eclipse.org/projects/tools.buildship
Using the Gradle build system in the Eclipse IDE: http://www.vogella.com/tutorials/EclipseGradle/article.html

1.2 配置文件

Gradle包含下面这些配置文件:
(1) build.gradle:指定了一个项目和它的任务。
(2) gradle.properties:用来配置构建属性。
(3) gradle.settings:它对于只有一个项目的构建而言是可选的,如果我们的构建中包含多于一个项目,那么它就是必须的,因为它描述了哪一个项目参与构建。每一个多项目的构建都必须在项目结构的根目录中加入一个设置文件。

1.2.1 设置proxy

如果想对所有的gradle项目设置代理,可以在GRADLE_USER_HOME(为目录 “~/.gradle/”)下新建文件gradle.properties,增加配置项:

systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=10384
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=10384

如果只是对单个项目设置代理,则仅修改项目中对应的gradle.properties文件即可。

1.3 实例:用Gradle编译Java程序

下面以一个简单的Hello world工程(你也可以使用命令 gradle init --type java-application 来自动生成Hello world工程)来介绍Gradle的基本使用。

这里假定你的工程源码已经存在(需要符合Maven的规范,也就是不同资源分别放在约定目录src/main/java, src/main/resources, src/test/java and src/test/resources等中),其目录结构和内容如下:

$ find /home/cig01/java-demo
/home/cig01/java-demo
/home/cig01/java-demo/src
/home/cig01/java-demo/src/main
/home/cig01/java-demo/src/main/java
/home/cig01/java-demo/src/main/java/App.java
$ cat ./src/main/java/App.java
public class App {

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

首先,在当前目录中新建文件 build.gradle ,其内容为:

apply plugin: 'java'

然后,执行 gradle build 命令即可开始编译。如:

$ gradle build
:compileJava
:processResources NO-SOURCE
:classes
:jar
:assemble
:compileTestJava NO-SOURCE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test NO-SOURCE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 1.962 secs

编译完成后,会生成jar包“build/libs/java-demo.jar”(包的名字java-demo默认为当前目录名字)。测试运行如下:

$ java -cp build/libs/java-demo.jar App
Hello world

说明:使用命令 gradle run 可更方便地执行编译后的程序。不过要求我们使用插件application,且配置mainClassName为主程序类名。即把文件 build.gradle 修改为:

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'App'

这时,运行 gradle run 可执行程序App。

$ gradle run
:compileJava UP-TO-DATE
:processResources NO-SOURCE
:classes UP-TO-DATE
:run
Hello world

BUILD SUCCESSFUL

Total time: 1.846 secs

上面的输出中有很多是gradle的输出,查找程序App的输出(字符串“Hello world”)不方便。可以使用 -q 选项来禁止gradle输出,这样可更快捷地查看到程序App的输出。如:

$ gradle -q run
Hello world

参考:https://guides.gradle.org/building-java-applications/

2 Gradle基础:Project和Task

Gradle中,有两个基本概念:Project和Task。 Project是指:构建产物(比如jar包)或实施产物(将应用程序部署到生产环境),一个Project包含一个或多个Task。Task是指:不可分的最小工作单元,执行构建工作(比如编译、打包、生成javadoc、发布等等)。

2.1 Task介绍(gradle命令行基本用法)

gradle的命令行用法为: gradle [option...] [task...] 。比如 gradle compile test 就是执行任务compile和test。

任务之间可以有依赖。比如下面的build.gradle文件中定义了如图 1 所示的任务依赖关系。

task compile {
    doLast {
        println 'compiling source'
    }
}

task compileTest(dependsOn: compile) {           //这里设置了任务compileTest依赖于任务compile
    doLast {
        println 'compiling unit tests'
    }
}

task test(dependsOn: [compile, compileTest]) {    //这里设置了任务test依赖于任务compile和compileTest
    doLast {
        println 'running unit tests'
    }
}

task dist(dependsOn: [compile, test]) {           //这里设置了任务dist依赖于任务compile和test
    doLast {
        println 'building the distribution'
    }
}

gradle_tasks_exam.png

Figure 1: Task dependencies

任务之间有依赖于,先执行依赖。比如执行命令 gradle dist test 时,会依次执行任务compile,compileTest,test,dist(每个任务最多会执行一次)。测试如下:

$ gradle dist test
:compile
compiling source
:compileTest
compiling unit tests
:test
running unit tests
:dist
building the distribution

BUILD SUCCESSFUL

Total time: 1 secs

每个任务最多执行一次。gradle test testgradle test 是相同的。

参考:https://docs.gradle.org/current/userguide/tutorial_gradle_command_line.html

2.1.1 排除某个任务的执行(-x)

使用选项 -x 可以排除某个任务的执行。以图 1 中的任务为例, gradle dist -x test 会排除任务test(及test的依赖)的执行:

$ gradle dist -x test
:compile
compiling source
:dist
building the distribution

BUILD SUCCESSFUL

Total time: 1 secs

2.1.2 任务名的简写

只要不冲突,任务名可以简写。如下面4种用法效果相同:

gradle d
gradle di
gradle dis
gradle dist

此外,如果任务名是 Camel case 形式,只要不冲突,对单词也可以进行简写。如下面3种用法效果相同:

gradle compileTest
gradle compTest
gradle cT

2.1.3 强制重新执行任务(–rerun-tasks)

默认gradle是增量编译的,如果任务的输入文件没有修改就不会重新编译。可以通过指定选项 --rerun-tasks 来使gradle总是执行指定任务。

3 Gradle插件简介

Gradle的核心能做的事件非常少,所有有用特性(比如编译Java代码等)都由Gradle插件来提供。

一个Gradle插件能够:
(1) 在Project中添加新Task;
(2) 为新加入的任务提供默认配置(如约定源文件默认位置);
(3) 加入新的属性;
(4) 为项目加入新的依赖。

对于简单的任务,你不用自己编写插件,Gradle提供了一些 Standard plugins ,下面是它们的不完整列表:

Table 1: 部分的Gradle standard plguins
Plugin Id Automatically applies Works with Description
java java-base - Adds Java compilation, testing and bundling capabilities to a project.
groovy java, groovy-base - Adds support for building Groovy projects.
scala java, scala-base - Adds support for building Scala projects.
antlr java - Adds support for generating parsers using Antlr.
application java, distribution - Adds tasks for running and bundling a Java project as a command-line application.
ear - java Adds support for building J2EE applications.
jetty war - Deploys your web application to a Jetty web container embedded in the build.
osgi java-base java Adds support for building OSGi bundles.
war java - Adds support for assembling web application WAR files.

要使用插件(假设插件名为foo),在文件 build.gradle 中使用 apply plugin: 'foo' 即可。

参考:
https://docs.gradle.org/current/userguide/plugins.html

3.1 插件JavaPlugin(java)简介

JavaPlugin是Gradle中非常基础的一个插件,在文件 build.gradle 中增加下面内容即可使用它。

apply plugin: 'java'
// apply plugin: org.gradle.api.plugins.JavaPlugin   // 和上一行相同
// apply plugin: JavaPlugin                          // 和上一行相同

JavaPlugin增加了下面Tasks到你的工程中。

Table 2: JavaPlugin往你的工程中增加了下面Tasks
Task name Depends on Type Description
compileJava All tasks which produce the compile classpath. This includes the jar task for project dependencies included in the compile configuration. JavaCompile Compiles production Java source files using javac.
processResources - Copy Copies production resources into the production resources directory.
classes The compileJava task and the processResources task. Some plugins add additional compilation tasks. Task Assembles the production classes and resources directories.
compileTestJava compile, plus all tasks which produce the test compile classpath. JavaCompile Compiles test Java source files using javac.
processTestResources - Copy Copies test resources into the test resources directory.
testClasses compileTestJava task and processTestResources task. Some plugins add additional test compilation tasks. Task Assembles the test classes and resources directories.
jar compile Jar Assembles the JAR file
javadoc compile Javadoc Generates API documentation for the production Java source, using Javadoc
test compile, compileTest, plus all tasks which produce the test runtime classpath. Test Runs the unit tests using JUnit or TestNG.
uploadArchives The tasks which produce the artifacts in the archives configuration, including jar. Upload Uploads artifacts in the archives configuration, including the JAR file.
clean - Delete Deletes the project build directory.
cleanTaskName - Delete Deletes files created by specified task. cleanJar will delete the JAR file created by the jar task, and cleanTest will delete the test results created by the test task.

JavaPlugin默认使用下面的工程结构:

Table 3: JavaPlugin默认使用的工程结构
Directory Meaning
src/main/java Production Java source
src/main/resources Production resources
src/test/java Test Java source
src/test/resources Test resources
src/sourceSet/java Java source for the given source set
src/sourceSet/resources Resources for the given source set

参考:https://docs.gradle.org/current/userguide/java_plugin.html

3.1.1 实例:修改工程默认结构

如果你的java源码在“scr/java”中,而不是默认的“src/main/java”中,你可以在文件 build.gradle 增加下面配置:

sourceSets {
    main {
        java {
            srcDirs = ['src/java']
        }
    }
}

4 Dependency Management

Maven repository中的库都可以引入到Gradle中。在项目的build.gradle文件中配置即可。下面是一个简单例子:

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

参考:https://docs.gradle.org/current/userguide/artifact_dependencies_tutorial.html


Author: cig01

Created: <2016-06-13 Mon 00:00>

Last updated: <2017-12-13 Wed 13:40>

Creator: Emacs 25.3.1 (Org mode 9.1.4)