在build.gradle中添加以下语句,表示插入java插件
apply plugin:'java'
java插件引入了sourceset这个概念,sourceset将编译时和执行时所要用到的source文件组合在一起,其中包含java的源文件和资源文件,有的插件还包括了groovy和Scala资源文件,sourceset与编译环境和运行环境都存在联系。
使用sourceset的目的是将一些源文件组合起来,为了某个特殊的目的在逻辑上进行分组。例如,你可能把测试的集合单独拿出来组合成一个sourceset,或者一些API啊,你项目中的实现类啊等等,都可以定义为一个sourceset。这只是个概念的问题,你知道知道你分组的意义:方便你管理文件。
java中定义了2个sourceset:一个是main group,还有一个是test group。
main:项目中的源文件,编译后组装到jar包中的。
test:项目的测试源码,例如JUint和TestNG写的测试代码。
compileJava:目的是编译java源文件,利用javac。依赖compile任务,属于JavaCompile类型。
apply plugin: 'java'
compileJava {
//enable compilation in a separate daemon process
options.fork = true
//enable incremental compilation
options.incremental = true
}
classes :组装class目录。依赖compileJava和processResource两个任务,还有一些编译的任务 。属于Task类型。
compileTestJava:编译测试源码,利用javac。依赖compile和一些产生测试编译环境的任务。属于JavaCompile类型。
processTestResource:将测试资源文件复制到项目class文件目录中。无依赖。属于Copy类型。
testClasses:组合测试的class目录。依赖compileTestJava和processTestResource和一些添加测试的编译任务。属于Task类型。
jar:组合成jar文件,依赖compile。属于Jar类型。
javadoc:生成java帮助文档,依赖compile。属于Javadoc类型。
test:执行测试case,依赖compile,compileTest等。属于Test类型
uploadArchives:上传存档文件。依赖那些在archives配置中产生镜像的任务,比如jar。属于UpLoad类型。
clean:删除build文件,使项目回归最原始状态.属于Delete类型。
cleanTaskName:删除由任务产生的文件,比如cleanJar就是删除有任务jar产生的文件,cleanTest就是删除由test产生的文件。属于Delete类型。
compile
:利用javac编译sourceset定义的源文件,依赖所有产生sourceset编译类路径的任务。属于JavaCompile类型SourceSet
Java
process
:将sourceset定义的资源文件复制到class目录中,无依赖,属于Copy类型。SourceSet
Resources
:组合sourceset中定义的文件目录,依赖compileSourceSetJava和processSourceSetResources两个任务,属于Task类型。sourceSet
Classes
assemble:组合分析所有的档案文件。依赖所有的存档文件。属于Task类型。
check:执行所有的验证类任务,依赖所有验证类任务,包括test。属于Task类型。
build:执行构建,依赖check和assemble,属于Task类型。
buildNeeded:执行构建,依赖testCompile配置的子项目中build和buildNeeded任务,属于Task类型。
buildDependents:执行构建,依赖当前项目的子项目的build和buildDependents任务。属于Task类型。
buildConfigName:为特殊的配置类任务构建一个镜像,该任务都是隐式添加的。依赖configName代表的任务。属于Task类型。
uploadConfigName:为某一个配置任务分配镜像,然后上传镜像,该任务都是隐式添加的。依赖configName定义的任务,属于UpLoad类型。
java plugin规定一些项目目录的结构,但是下面的目录并不是要求必须存在。java在编译的时候,会访问下面所有的目录,如果不存在,会记住这些没有的目录。
src/main/java:java源文件
src/main/resources:项目资源文件
src/test/java:测试源文件
src/test/resources:测试资源文件
src/sourceSet/java:sourceset定义的java源文件,注意其中的sourceSet一级是根据sourceSet定义的目录名替换的。下同
src/sourceSet/resourcs:sourceset定义的资源文件
通过下面的方式可以修改默认的目录结构,定义你自己想要的目录
sourceSets{
main{
java{
srcDir 'src/java'
}
resources{
srcDir 'src/resources'
}
}
}
上面的图是从文档上截取下来的,它列举了任务之间的依赖关系,比如第一个compile是被compileJava所依赖的,即执行compile前,会先执行compile。所以要理解Name列是被依赖的任务,一般是全局任务,不是java插件特有的,而Used by tasks一般是plugin特有的。Extends则说明继承的任务,说明该任务是在被继承任务的基础上扩展的。
再来看另外一张图:
上面的图更加的清晰展现出java任务和gradle任务之间的联系,浅蓝色的代表java任务,绿色代表gradle任务。用used by标注的代表箭头指向的任务使用了左边的任务。
而uploadArchives和archives之前的关系是uploads,说明uploadArchives依赖于archives任务,等archives任务生成存档文件后,uploadArchives就会把这些存档文件上传。
而jar 和archives、runtime之间的关系是,在后者执行的时候,jar任务会将定义的jar包添加其中。那么这个依赖关系到底怎么算,是说jar任务依赖runtime,还是runtime依赖jar呢,应该是jar依赖runtime。因为runtime其实不管你有没有jar任务,如果有才会将jar任务定义的东西执行,如果没有,也是不会影响它。但是jar任务就不同了,没有runtime,jar还有用么?
下面再来看看谁能sourceSet任务的依赖配置,于java plugin正常任务的图是一样的,就不多解释了。
目录属性都是成双成对出现,目录名+目录。目录名是一个文件夹的名称,相对于build目录,而目录则是加上build目录。一些默认值上面都列举出来,不想浪费时间一一列举了。
比较重要的是sourceSets,包含了项目中定义的sourcesets,下面一节会详细介绍。archivesBaseName项目压缩包的名称。manifest操作MANIFEST文件的。
(终于到了能写点代码的时候了)
apply plugin:'java'
println sourceSets.main.output.classesDir
println sourceSets['main'].output.classesDir
sourceSets{
println main.output.classesDir
}
sourceSets{
main{
println output.classesDir
}
}
sourceSets.all{
println name
}
执行gradle命令后输出:
D:\GRADLE~2\0112>gradle -q
D:\gradle_product\0112\build\classes\main
D:\gradle_product\0112\build\classes\main
D:\gradle_product\0112\build\classes\main
D:\gradle_product\0112\build\classes\main
main
test
Welcome to Gradle 2.2.1.
To run a build, run gradle ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
说明想要获得sourcesets中属性值的方法有很多种,上面的程序中就列举了4种。
apply plugin:'java'
sourceSets{
main{
java{
srcDir 'src/java'
}
resources{
srcDir 'src/resources'
}
}
}
println sourceSets.main.java.srcDirs
println sourceSets['main'].resources.srcDirs
sourceSets{
println main.java.srcDirs
}
sourceSets{
main{
println java.srcDirs
}
}
sourceSets.all{
println name
}
根据实际操作来看,我们只是添加了一个java目录和一个resources目录。
D:\GRADLE~2\0112>gradle -q
[D:\gradle_product\0112\src\main\java, D:\gradle_product\0112\src\java]
[D:\gradle_product\0112\src\main\resources, D:\gradle_product\0112\src\resources
]
[D:\gradle_product\0112\src\main\java, D:\gradle_product\0112\src\java]
[D:\gradle_product\0112\src\main\java, D:\gradle_product\0112\src\java]
main
test
Welcome to Gradle 2.2.1.
To run a build, run gradle ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
上面的表格列举了一些sourceset重要的属性,其中的一些属性在之前的2个例子中也有涉及。
apply plugin:'java'
sourceSets{
intTest
}
dependencies {
intTestCompile 'junit:junit:4.11'
intTestRuntime 'org.ow2.asm:asm-all:4.0'
}
D:\GRADLE~2\0112>gradle intTestClasses
:compileIntTestJava UP-TO-DATE
:processIntTestResources UP-TO-DATE
:intTestClasses UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.699 secs
apply plugin:'java'
sourceSets{
intTest
}
dependencies {
intTestCompile 'junit:junit:4.11'
intTestRuntime 'org.ow2.asm:asm-all:4.0'
}
//将intTest输出文件打成jar包
task intTestJar(type:Jar){
from sourceSets.intTest.output
}
//为intTest中所有的java文件生成java帮助文档
task intTestJavadoc(type:Javadoc){
source sourceSets.intTest.allJava
}
//为intTest添加测试
task intTest(type:Test){
testClassesDir = sourceSets.intTest.output.classesDir
classpath = sourceSets.intTest.runtimeClasspath
}
首先我们执行intTest任务:
D:\GRADLE~2\0112>gradle intTestJar
:compileIntTestJava UP-TO-DATE
:processIntTestResources UP-TO-DATE
:intTestClasses UP-TO-DATE
:intTestJar
BUILD SUCCESSFUL
Total time: 4.337 secs
然后我们执行intTestJavadoc来生成java帮助文档:
D:\GRADLE~2\0112>gradle intTestJavadoc
:intTestJavadoc UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.73 secs
最后来执行测试
D:\GRADLE~2\0112>gradle intTest
:compileIntTestJava UP-TO-DATE
:processIntTestResources UP-TO-DATE
:intTestClasses UP-TO-DATE
:intTest UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.793 secs
任务javadoc是Javadoc类的一个实例,支持核心java文档选项和标准doclet格式,为了完整的继承这些特性,gradle定义了2个类:CoreJavadocOptions和StandardJavadocDocletOptions。详细信息也可以去这两个类中去查查。
javadoc中的一些属性:
classpath:执行环境,sourceSets.main.output代表的目录,以及sourceSets.main.compileClasspath代表的目录。是FileCollection的
source:源码文件目录,sourceSets.main.allJava代表的目录,是FileTree类型的。
destinationDir:生成的文档存放目录
title:项目的版本和名称
该任务是Delete的一个实例,删除用dir描述的目录
是sourceset中的属性,一般是通过Copy处理资源相关信息。会被ProcessResources用到:
ProcessResources.srcDirs引用的是sourceSet.resources的值。
ProcessResources.destinationDir引用的是sourceSet.output.resourcesDir的值。
java plugin为项目中的每一个sourceset都提供一个CompileJava对象实例。在脚本中是下面的样式
apply plugin: 'java'
compileJava {
//enable compilation in a separate daemon process
options.fork = true
//enable incremental compilation
options.incremental = true
}
classpath:FileCollction,默认值是sourceSet.compileClasspath
source:FileTree,默认值是sourceSet.java
destinationDir:File.默认值是sourceSet.output.classesDir
该功能正在孵化中,以后有可能更改。
该功能的主要目的是
1.避免在编译了并不需要编译的源文件,提高编译的速度。
2.可能只是改变一点的输出,并不需要重新编译一些没有任何改变的目录。这一点对JRebel很有用。
这个功能肯定是一个高级且难以理解的东西,因为它涉及到底层的算法。所以我想我是不可能弄明白的了,且对我有啥用。只是知道有这么个东西就行。
test任务是一个Test实例,它会自动识别和执行source set定义test目录下所有的单元测试,而且会生成测试报告(这个好像挺爽的啊,看来测试驱动开发看能能很容易的实现啦)。
支持JUnit和TestNG。
测试的执行是独立于JVM的,和构建的主进程也是分离的,其中关于jvm和运行时状态属性是可以通过API进行修改的。
1.你可以指定是否平行的执行测试。
2.你可以指定执行一定数量的case后重启执行进程。
3.设置case失败后的行为。
4.设置测试输出的log的等级。
可以通过Test.getDebug属性来让jvm进入5005端口,进入调试模式。而且你可以通过命令行模式参数--debug -jvm进入debug模式。
从gradle1.0开始,就具备了执行某些特殊的case,或者根据匹配模式删选case来执行。可以做到以下几点过滤:
1.依据测试方法的等级过滤,执行一个单一的测试。
2.依据自定义的注解(以后实现)
3.依据测试的层次,执行继承某一个基础类的测试(以后实现)
4.依据一些运行时的规则,例如一些特殊的系统属性值或静态状态(以后实现)
说了这么多废话,如果在脚本中定义过滤条件呢?
test {
filter{
//方法名
includeTestsMatching "*UiCheck"
//包名过滤
includeTestsMatching "org.gradle.internal.*"
//整合的case
includeTestsMatching "*IntegTest"
}
}
也可以通过gradle命令行的参数来过滤:
gradle可以自动识别出哪些class是测试类,如果做到的呢,在编译阶段,gradle观察这些编译的java类。而扫描哪些文件夹里的类,你可以去设置,包括哪些文件,不包括哪些文件,都可以自定义。而且它也会扫描出用JUnit和TestNG框架写的case。以JUnit为例来看看。
当使用JUnit的时候,我们会扫描junit3和junit4写的case。
1.类或超类继承与TestCase或者GroovyTestCase。
2.类或超类使用了@RunWith。
3.类或超类包含@Test注解的方法。
当使用TestNG的话,我们只扫描@Test注解的方法。
junit分组
test{
useJUnit{
includeCategories 'org.gradle.junit.CategoryA'
includeCategories 'org.gradle.junit.CategoryB'
}
}
test{
useJUnit{
includeCategories 'org.gradle.junit.CategoryA'
includeCategories 'org.gradle.junit.CategoryB'
}
useTestNG{
excludeGroups 'integrationTests'
includeGroups 'unitTests'
}
}
gradle默认情况下生成下面3种报告:
1.HTML格式
2.XML格式
3.二进制
可以使用任务testReports来生成测试报告:
subprojects{
apply plugin:'java'
test{
reports.html.enabled = false
}
}
task testReport(type:TestReport){
destinationDir = file("$buildDir/report/allTest")
reportOn subprojects*.test
}
jar任务会将项目的源文件和资源文件打成jar包。
jar中manifest属性,定义了jar包的版本和名称。文件位于tmp/