天天看点

Gradle 5.0 正式版本发布,一大波新特性来袭

官方 5.0 Release Note 链接: https://docs.gradle.org/5.0/release-notes.html

前言

在历经了一年多时间, 20 个 4.x 系列版本的迭代后,Gradle 官方终于在 11月26日 发布了 5.0 的正式版本,让我们赶紧来看一下有哪些令人激动的新特性。

官方新特性一览

  • Kotlin DSL 1.0
  • Dependency version alignment
  • Gradle build initialization features
  • Searchable documentation
  • Task timeouts
  • HTTP retries during dependency resolution
  • Java 11 runtime support
  • Plugin authoring features
  • Gradle Native features
  • Promoted features

早在 Gradle 4.x 版本中就已经支持了通过使用 Koltin DSL 的方式去编写构建脚本,但是当时刚出来,很多地方支持的还不太好(需要踩坑),所以并不推荐大家迁移过去,而是尝鲜为主。现在 Kotlin DSL 1.0 release 版本出来后,意味着接下来你可以放心的迁移或者使用 Kotlin DSL 啦。新版本做了很多优化和改进的地方,比如:

  • Code Completion:代码自动完成
  • Error Highlighting:错误高亮
  • Quick Documentation:文档快速提示
  • Refactoring:代码重构
    ![图片来自官方](https://user-gold-cdn.xitu.io/2018/11/27/16753ed585f2bd3f?w=1340&h=746&f=png&s=649481)
               
如何迁移你的构建语言到 Kotlin DSL 上,可以参考我的另一篇文章[Gradle指南之从Groovy迁移到Kotlin

](

https://juejin.im/post/5b875c9c6fb9a01a0d74c34b)

Dependency version alignment allows different modules belonging to the same logical group (a platform) to have identical versions in a dependency graph.

根据官网的介绍,直译过来的意思是:依赖版本一致性允许属于相同的逻辑组(平台)的不同module 拥有相同的版本依赖图。

这个概念确实不好理解,我自己也是花了一些时间去理解和消化。还是通过一个示例来说明吧。如果有英文水平高或者理解能力比较强的同学,欢迎指教。

比如,我们

build.gradle

有以下依赖:

dependencies {
        // a dependency on Jackson Databind
        implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.9'

        // and a dependency on vert.x
        implementation 'io.vertx:vertx-core:3.5.3'
    }
           

因为

vertx-core

也间接依赖了

jackson-core

,通过依赖传递,当解析依赖信息的时候,我们实际依赖的版本号是:

  • jackson-core

    版本 2.9.5(依赖传递)
  • jackson-databind

    版本 2.8.9 -> 2.9.5(低版本通过依赖仲裁变为高版本)
  • jackson-annotation

    版本 2.9.0 (

    jackson-databind

    2.8.9 版本间接依赖

    jackson-annotation

    2.9.0 版本,注意这里,因为上面的依赖仲裁,变成了被高版本 的

    jackson-databind

    2.9.5 所依赖)

通过以上的分析,我们发现实际上解析出来的依赖库版本出现了和预期不一致的情况,而类似这种情况很容易会导致一些未知问题,尤其是在一些不兼容老版本接口的依赖库里就会直接导致 Crash。

通常,针对这种问题,之前的做法可能就是简单粗暴的强指定版本号,不过,现在有了更加优雅的方式去帮助我们去管理版本,即

Dependency version alignment

,我们可以通过指定一个

platform

去管理某一组的

module

回到刚才的场景示例中,我们在

build.gradle

里可以定义

jackson

为一组的

module

版本的规则,如下所示:

class JacksonAlignmentRule implements ComponentMetadataRule {
        void execute(ComponentMetadataContext ctx) {
            ctx.details.with {
                if (id.group.startsWith("com.fasterxml.jackson")) {
                    // declare that Jackson modules all belong to the Jackson virtual platform
                    belongsTo("com.fasterxml.jackson:jackson-platform:${id.version}")
                }
            }
        }
    }
           

然后应用该规则:

dependencies {
        components.all(JacksonAlignmentRule)
    }
           

最后,在执行完

./gradlew app:dependencies

命令后,你会发现当匹配上

com.fasterxml.jackson

组的

module

的版本都保持了一致,也就是

  • jackson-core

    版本 2.9.5
  • jackson-databind

    版本 2.8.9 -> 2.9.5
  • jackson-annotation

    版本 2.9.0 -> 2.9.5

另外,

platform

同样也提供了强制为一组

module

指定某个版本号,比如:

dependencies {
        // Forcefully downgrade the Jackson platform to 2.8.9
        implementation enforcedPlatform('com.fasterxml.jackson:jackson-platform:2.8.9')
    }
           

还有一个比较方便的地方,就是通过

platform

,我们可以直接省略该

module

的版本号(从此告别通过定义版本变量去维护众多

module

的版本信息),如下所示:

dependencies {
        // import a BOM. The versions used in this file will override any other version found in the graph
        implementation(enforcedPlatform("org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE"))

         // define dependencies without versions
        implementation("com.google.code.gson:gson")
        implementation("dom4j:dom4j")

         // this version will be overriden by the one found in the BOM
        implementation("org.codehaus.groovy:groovy:1.8.6")
    }
           

新版本对

gradle init

方法进行了升级,通过更多的特性和交互,来帮助我们去快速初始化一个 Gradle 项目。简单来说的话,就是加强版的脚手架。

Interactive mode

当你在控制台执行

init

task 后,Gradle 将会提供更多的构建信息提示,来帮助你生成 Gradle 模版项目。

Kotlin library and applications

init

task 可以通过

kotlin-library

或者

kotlin-application

类型来设置生成一个 Kotlin 的类库或者应用。你只需要根据它的提示来操作即可。

Generated builds use recommended configurations

init

task 生成的构建脚本将推荐使用新的

implementation

testImplementation

testRuntimeOnly

去代替

compile

testCompile

testRuntime

Configure project and source package names

  • --project-name

    选项可以帮助你调整生成的项目名称
  • --package

    选项可以帮助你调整生成的项目包名

Create resource directories

init

task 会创建一个空的 resource 目录

Create a .gitignore file

init

task 会生成一个简单的

.gitignore

文件来帮助你设置你的 Git repository 。

Gradle 的文档搜索功能回来了(虽然我一直不知道这个功能在哪里),总之,可以更加方便的搜索用户手册和 DSL 的描述。

当然,还有更方便查找类和方法的

Gradle API Javadocs

这个超时设置简直太有用了有木有。特别是当你因为一些网络原因,导致你的

build task

一直卡在那里的时候,你的心里一定是万马奔腾的感觉,赶紧用起来吧,不要再浪费这些无用的时间了。示例:

task hangingTask() {
        doLast {
            Thread.sleep(100000)
        }
        timeout = Duration.ofMillis(500)
    }
           

HTTP 访问重试功能,嗯。挺好

Performance features

Gradle can be started as a low-priority process

通过

--priority low

命令参数或者

org.gradle.priority=low

属性设置可以让你的 Gradle 以一个低优先级的进程启动,至于好处嘛,当然是你一边在

building

的时候,一边听音乐的时候,再也不会感觉一卡一卡的了 :)

JaCoCo plugin now works with the build cache and parallel test execution

简单看了下介绍,可以帮助你查看代码覆盖率的 JaCoCo 插件,感兴趣的同学可以

点这里了解更多

Gradle 5.0 版本构建支持 Java 11 版本

这个版本为插件和自定义 task 提供了创建

SourceDirectorySet

的 API、提高

Provider

的 API、和构建缓存的兼容性提高。

Gradle Native project 持续的改善和提升 native 生态系统,

更多细节:

Changes included in Gradle 5.0

一些现有功能的提升,

详细点击这里

其他

5.0 版本共计修复了 166 个 issues(惊人),当然,伴随而来的还有一些已知的 issues ,详细可以点击这里

5.0 release-notes

总结

Gradle 5.0 版本真的是干货满满,尤其是对于使用 Gradle 构建的 Android 或者 Java 开发者来说,像 Kotlin DSL(构建语言)、Dependency version alignment(依赖版本一致性)、Performance features(性能提升) 等等这些特性还是很让人期待的。有兴趣的小伙伴可以赶紧更新一波了。

如何升级到 Gradle 5.0 版本呢,很简单,以下两种方式任选其一:

  • 执行

    ./gradlew wrapper --gradle-version=5.0

    命令
  • 或者直接修改你的

    rootProject/gradle/wrapper/gradle-wrapper.properties

    distributionBase=GRADLE_USER_HOME
        distributionPath=wrapper/dists
        distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-all.zip
        zipStoreBase=GRADLE_USER_HOME
        zipStorePath=wrapper/dists           

继续阅读