一, 编译工具历史
grade 用在 Android 环境被大家所熟知, 其实 grade 是一种流行的编译框架, 也可以用在编译 java 环境上.
1.1 Java 编译步骤
java 工程的编译史是, JAVA 工程一开始是用 javac, 但是构建一个项目需要做到:
编译源码
单元测试, 集成测试
执行静态代码分析
创建发布版本
部署到目标环境
部署传递过程
执行冒烟测试和自动功能测试
1.2 编译演进史
完成这一系列步骤的是项目构建工具, 先后有了 ANT, Maven,Gradle
ANT 是类似于 Make 的自动化编译工具, 编译规则用 xml 描述. 但是 ANT 的 xml 描述文件不便于人工阅读, 并且臃肿. 而且 ANT 没有依赖包管理 (Ivy 改进了).
后面又有了 Maven.Maven 解决了依赖包管理问题, 并且能够从网络上下载依赖包. 但是 Maven 没有解决包版本冲突问题, 虽然改进了 xml 的描述语法更加简洁, 但是还是有 xml 缺点.
Gradle 最大的改进是, 抛弃 xml, 拥抱 DSL 描述性语言, 语法更简洁, 同样的意思用极少量的语言表达出来.
二, gradle 认知
2.1 buildscript 块
- buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- }
- }
buildscript 中定义了脚本需要使用的资源. 包括依赖项, 第三方插件, maven 仓库地址等. gradle 在执行脚本时, 第一执行 buildscript 代码块中的内容, 然后执行剩余的 build 脚本.
2.2 插件
"buildscript {}" 块指定第三方库作为 Gradle 插件的话, 指定插件使用 "apply plugin". 比如接着在 build.gradle 继续写入.
- apply plugin: "java"
- apply plugin: "eclipse"
- apply plugin: "idea"
- apply plugin: "application"
- // use jacocoTestReport task to create coverage report
- apply plugin: "jacoco"
2.3 jdk 版本限定
接着使用 sourceCompatibility 和 targetCompatibility 定义 jdk 版本. 分别是制定编译 java 文件字节码和 java 虚拟机兼容的版本号.
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
2.4 常量
接下来定义些常量. 常量定义了常用组件的版本号, 在后续脚本直接引用此常亮, 后续有升级依赖版本号更方便.
- def log4jVersion = "2.11.2"
- def scalaVersion = "2.11"
- def sparkVersion = "2.2.0"
- def clouderaVersion = "cdh6.0.0"
- //def kafkaVersion = "0.9.0-kafka-2.0.2"
- def kafkaVersion = "0.8.2.1"
- def jacksonVersion = "2.9.9"
2.5 依赖仓库
使用 repository 定义依赖仓库:
- repositories {
- mavenCentral()
- // spark
- maven {
- url "https://repository.cloudera.com/artifactory/cloudera-repos/"
- }
- }
2.6 mainClassname 定义了 class 的名字
mainClassName="com.xxx.xxx"
2.7 配置强制版本号和 exclude 选项
- configurations.all {
- resolutionStrategy {
- force "io.netty:netty-all:4.1.6.Final"
- force "io.netty:netty-tcnative-boringssl-static:1.1.33.Fork23"
- }
- exclude group: 'org.slf4j', module: 'slf4j-log4j12'
- }
2.8 依赖模块
buildscript 代码块中的 repositories 和 dependencies 的使用方式与直接在 build.gradle 文件中一样. 不同之处是在 buildscript 代码块中你可以对 dependencies 使用 classpath 声明. compile 是 build 使用的依赖, 而 testCompile 是编译测试用例所需要的依赖.
- dependencies {
- compile "com.googlecode.json-simple:json-simple:1.1"
- compile("io.lettuce:lettuce-core:5.0.3.RELEASE") {
- exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
- exclude group: "io.netty"
- }
- testCompile "info.solidsoft.mockito:mockito-java8:1.0.0-beta"
- compile fileTree(dir: 'libs', include: ['*.jar'])
- }
2.9 测试相关:
- test {
- systemProperty "io.lettuce.core.epoll", "false"
- testLogging {
- exceptionFormat "full"
- events "passed", "skipped", "failed"
- quiet {
- events "failed"
- exceptionFormat "full"
- }
- }
- reports {
- junitXml.enabled = true
- html.enabled = true
- }
- if (Files.exists(Paths.get("reports"))) {
- File out = File.createTempFile("testlog-", ".txt", new File("reports"))
- beforeTest { descriptor ->
- out.append("Running test:" + descriptor + "\n");
- }
- // listen to standard out and standard error of the test JVM(s)
- onOutput { descriptor, event ->
- out.append(event.message.replaceAll(/\n$/, "") +"\n")
- }
- }
- }
2.10 解析完的构建
开始构建会进入到此项脚本
- gradle.taskGraph.whenReady {
- }
2.11 各种 task
接着可以定义各种 task.
- task spark(type: Jar) {
- from sourceSets.main.output
- baseName = 'spark'
- }
2.12 打包后的操作
- compileJava.doLast {
- tasks.instrument.execute()
- }
三, gradle 使用
3.1 安装 gradle
当前最新的是这个 wget https://downloads.gradle-dn.com/distributions/gradle-5.6.2-bin.zip. 这个链接不能保证后面也有效.
3.2 使用 gradle
让 gradle 去解析 build.gradle 文件或者执行./gradlew tasks 列出所有可执行的 task.
图 1 grdle 列出所有的 task
执行相应的 tasks 任务, 比如./gradlew build,./gradlew test 等等.
来源: https://www.qcloud.com/developer/article/1512667