前言
在历经了一年多时间, 20 个 4.x 系列版本的迭代后,Gradle 官方终于在 11月26日 发布了 5.0 的正式版本,先放上一张官方各版本 Gradle 性能对比图
官方表示这是至今为止最快、最安全,最强大的版本。
● 更快的构建速度
● 细粒度的传递依赖管理
● 更高效的内存执行等等。
● ……
让我们赶紧来看一下有哪些令人激动的新特性。
官方新特性一览
● 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
我擦,感觉一脸懵逼,没关系,下面我会针对这些特性做些简要的总结和说明,内容可能比较多,但是干货满满,建议耐心阅读下去。
Kotlin DSL 1.0
早在 Gradle 4.x 版本中就已经支持了通过使用 Koltin DSL 的方式去编写构建脚本,但是当时刚出来,很多地方支持的还不太好(需要踩坑),所以并不推荐大家迁移过去,而是尝鲜为主。现在 Kotlin DSL 1.0 release 版本出来后,意味着接下来你可以放心的迁移或者使用 Kotlin DSL 啦。新版本做了很多优化和改进的地方,比如:
● Code Completion :代码自动完成● Error Highlighting :错误高亮
● Quick Documentation :文档快速提示
● Refactoring:代码重构
如何迁移你的构建语言到 Kotlin DSL 上,可以参考我的另一篇文章Gradle指南之从Groovy迁移到Kotlin
Dependency version alignment
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 build initialization features
新版本对 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 。
Searchable documentation
Gradle 的文档搜索功能回来了(虽然我一直不知道这个功能在哪里),总之,可以更加方便的搜索用户手册和 DSL 的描述。
当然,还有更方便查找类和方法的 Gradle API Javadocs。
Task timeouts
这个超时设置简直太有用了有木有。特别是当你因为一些网络原因,导致你的 build task
一直卡在那里的时候,你的心里一定是万马奔腾的感觉,赶紧用起来吧,不要再浪费这些无用的时间了。示例:
task hangingTask() { doLast { Thread.sleep(100000) } timeout = Duration.ofMillis(500) } 复制代码
HTTP retries during dependency resolution
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 插件,感兴趣的同学可以点这里了解更多
Java 11 runtime support
Gradle 5.0 版本构建支持 Java 11 版本
Plugin authoring features
这个版本为插件和自定义 task 提供了创建 SourceDirectorySet
的 API、提高 Provider
的 API、和构建缓存的兼容性提高。
Gradle Native features
Gradle Native project 持续的改善和提升 native 生态系统, 更多细节:Changes included in Gradle 5.0
Promoted features
一些现有功能的提升,详细点击这里
其他
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 复制代码