学习Gradle 3 Java 快速入门

1、插件介绍

插件是对 Gradle 功能的扩展,Gradle 有着丰富的插件,你可以在这里搜索相关插件(传送门)。本章将简要介绍 Gradle 的 Java 插件(Java plugin),这个插件会给你的构建项目添加一些任务,比如编译 java 类、执行单元测试和将编译的 class 文件打包成 jar 文件等。


Java 插件是基于约定的(约定优于配置),它在项目的很多方面定义了默认值,例如,Java 源文件应该位于什么位置。我们只要遵循插件的约定,就不需要在 Gradle 配置脚本进行额外的相关配置。当然,在某些情况下,你的项目不想或不能遵循这个约定也是可以的,这样你就需要额外的配置你的构建脚本。


Gradle Java 插件对于项目文件存放的默认位置与 maven 类似。


Java 源码存放在目录:src/main/java


Java 测试代码存放目录:src/test/java


资源文件存放目录:src/main/resources


测试相关资源文件存放目录:src/test/resources


所有输出文件位于目录:build


输出的 jar 文件位于目录:build/libs


2、一个简单的 Java 项目


新建一个文件 build.gradle,添加代码:



apply plugin: 'java'


以上代码即配置 java 插件到构建脚本中。当执行构建脚本时,它将给项目添加一系列任务。我们执行:gradle build,来看看输出的结果:



:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build UP-TO-DATE
BUILD SUCCESSFUL


根据输出结果可以看出,我们执行的 build 这个任务依赖其他任务,比如 compileJava 等,这就是 java 插件预先定义好的一系列任务。


你还可以执行一些其他的任务,比如执行:gradle clean,gradle assemble,gradle check 等。


gradle clean:删除构建目录以及已经构建完成的文件;


gradle assemble(装配):编译和打包 java 代码,但是不会执行单元测试(从上面的任务依赖结果也可以看出来)。如果你应用了其他插件,那么还会完成一下其他动作。例如,如果你应用了War这个插件,那么这个任务将会为你的项目生成 war 文件。


gradle check:编译且执行测试。与 assemble 类似,如果你应用了其他包含 check 任务的插件,例如,Checkstyle插件,那么这个任务将会检查你的项目代码的质量,并且生成检测报告。


如果想知道 Gradle 当前配置下哪些任务可执行,可以执行:gradle tasks,例如应用了 java 插件的配置,执行该命令,输出:



:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles classes 'main'.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles classes 'test'.
Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.
Help tasks
----------
components - Displays the components produced by root project 'learn-gradle'. [incubating]
dependencies - Displays all dependencies declared in root project 'learn-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'learn-gradle'.
help - Displays a help message.
model - Displays the configuration model of root project 'learn-gradle'. [incubating]
projects - Displays the sub-projects of root project 'learn-gradle'.
properties - Displays the properties of root project 'learn-gradle'.
tasks - Displays the tasks runnable from root project 'learn-gradle'.
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
To see all tasks and more detail, run gradle tasks --all
To see more detail about a task, run gradle help --task <task>
BUILD SUCCESSFUL


小伙伴们看到这里会不会有疑问,如果在构建脚本中定义了名为 tasks 的任务,执行会是如何?好奇的小伙伴可以自己试一试噢。事实上,是会覆盖原有的任务的。


3、外部依赖


通常一个 Java 项目会依赖多个其他项目或 jar 文件,我们可以通过配置 gradle 仓库(repository)告诉 gradle 从哪里获取需要的依赖,并且 gradle 还可以配置使用 maven 仓库。例如,我们配置 gradle 使用 maven 中央仓库,在 build.gradle 中添加代码:



repositories {
mavenCentral()
}


接下来,我们来添加一些依赖。代码示例:



dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}


关于依赖,暂时就点这么多。详细可以参考gradle 依赖管理基础,也可以关注后续文章。


4、定义项目属性


Java 插件会为项目添加一系列的属性,通常情况下,初始的 Java 项目使用这些默认配置就足够了,我们不需要进行额外的配置。但是如果默认属性不满足于你的项目,你也可以进行自定义项目的一些信息。例如我们为项目指定版本号和一些 jar manifest 信息。



sourceCompatibility = 1.5
version = '1.0'
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
}
}


事实上,Java 插件添加的一系列任务与我们之前在脚本中自定义的任务没什么区别,都是很常规的任务。我们可以随意定制和修改这些任务。例如,设置任务的属性、为任务添加行为、改变任务的依赖,甚至替换已有的任务。例如我们可以配置 Test 类型的 test 任务,当 test 任务执行的时候,添加一个系统属性。配置脚本如下:



test {
systemProperties 'property': 'value'
}


另外,与之前提到的“gradle tasks”命令类型,我们可以通过“gradle properties”来查看当前配置所支持的可配置属性有哪些。


5、将 Jar 文件发布到仓库



uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}


执行 gradle uploadArchives,将会把相关 jar 文件发布到 reops 仓库中。更多参考:Publishing artifacts


6、构建多个 Java 项目


假设我们的项目结构如下所示:



multiproject/
--api/
--services/webservice/
--shared/
--services/shared/


项目 api 生成 jar 文件,Java 客户端通过 jar 提供的接口访问 web 服务;项目 services/webservice 是一个 webapp,提供 web 服务;项目 shared 包含 api 和 webservice 公共代码;项目 services/shared 依赖 shared 项目,包含 webservice 公共代码。


接下来,我们开始定义多项目构建。


1)首先,我们需要添加一个配置文件:settings.gradle 文件。settings.gradle 位于项目的根目录,也就是 multiproject 目录。编辑 settings.gradle,输入配置信息:



include "shared", "api", "services:webservice", "services:shared"


include 是Gradle DSL定义的核心类型 Settings 的方法,用于构建指定项目。配置中指定的参数“shared”、“api”等值默认是当前配置目录的目录名称,而“services:webservice”将根据默认约定映射系统物理路径 "services/webservice"(相对于根目录)。关于 include 更详细的信息可以参考:构建树


2)定义所有子项目公用配置。在根目录创建文件:build.gradle,输入配置信息:



subprojects {
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
}
version = '1.0'
jar {
manifest.attributes provider: 'gradle'
}
}


subprojects 是Gradle DSL定义的构建脚本模块之一,用于定义所有子项目的配置信息。在以上配置中,我们给所有子项目定义了使用“java”和“eclipse-wtp”插件,还定义了仓库、依赖、版本号以及 jar(jar 是 Gradle 的任务类型之一,任务是装配 jar 包,jar 任务包含属性 manifest,用于描述 jar 的信息,具体参考:Jar)。


我们在根目录执行 gradle build 命令时,这些配置会应用到所有子项目中。


3)给项目添加依赖


新建文件:api/build.gradle,添加配置:



dependencies {
compile project(':shared')
}


以上,我们定义了 api 项目依赖 shared 项目,当我们在根目录执行 gradle build 命令时,gradle 会确保在编译 api 之前,先完成 shared 项目编译,然后才会编译 api 项目。


同样,添加 services/webservice/build.gradle,添加配置:



dependencies {
compile project(':services:shared')
}


在根目录执行:gradle compileJava,输出:



:shared:compileJava UP-TO-DATE
:shared:processResources UP-TO-DATE
:shared:classes UP-TO-DATE
:shared:jar UP-TO-DATE
:api:compileJava UP-TO-DATE
:services:compileJava UP-TO-DATE
:services:shared:compileJava UP-TO-DATE
:services:shared:processResources UP-TO-DATE
:services:shared:classes UP-TO-DATE
:services:shared:jar UP-TO-DATE
:services:webservice:compileJava UP-TO-DATE
BUILD SUCCESSFUL


通过输出信息我们就可以清楚看出依赖配置是否正确啦。