Gradle Java 插件
java 插件是构建 jvm 项目的基础,它为项目增加了很多能力,例如编译,测试,打包,发布等等。
很多插件都是基于 java 插件实现的,例如 android 插件。
用法
使用 id 应用插件
plugins { id 'java' }
source sets 源集
java 插件引入了源集的概念,它在逻辑上表示一组用于编译执行的源文件,这些源文件可能包括源代码文件和资源文件。
一个源集有一个相关联的编译类路径和运行时类路径。
java 插件就是通过源集的概念来管理源代码目录的。
源集的一个用途是,把源文件进行逻辑上的分组,以描述它们的目的。
例如,你可能会使用一个源集来定义一个集成测试套件,或者你可能会使用单独的源集来定义你的项目的 api 和实现类。
java 插件提供了两个标准源集
- main 包含了项目的源代码,被用于编译和生成 jar 文件
- test 包含单元测试源代码,它们将被编译并使用 junit 或 testng 来执行。
源集提供了很多属性,我这里就列出几个重要的属性:
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
name - 只读 | string | 非空 | 源集的名字 |
output - 只读 | sourcesetoutput | 非空 | 源集的输出文件,包括它编译过的类和资源。 |
output.classesdirs 只读 | filecollection | $builddir/classes/java/$name 例如:build/classes/java/main |
源集编译过的 class 文件目录 |
output.resourcesdir 只读 | file | $builddir/resources/$name例如main源集:build/resources/main | 源集产生的资源目录 |
java - 只读 | sourcedirectoryset | [${project.projectdir}/src/${sourceset.name}/java] | 源集的 java 源代码 ,只包含 .java 会排除其他类型。 |
java.srcdirs | set |
src/$name/java, 例如 src/main/java |
源集的 java 源文件的源目录。是一个集合,可以设置多个源代码目录,更改源代码目录就是更改这个属性 |
java.outputdir | file | $builddir/classes/java/$name, e.g. build/classes/java/main |
源代码编译的 class 文件输出目录 |
resources - 只读 | sourcedirectoryset | [${project.projectdir}/src/${sourceset.name}/resources] | 源集的资源,只包含资源。 |
resources.srcdirs | set |
[src/$name/resources] | 源集的资源目录,是一个集合,可以指定多个 |
跟多的源集属性可以查看下面的文档
定义一个新的源集
源集的位置也很重要,不要在 dependencies
下面,否则对源集的依赖就将不起作用
sourcesets { other }
访问源集
sourcesets 是 java 插件为 project 增加的一个属性,可以直接使用。
task outsourceset { dolast { //遍历 sourcesets.all { println "$name -> " } println "-----分割线----" //单个的 println "${sourcesets.main.name} -> " println "${sourcesets['main'].name} -> " //一些属性 println " java.srcdirs -->${sourcesets.main.java.srcdirs}" println " resource.srcdirs -->${sourcesets.main.resources.srcdirs}" } }
为源集添加依赖
dependencies { // this dependency is used by the application. implementation 'com.google.guava:guava:27.1-jre' // use junit test framework testimplementation 'junit:junit:4.12' //为 other 源集添加依赖 otherimplementation 'com.google.code.gson:gson:2.8.5' }
将源集打成一个 jar 包
创建一个 otherjar 任务,将源集的输出作为任务的文件来源。
执行这个任务即可生成 jar 包。
/** * 为 other 源集打个 jar 包 * 默认输出目录是 build/libs * 默认名字是 [archivebasename]-[archiveappendix]-[archiveversion]-[archiveclassifier].[archiveextension] */ task otherjar(type:jar){ archivebasename = sourcesets.other.name archiveversion = '0.1.0' destinationdirectory = file("${project.projectdir}/jar") from sourcesets.other.output }
为源集生成 doc
创建一个任务将源集的所有 java 文件作为源文件。
执行这个任务即可生成 doc 文件。
task otherdoc(type:javadoc){ destinationdir = file("${project.projectdir}/doc") source sourcesets.other.alljava title sourcesets.other.name }
项目结构
java 插件的默认目录结构如下所示, 无论这些文件夹中有没有内容, java 插件都会编译里面的内容, 并处理没有的内容。
这个目录结构也是 java 世界标准的项目目录。
目录 | 描述 |
---|---|
src/main/java | java 源文件目录 |
src/main/resources | 资源文件目录,例如 xml 和 properties 文件 |
src/test/java | java 测试源文件目录 |
src/test/resources | 测试资源目录 |
src/sourceset/java | 给定源集的源代码目录 |
src/sourceset/resources | 给定源集的资源目录 |
更改默认目录
这里以更改 main 源集的源代码和资源目录为例
sourcesets { main { java { srcdirs = ['src/java'] } resources { srcdirs = ['src/resources'] } } }
增加的任务
java 插件为 project 增加了很多实用的任务,如下:
-
compilejava 类型是 javacompile
依赖于:所有参与编译类路径的任务,包括 jar 任务和通过项目依赖性在类路径上的项目中的任务。
功能:使用 jdk 编译器编译生产 java 源文件。 -
processresources copy
功能:复制生产资源到资源目录 -
classes
依赖:compilejava , processresources
这是个整合的任务,只是依赖于其他任务。其他插件可能会附加别的编译任务到这里。 -
compiletestjava javacompile
依赖:classes, 以及有助于测试编译类路径的所有任务
功能:使用 jdk 编译器编译测试 java 源代码和资源文件 -
processtestresources copy
功能:复制测试资源到测试资源目录 -
testclasses
依赖:compiletestjava , processtestresources
这是个整合任务,只是依赖其他任务。其他扩展插件可能会将测试编译任务附加到这里。
-
jar jar
依赖:classes
功能:根据主源集的类和资源,组装生产 jar 文件。 -
javadoc javadoc
依赖:classes
功能:生成 api 文档。
-
test test
依赖:testclasses 以及生成测试运行时类路径的所有任务
功能:使用 junit 或者 testng 运行单元测试
-
uploadarchives upload
依赖:jar 以及生辰附加在 archives{} 配置里的构件的任何其他任务。
功能:上传 archives{} 配置里的构件包含生成的 jar 文件到配置的仓库。
-
clean delete
功能:删除项目构建目录
-
clean[taskname] delete
功能:删除由指定任务生成的文件。例如 cleanjar 将删除由 jar 任务产生的文件。
源集任务
你增加的每一个源集,java 插件都会为它增加下面列出的任务:
-
compilesourcesetjava javacompile
依赖:所有有助于源集编译类路径的任务。
功能:使用 jdk 编译器编译给定源集的 java 源文件
-
processsourcesetresources copy
功能:复制给定源集的资源到资源目录
-
sourcesetclasses task
依赖:compilesourcesetjava , processsourcesetresources
功能:准备给定的源集的类和资源以进行打包和执行。一些扩展插件可能会为给定源集附加编译任务到这里
生命周期任务
java 插件将它的一些任务附加到基础插件(java插件自动应用)定义的生命周期任务上。
它还添加了一些其他的生命周期任务:
-
assemble
依赖:jar, 以及创建附加到归档配置的工件的所有其他任务。
汇总项目中所有归档的聚合任务。 这个任务是基础插件(base)里定义的。
-
check
依赖:test
汇总项目中的验证任务,例如运行测试。一些插件会增加自己的验证任务到这里。这个任务是基础插件(base) 里定义的。
-
build
依赖:check, assemble
聚合执行项目完整构建的任务。这个任务是基础插件(base) 里定义的。
-
buildneeded
依赖:build ,以及在testruntimeclasspath配置中依赖的所有项目中的buildneeded任务。
执行项目本身及其依赖的所有项目的完整构建。
-
builddependents
依赖:build, 以及在 testruntimeclasspath 配置中依赖此项目的所有项目的 builddependents 任务
执行项目本身以及依赖于它的所有项目的完整构建。
-
buildconfigname -任务规则
依赖:生成附加到命名- configname -配置的工件的所有任务
为指定的配置组装工件。这个规则是在基础插件增加的。
-
uploadconfigname -任务规则,类型:upload
依赖:生成附加到命名- configname -配置的工件的所有任务
在指定的配置里组装和上传构件。这个规则是在基础插件增加的。
下面的图展示了这些任务的关系
依赖管理
java 插件增加了很多依赖配置到项目中,javacompile 和 test 任务就可以使用这些配置将依赖文件添加到类路径并使用他们。
依赖配置 | 描述 |
---|---|
编译时依赖,被 implementation 取代 | |
implementation 继承自compile | 仅实现依赖性。 |
compileonly | 仅仅编译时依赖 运行时不能用 |
compileclasspath 继承自 compile,compileonly,implemenation | 当编译源代码时使用的编译类路径,被 compilejava 任务使用 |
annotationprocessor | 编译时使用的注解处理器 |
|
运行时依赖,由 runtimeonly 取代 |
runtimeonly | 仅运行时依赖,编译时不能用 |
runtimeclasspath 继承自 runtimeonly,runtime,implementation | 运行时类路径包含 implementation 和仅运行时的元素 |
|
测试编译的依赖项,被 testimplementation 取代 |
testimplementation 继承自 testcompile,implemenation | 仅实现测试依赖 |
testcompileonly | 编译时测试依赖,仅仅只在编译时 |
testcompileclasspath 继承自 testcompile ,testcompileonly ,testimplementation | 测试编译类路径,当编译测试代码的时由 compiletestjava 任务使用 |
|
测试运行时依赖,由 testruntimeonly 取代 |
testruntimeonly 继承自 runtimeonly | 测试的运行时依赖 |
testruntimeclasspath 继承自 testruntimeonly,testruntime,testimplementation | 运行测试的运行时类路径,由 test 任务使用 |
archives | 项目产生的构件(例如 jar),由 uploadarchives 使用 |
下面两张图是 main 和 test 源集的配置依赖关系
- 灰色字体:已废弃的
- 黑色字体绿色背景:可以根据配置声明依赖项。
- 灰蓝背景: 该配置用于被任务使用,而不是用于声明依赖项。
- 浅蓝色背景:任务
除了以上的配置,java 插件为了每个源集还添加了以下配置,这些配置只针对给定源集
依赖配置 | 描述 |
---|---|
|
给定源集的编译时依赖,由 sourceset implementation 取代 |
sourceset implementation extend sourcesetcompile | 实现给定源集的依赖性。由 sourcesetcompileclasspath, sourcesetruntimeclasspath 使用。 |
sourcesetcompileonly | 给定源集的编译时依赖,只能在编译时使用。 |
sourcesetcompileclasspath extend compilesourcesetjava | 当编译源代码时的编译类路径,被 sourcesetcompile,sourcesetcompileonly,sourcesetimplementation 使用。 |
sourcesetannotationprocessor | 给定源集在编译时使用的注解处理器 |
|
给定源集的运行时依赖,由 sourcesetruntimeonly 取代 |
sourcesetruntimeonly | 给定源集的运行时依赖,仅仅是运行时的 |
sourcesetruntimeclasspath extends sourcesetruntimeonly ,sourcesetruntime,sourcesetimplementation | 给定源集的运行时类路径,包含 implement 和 runtime 的元素。 |
增加的属性
java 插件为项目增加了很多新的属性,可以在脚本中直接使用这些属性。
下面是一些我认为比较重要的属性:
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
sourcesets 只读 | sourcesetcontainer | 非空 | 包含项目的源集 |
sourcecompatibility | javaversion | 当前 jvm 的版本 | 编译 java 源代码时使用的 java 版本,可以是一个 数值或者字符串,例如 '1.8' 或者 1.8 |
targetcompatibility | javaversion | sourcecompatibility | 生成 class 文件的版本,可以是一个 数值或者字符串,例如 '1.8' 或者 1.8 |
archivesbasename | string | 归档的文件使用的名字,例如 jar 和 zip 文件 | |
manifest | manifest | 一个空的清单 | 包含所有 jar 文件的清单。 |
libsdirname | string | libs | 项目生成的库的存放目录,项目的相对路径。 |
更多的属性可以查看文档 convention properties
学习资料:
下一篇: JQ的简单使用(基础)——————JQ