需要准备
- 一个熟悉的 IDE 开发工具
- JDK 7及以上
- Gradle 3.2以上
通过五步聚来使用 Java 插件
第一步,Java 插件的引用
在 build.gradle 中添加以下语句,表示对 java 插件的引用。
apply plugin:'java'
第二步,Java 插件的任务
任务名称 | 依赖 | 类型 | 描述 |
---|---|---|---|
compileJava | 依赖类路径下所有的编辑任务 | JavaCompile | 使用javac来编译工程的java源文件 |
processResources | - | Copy | 将项目的资源文件复制到项目生产的class目录中 |
classes | 依赖compileJava和processResource两个任务,一些插件添加的额外编译任务 | Task | 组装产生的classes和resources目录 |
compileTestJava | 依赖compile和一些产生测试编译环境的任务 | JavaCompile | 使用javac编译java测试源码 |
processTestResources | - | Copy | 将测试资源文件复制到项目产生的test资源文件目录中 |
testClasses | 依赖compileTestJava和processTestResource和一些添加测试的编译任务 | Task | 组装测试的classes和资源目录 |
jar | 依赖compile | Jar | 组装成jar文件 |
javadoc | 依赖compile | Javadoc | 生成java帮助文档 |
test | 依赖compile,compileTest等 | Test | 使用JUnit和TestNG执行单元测试 |
uploadArchives | 依赖那些在归档配置过程中产生镜像的任务,比如jar。属于UpLoad类型 | Upload | 上传归档文件,包括JAR文件 |
clean | - | Delete | 删除项目的build目录 |
cleanTaskName | - | Delete | 删除由任务所产生的文件,比如cleanJar就是删除有任务jar产生的文件,cleanTest就是删除由test产生的文件 |
工程中添加的每一个资源集合( source set ),Java 插件将会为它们添加以下编译任务,在“定义一个新的资源集合”一节中还会具体用到这些任务的。
任务名称 | 依赖 | 类型 | 描述 |
---|---|---|---|
compileSourceSetJava | 依赖所有产生sourceset编译类路径的任务 | JavaCompile | 使用javac编译sourceset定义的源文件 |
processSourceSetResources | - | Copy | 将sourceset定义的资源文件复制到resources目录 |
sourceSetClasses | 依赖compileSourceSetJava和processSourceSetResources两个任务 | Task | 组装sourceset中定义的文件目录 |
而 Java 插件添加的这些任务组成了工程的生命周期。
任务名称 | 依赖 | 类型 | 描述 |
---|---|---|---|
assemble | 依赖所有的归档文件,包括Jar任务 | Task | 组装工程中所有的归档文件 |
check | 依赖所有验证类任务,包括test | Task | 在工程中执行所有的验证类任务 |
build | 依赖check和assemble | Task | 执行工程的完全构建 |
buildNeeded | 不仅依赖当前工程的build和buildNeeded任务,也依赖那些作为当前工程运行时依赖库的所有工程中的build和buildNeeded任务 | Task | 执行工程的完全构建,也包括那些作为当前工程运行时依赖库的所有工程的构建 |
buildDependents | 不仅依赖当前工程的build和buildDependents任务,也依赖那些把当前工程当作运行时依赖库的所有工程中的build和buildDependents任务 | Task | 执行工程的完全构建,也包括那些把当前工程当作运行时依赖库的所有工程的构建,该任务正好与buildNeeded依赖相反 |
buildConfigName | 依赖配置configName指定的任务 | Task | 组装那些特殊配置的镜像,该任务被Java插件隐式添加的 |
uploadConfigName | 依赖configName定义的任务 | Upload | 组装和上传那些特殊配置的镜像,该任务被Java插件隐式添加的 |
下面的图展示了各任务之间的关系:
enter image description here第三步,工程目录结构
Java 插件约定的工程目录结构,在进行 java 编译的时候,会访问下面所有的目录,但是这些目录并不要求必须存在。
目录 | 意义 |
---|---|
src/main/java | java源文件 |
src/main/resources | 项目资源文件 |
src/test/java | 测试源文件 |
src/test/resources | 测试资源文件 |
src/sourceSet/java | source set定义的java源文件 |
src/sourceSet/resources | source set定义的资源文件 |
我们可以通过 sourceSets 来修改这些默认的目录结构,比如修改 src/main/java为src/java、然后修改 src/main/resources 为 src/resources,更多 sourceSets 的配置将在“source sets属性介绍”一节中详细介绍,其示例代码如下:
sourceSets{
main{
java{
srcDir 'src/java'
}
resources{
srcDir 'src/resources'
}
}
}
第四步,依赖管理
Java 插件为工程添加了一些依赖配置,并且把这些配置指绑定到任务中,比如 compileJava 和 test 任务。下面为依赖配置列表。
名称 | 继承 | 被什么任务使用 | 作用 |
---|---|---|---|
compile | - | - | 编译时的依赖 |
compileOnly | compile | - | 仅在编译时的依赖,不在运行时依赖 |
compileClasspath | compileOnly | compileJava | 编译类路径,在编译资源(source)时使用 |
runtime | compile | - | 在运行时使用 |
testCompile | compile | - | 在编译测试时的额外依赖 |
testCompileOnly | testCompile | - | 仅在编译测试时的额外依赖,不在测试运行时依赖 |
testCompileClasspath | testCompileOnly | compileTestJava | 测试编译类路径,在编译测试资源(source)时使用 |
testRuntime | runtime, testCompile | test | 仅在测试运行时的额外依赖 |
archives | - | uploadArchives | 工程生成归档文件时,比如生成jars文件时 |
default | runtime | - | 在工程运行时的默认依赖配置 |
以下是依赖配置关系图,浅蓝色的代表 java 任务,绿色代表 gradle 任务。
enter image description here资源集合( source set )的依赖配置,在“定义一个新的资源集合”一节中会使用到这些任务。
名称 | 继承 | 被什么任务使用 | 作用 |
---|---|---|---|
sourceSetCompile | - | - | 为指定的资源集合在编译时的依赖 |
sourceSetCompileOnly | sourceSetCompile | - | 为指定的资源集合仅在编译时的依赖,不在运行时依赖 |
sourceSetCompileClasspath | sourceSetCompileOnly | compileSourceSetJava | 编译类路径,在编译资源(source)时使用 |
sourceSetRuntime | sourceSetCompile | - | 为指定的资源集合在运行时依赖 |
第五步,常用的属性
Java 插件会为工程添加一些常用的属性,我们可以直接在编译脚本中直接使用。
属性名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
reportsDirName | String | reports | 生成报告的目录名称 |
reportsDir | File(只读) | buildDir/reportsDirName | 生成报告的目录 |
testResultsDirName | String | test-results | 生成测试result.xml文件的目录名称 |
testResultsDir | File(只读) | reportsDir/testReportDirName | 生成测试报告的目录 |
libsDirName | String | libs | 生成lib库的目录名称 |
libsDir | File(只读) | buildDir/libsDirName | 生成lib库的目录 |
distsDirName | String | distributions | 生成发布文件的目录名称 |
distsDir | File(只读) | buildDir/distsDirName | 生成发布文件的目录 |
docsDirName | String | docs | 生成帮助文档的目录名称 |
docsDir | File(只读) | buildDir/docsDirName | 生成帮助文档的目录 |
dependencyCacheDirName | String | dependency-cache | 存储缓存资源依赖信息的目录名称 |
dependencyCacheDir | File(只读) | buildDir/dependencyCacheDirName | 存储缓存资源依赖信息的目录 |
其它属性
属性名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
sourceSets | SourceSetContainer (只读) | Not null | 包含工程的资源集合(source sets.) |
sourceCompatibility | JavaVersion,也可以使用字符串或数字,比如 '1.5' 或者 1.5 | 根据使用的JVM定 | 编译java文件时指定使用的java版本 |
targetCompatibility | JavaVersion,也可以使用字符串或数字,比如 '1.5' 或者 1.5 | sourceCompatibility | 生成classes的java版本 |
archivesBaseName | String | projectName | 作为归档文件的默认名称,如JAR或者ZIP文件的名称 |
manifest | Manifest | 空的Manifest | 所有JAR包的Manifest文件 |
Java 插件中的任务和属性详讲
source sets 属性介绍
我们可以使用 sourceSets 属性来访问工程的资源集合,它是 SourceSetContainer 类形的容器。我们还可以使用 sourceSets{ } 这样的代码块,它可以通过闭包来设置资源集合( source set )容器。
首先如何访问资源集合呢?我们可以通过如下展示的几种方式来访问,代码示例如下:
apply plugin:'java'
// 几种访问main资源集合的方式
println sourceSets.main.output.classesDir // 1
println sourceSets['main'].output.classesDir // 2
sourceSets {
println main.output.classesDir // 3
}
sourceSets {
main {
println output.classesDir // 4
}
}
// 遍历资源集合
sourceSets.all {
println name // 5
}
任意执行一个命令,比如执行gradle tasks
输出结果如下:
/Users/bill/multiprojects/build/classes/main // 1
/Users/bill/multiprojects/build/classes/main // 2
/Users/bill/multiprojects/build/classes/main // 3
/Users/bill/multiprojects/build/classes/main // 4
main // 5
test // 5
同样,我们也可以使用上面的方法来修改默认属性值,示例代码如下:
sourceSets {
main {
java {
srcDirs = ['src/java']
}
resources {
srcDirs = ['src/resources']
}
}
}
下表中列出了资源集合中重要的属性,更多的可以参照官网 SourceSet。
属性名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
name | String(只读) | Not null | 资源集合的名称,用来辨别它 |
output | SourceSetOutput(只读) | Not null | 资源集合的输出文件,它包括编译后的classes和resources |
output.classesDir | File | buildDir/classes/name | 生成classes资源的目录 |
output.resourcesDir | File | buildDir/resources/name | 生成resources资源的目录 |
compileClasspath | FileCollection | compileSourceSet的配置 | 当编译资源的时候使用的类路径地址 |
runtimeClasspath | FileCollection | output + runtimeSourceSet的配置 | 执行classes文件的类路径地址 |
java | SourceDirectorySet(只读) | Not null | Java源文件的目录集合,它仅仅包括.java 文件,其它所有的文件都被排除了。 |
java.srcDirs | Set<File> | [projectDir/src/name/java] | 指定包含java源代码的目录 |
resources | SourceDirectorySet(只读) | Not null | 资源resources目录集合,它仅仅包含资源文件,其它任务.java 文件将会被排除掉。 |
resources.srcDirs | Set<File> | [projectDir/src/name/resources] | 指定包含资源的目录 |
allJava | SourceDirectorySet(只读) | java | 所有的.java 文件的集合 |
allSource | SourceDirectorySet(只读) | resources + java | 所有资源文件的集合,它包含了.java 文件集合和resource 资源文件集合。 |
定义一个新的资源集合( source set )
使用 sourceSets{ } 代码块来定义新的资源集合,代码如下:
sourceSets {
intTest
}
当我们定义新的资源集合时,Java 插件会为该新资源集合添加相关依赖配置任务,具体见“第二步,Java 插件的任务”。
我们可以使用这些配置去定义 compile 和 runtime 的依赖,示例代码如下:
sourceSets {
intTest
}
dependencies {
intTestCompile 'junit:junit:4.12'
intTestRuntime 'org.ow2.asm:asm-all:4.0'
}
Java 插件同时还会为资源集合添加组装类的任务,具体见“第二步,Java 插件的任务”。例如,我们新定义的资源集合名为 intTest,所以我们可以使用命令gradle intTestClasses
来编译该资源类,其执行结果如下:
$ gradle intTestClasses
:compileIntTestJava
:processIntTestResources
:intTestClasses
BUILD SUCCESSFUL
Total time: 1 secs
接下来介绍一些资源集合其它的例子:
// 为资源集合组装jar包
task intTestJar(type: Jar) {
from sourceSets.intTest.output
}
// 为资源集合生成Javadoc帮忙文档
task intTestJavadoc(type: Javadoc) {
source sourceSets.intTest.allJava
}
// 为资源集合进行单元测试
task intTest(type: Test) {
testClassesDir = sourceSets.intTest.output.classesDir
classpath = sourceSets.intTest.runtimeClasspath
}
重要的几个任务介绍
- Javadoc 任务
任务属性 | 类型 | 默认值 |
---|---|---|
classpath | FileCollection | sourceSets.main.output + sourceSets.main.compileClasspath |
source | FileTree | sourceSets.main.allJava |
destinationDir | File | docsDir/javadoc |
title | String | 工程的名称和版本号 |
- Clean 任务
任务属性 | 类型 | 默认值 |
---|---|---|
dir | File | buildDir |
* Resources 任务 | ||
任务属性 | 类型 | 默认值 |
------ | ------- | ------- |
srcDirs | Object | sourceSet.resources |
destinationDir | File | sourceSet.output.resourcesDir |
* CompileJava 任务 | ||
任务属性 | 类型 | 默认值 |
------ | ------- | ------- |
classpath | FileCollection | sourceSet.compileClasspath |
source | FileTree | sourceSet.java |
destinationDir | File | sourceSet.output.classesDir |
* Jar 任务 | ||
它会把工程的 class 文件和 resources 文件打包成一个 Jar 文件。每一个 jar 或 war 文件都会包含一个 manifest 属性,当打包时会同时生成一个相应的 MANIFEST.MF 文件。我们可以自定义 MANIFEST.MF,示例代码如下: |
jar {
manifest {
attributes("Implementation-Title": "Gradle",
"Implementation-Version": version)
}
}
单元测试介绍
测试( test )任务能够自动检测并执行测试资源集合中所有的单元测试类,当测试执行完成后会生成测试报告,目前支持 JUnit 和 TestNG。
当使用 JUnit3 或 JUnit4 时,任务能自动检测到以下几种情况的单元测试。
- 继承自 TestCase 或 GroovyTestCase 的类
- 类或者父类上有@RunWith注解的类
- 类或父类中包含的方法上有@Test注解的类
如果使用的是 TestNG 时,会自动扫描方法上有@Test注解的类。
而 Gradle 默认是使用的 JUnit 测试,我们可通过指定使用 TestNG 测试,代码如下:
test {
useTestNG()
}
接下来我们可以实现分组测试,首先需要在单元测试方法上使用 groups 指定分组,代码如下:
public class GroupTest {
@BeforeClass
public void setUp() {
System.out.println("setUp");
}
@Test(groups = { "groupA" })
public void groupATest() {
System.out.println("group A test");
}
@Test(groups = { "groupB" })
public void groupBTest() {
System.out.println("group B test");
}
}
然后在 test 任务中指定执行哪一组单元测试,代码如下:
test {
useTestNG{
includeGroups 'groupA'
}
}
测试完成后可以生成以下三种方式的报告。
- HTML 格式的测试报告
- XML 格式的测试报告,可以结合 CI 工具使用
- 可以生成二进制格式的测试报告
具体的示例代码如下:
subprojects {
apply plugin: 'java'
// 禁用了测试任务独立生成测试报告
test {
reports.html.enabled = false
}
}
task testReport(type: TestReport) {
destinationDir = file("$buildDir/reports/allTests")
// 包括了子项目中的测试报告结果
reportOn subprojects*.test
}
在上面示例代码中,我们使用自定义的 testReport 任务可以把多个子项目的测试报告整合拷贝到指定目录输出。
小结
在本章中我们详细介绍了 Java 插件的使用方法,首先通过五步聚完成了 Java 插件的基本用法,然后再重点介绍了资源集合( source set )、几个重要的任务和单元测试等内容。
网友评论